ViewVC Help
View File | Revision Log | View Changeset | Root Listing
root/Oni2/s10k/Vago/mainwindow.cpp
Revision: 999
Committed: Sat Apr 26 12:40:47 2014 UTC (11 years, 5 months ago) by s10k
Content type: text/x-c++src
Original Path: Vago/trunk/Vago/mainwindow.cpp
File size: 62363 byte(s)
Log Message:
Vago 0.9a mac specific changes

File Contents

# Content
1 #include "mainwindow.h"
2 #include "ui_mainwindow.h"
3
4 const QString MainWindow::VagoSettingsName = "settingsVago.ini";
5
6 MainWindow::MainWindow(QWidget *parent) :
7 QMainWindow(parent),
8 ui(new Ui::MainWindow)
9 {
10 ui->setupUi(this);
11
12 this->AppDir=getOSIndependentAppPath();
13
14 this->myLogger = new Logger(this->AppDir); //start logger
15
16 this->myLogger->writeString("Detected AppDir: "+this->AppDir);
17 this->myLogger->writeString("True app dir: "+QDir::currentPath());
18
19 this->setWindowTitle("Vago v"+GlobalVars::AppVersion);
20
21 if(!QFile::exists(this->AppDir+"/"+GlobalVars::OniSplitString)){
22 Util::showErrorPopUp("OniSplit not found. Please download it at "+GlobalVars::ModsDomain+" and put it in the same folder of Vago. \n\nProgram will now exit.");
23 exit(1);
24 }
25
26 if(!QFile::exists(this->AppDir+"/"+GlobalVars::XmlToolsString)){
27 Util::showErrorPopUp("xmlTools not found. Please download it at "+GlobalVars::ModsDomain+" and put it in the same folder of Vago. \n\nProgram will now exit.");
28 exit(1);
29 }
30
31 this->vagoSettings = new QSettings(this->AppDir + "/" + this->VagoSettingsName, QSettings::IniFormat);
32
33 //First Execution? Old configuration? Settings missed?
34 bool iniChanged=false;
35 if(!this->vagoSettings->contains("VagoVersion") || this->vagoSettings->value("VagoVersion")!=GlobalVars::AppVersion){
36 this->vagoSettings->setValue("VagoVersion", GlobalVars::AppVersion);
37 iniChanged=true;
38 }
39 if(!this->vagoSettings->contains("Workspace")){
40 this->vagoSettings->setValue("Workspace", this->AppDir+"/VagoWorkspace");
41 iniChanged=true;
42 }
43 if(!this->vagoSettings->contains("AeFolder")){
44
45 Util::showPopUp("Seems it's the first time you are executing Vago. \n\nPlease input your Anniversary Edition (AE) Folder.");
46 QString aefolder=Util::normalizePath(QFileDialog::getExistingDirectory(this,"Choose Anniversary Edition (AE) folder..."));
47
48 if(aefolder.isEmpty()){
49 Util::showErrorPopUp("AE folder is mandatory. Application will now exit.");
50 exit(1);
51 }
52
53 if(!aefolder.endsWith("AE")){
54 Util::showWarningPopUp("Seems the folder you selected isn't called 'AE'. \n\nIf you run in any problems you can always change it in Vago preferences window.");
55 }
56
57 this->vagoSettings->setValue("AeFolder", aefolder);
58 iniChanged=true;
59 }
60 if(!this->vagoSettings->contains("WindowWidth")){
61 this->vagoSettings->setValue("WindowWidth", GlobalVars::DefaultWindowWidth);
62 iniChanged=true;
63 }
64 if(!this->vagoSettings->contains("WindowHeight")){
65 this->vagoSettings->setValue("WindowHeight", GlobalVars::DefaultWindowHeight);
66 iniChanged=true;
67 }
68 if(!this->vagoSettings->contains("OniWindow")){
69 this->vagoSettings->setValue("OniWindow", true);
70 iniChanged=true;
71 }
72 if(!this->vagoSettings->contains("SeparateInWorkspace")){
73 this->vagoSettings->setValue("SeparateInWorkspace",true);
74 iniChanged=true;
75 }
76 if(!this->vagoSettings->contains("ConfirmExit")){
77 this->vagoSettings->setValue("ConfirmExit", false);
78 iniChanged=true;
79 }
80 #ifdef Q_OS_MAC
81 if(!this->vagoSettings->contains("useYesAsDefaultWhenRemovingItems")){
82 this->vagoSettings->setValue("useYesAsDefaultWhenRemovingItems", false);
83 iniChanged=true;
84 }
85 #endif
86
87 if(iniChanged){
88 this->vagoSettings->sync();
89 }
90 ///
91
92 this->workspaceLocation=this->vagoSettings->value("Workspace").toString();
93 this->workspaceWizardsLocation=this->workspaceLocation+"/Wizards";
94 this->AeLocation=this->vagoSettings->value("AeFolder").toString();
95 this->outputFolder=this->workspaceLocation;
96 this->startedWindowWidth=this->vagoSettings->value("WindowWidth").toInt();
97 this->startedWindowHeight=this->vagoSettings->value("WindowHeight").toInt();
98 #ifdef Q_OS_MAC
99 this->useYesAsDefaultWhenRemovingItems=this->vagoSettings->value("useYesAsDefaultWhenRemovingItems").toBool();
100 #endif
101
102 //Create our workspace if it doesn't exists yet
103 if(!QDir(this->workspaceLocation).exists()){
104 QDir().mkdir(this->workspaceLocation);
105 }
106 this->itemsLoaded=new QLabel(this);
107 ui->statusBar->addWidget(this->itemsLoaded);
108 this->myBar = new QProgressBar(this);
109 this->myBar->setTextVisible(false); //hides text
110
111 this->myBar->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Fixed);
112 this->myBar->setMinimumWidth(150);
113 this->myBar->hide(); //hide while not being used
114 ui->tbAbortConversion->hide(); //hide while not being used
115
116 ui->statusBar->addPermanentWidget(this->myBar); //this adds automatically in right
117 ui->statusBar->addPermanentWidget(ui->tbAbortConversion);
118
119 //Initialize list pointers
120 this->listToProccess = new QStringList;
121
122 //Create a thread for do the conversion in background
123 this->myConverter = new Converter(this->AppDir,this->myLogger,this->listToProccess);
124
125 // User interface
126 ui->mainToolBar->addWidget(ui->tbAE); //add ae installer launch button
127 ui->mainToolBar->addWidget(ui->emptySpacerLabel); //trick, we can't add directly a space so we add an empty
128 ui->mainToolBar->addWidget(ui->tbOni); //add oni launch buttonlabel
129 ui->mainToolBar->addWidget(ui->emptySpacerLabel2); //same as before
130 ui->mainToolBar->addWidget(ui->tbCommand); //add option to manual onisplit commands
131 ui->mainToolBar->addWidget(ui->emptySpacerLabel3); //same as before
132 ui->mainToolBar->addWidget(ui->tbOpenFolder); //add option to open folder with files converted etc
133
134 ui->mainToolBar->setLayoutDirection(Qt::RightToLeft);
135
136 setConverterButtonsSize();
137
138 #ifdef Q_OS_MAC
139 // setUnifiedTitleAndToolBarOnMac(true); // Qt suggests to use it on mac | http://www.slideshare.net/qtbynokia/how-to-make-your-qt-app-look-native // align on left doesn't work if active
140 ui->tbOni->setIcon(QIcon(":/new/icons/oni_icon_mac.png")); // Oni executable on mac have a different icon than windows
141 // Set mac platform the first one in the menu, and also make it checkable by default
142 ui->menuTarget_Platform->removeAction(ui->actionWindows);
143 ui->menuTarget_Platform->addAction(ui->actionWindows);
144 ui->actionWindows->setChecked(false);
145 ui->actionMac_Windows_demo->setChecked(true);
146 // resize(800,600); // Mac OS pcs should be able to render this resolution without any problem. It's also better
147 //// because the components on mac use more space
148 #else
149 //resize(640,480); // windows stuff
150 #endif
151
152 resize(this->startedWindowWidth,this->startedWindowHeight);
153
154 connectSlots();
155
156 //Commands Mapping
157 this->commandMap = QHash<QString, QString>();
158 mapCommands();
159
160 updateItemsLoaded(ui->twSourcesXML);
161
162 this->myLogger->writeString("Application started.");
163 }
164
165 MainWindow::~MainWindow()
166 {
167 delete ui;
168 this->myLogger->writeString("Application Exited.");
169 }
170
171 void MainWindow::on_actionExit_triggered()
172 {
173 close();
174 }
175
176 void MainWindow::on_actionAbout_triggered()
177 {
178 //Show preferences
179 About *aboutWindow = new About(this);
180 aboutWindow->show(); //it destroys itself when finished.
181 }
182
183 void MainWindow::on_actionAE_Package_Creator_triggered()
184 {
185 PackageWizard myWizard = PackageWizard(this->workspaceWizardsLocation, this->vagoSettings, this->myLogger);
186 myWizard.exec();
187 }
188
189 void MainWindow::on_actionSound_Wizard_triggered()
190 {
191 SoundWizard myWizard (this->AppDir, this->workspaceWizardsLocation, this->myLogger, &this->commandMap);
192 myWizard.exec();
193 }
194
195 void MainWindow::on_tbOni_clicked()
196 {
197 QStringList arguments;
198
199 if(this->vagoSettings->value("OniWindow").toBool()){ // Run in a window?
200 arguments << "-noswitch";
201 }
202 #ifdef Q_OS_WIN
203 else{
204 arguments << "-switch"; // only supported on windows. Was added by daodan dll.
205 }
206 #endif
207
208 arguments << "-debugfiles";
209
210 if(!QProcess::startDetached(this->AeLocation+"/"+GlobalVars::OniExe,arguments,this->AeLocation)){
211 showErrStatusMessage("Oni could not be started!");
212 }
213 }
214
215 void MainWindow::on_tbAE_clicked()
216 {
217 // If the app turn out someday to a native app use QProcess::startDetached instead...
218
219 if(!QDesktopServices::openUrl("file:///"+this->AeLocation+"/AEInstaller/bin/AEInstaller2.jar")){
220 showErrStatusMessage("Could not start AE Installer!");
221 }
222 }
223
224 void MainWindow::on_tbOpenFolder_clicked()
225 {
226 QDesktopServices::openUrl(QUrl("file:///"+this->outputFolder));
227 }
228
229 void MainWindow::on_tbAbortConversion_clicked()
230 {
231 if(Util::showQuestionPopUp(this,"Are you sure you want to abort the current conversion?")){
232 emit terminateCurrProcess();
233 }
234 }
235
236 void MainWindow::on_cbEnvMap_toggled(bool checked)
237 {
238 ui->leEnvMapTexture->setEnabled(checked);
239 }
240
241 void MainWindow::on_cbTexture_toggled(bool checked)
242 {
243 ui->leTextureName->setEnabled(checked);
244 }
245
246 void MainWindow::on_cbWithAnimation_toggled(bool checked)
247 {
248 ui->leAnimationName->setEnabled(checked);
249 }
250
251 void MainWindow::on_cbSpecificFilesLevels_toggled(bool checked)
252 {
253 ui->leSpecificFilesLevels->setEnabled(checked);
254 }
255
256 void MainWindow::on_actionCheck_For_Updates_triggered()
257 {
258
259 //let's check in the web if this version is the latest
260 QNetworkAccessManager *manager = new QNetworkAccessManager(this);
261 connect(manager, SIGNAL(finished(QNetworkReply*)),
262 this, SLOT(checkVagoLastVersion(QNetworkReply*)));
263
264 manager->get(QNetworkRequest(QUrl(GlobalVars::VagoCheckUpdatesUrl)));
265
266 }
267
268 void MainWindow::checkVagoLastVersion(QNetworkReply *result){
269
270 if(result->error()==QNetworkReply::NoError){
271 QScriptEngine engine;
272 QScriptValue sc = engine.evaluate("(" + QString(result->readAll()) + ")");
273
274 // "field_version":{"und":[{"value":"0.6a","format":null,"safe_value":"0.6a"}]} //Note the use of [{}] which means it's a array of 1 element with one object inside (so the use of [0] bellow
275
276 QString newVersion = sc.property("field_version").toObject().property("und").toObject().property("0").toObject().property("value").toString();
277
278 if(newVersion!=GlobalVars::AppVersion){
279 Util::showRichPopUp("There's a new version of Vago! (v"+newVersion+")<br/><br/>"+
280 "You can download it <a href='"+GlobalVars::VagoWebUrl+"'>here</a>.");
281 }
282 else{
283 Util::showPopUp("You are using last version.");
284 }
285 }
286 else{
287 Util::showErrorPopUp("An error occurred checking last version:\n\n"+result->errorString());
288 }
289 result->deleteLater();
290 }
291
292 void MainWindow::on_pbAddSourceXML_clicked()
293 {
294 addFilesSource( ui->twSourcesXML,QFileDialog::getOpenFileNames(this,"Choose the files...","./" , "All Files (*.*)"));
295 }
296
297 void MainWindow::on_pbAddSourceTextures_clicked()
298 {
299 addFilesSource( ui->twSourcesTextures, QFileDialog::getOpenFileNames(this,"Choose the files...","./" , "All Files (*.*)"));
300 }
301
302 void MainWindow::on_pbAddSourceObjects_clicked()
303 {
304 addFilesSource( ui->twSourcesObjects,QFileDialog::getOpenFileNames(this,"Choose the files...","./" , "All Files (*.*)"));
305 }
306
307 void MainWindow::on_pbAddSourceCharacters_clicked()
308 {
309 addFilesSource( ui->twSourcesCharacters,QFileDialog::getOpenFileNames(this,"Choose the files...","./" , "All Files (*.*)"));
310 }
311
312 void MainWindow::on_pbAddSourceLevels_clicked()
313 {
314 if(QString::compare(ui->cbFromXML->currentText(),"ONI FILES",Qt::CaseSensitive)==0 && QString::compare(ui->cbToXML->currentText(),"DAT",Qt::CaseSensitive)==0){ //CaseSensitive is faster)
315 addFilesSource(ui->twSourcesLevels,Util::multipleDirDialog("Choose folders with ONIs..."));
316 }
317 else{
318 addFilesSource(ui->twSourcesLevels,QFileDialog::getOpenFileNames(this,"Choose the files...","./" , "All Files (*.*)"));
319 }
320 }
321
322 void MainWindow::on_pbAddSourceMisc_clicked()
323 {
324 addFilesSource( ui->twSourcesMisc,QFileDialog::getOpenFileNames(this,"Choose the files...","./" , "All Files (*.*)"));
325 }
326
327 QString MainWindow::getFileOutputFolder(QString fromTo, QString myOutputFolder){
328
329 if(myOutputFolder==""){ //We may want to change to a non standart location with context menu
330 myOutputFolder=this->outputFolder;
331 }
332
333 if(this->vagoSettings->value("SeparateInWorkspace").toBool() && myOutputFolder==this->workspaceLocation){
334 myOutputFolder+="/"+ui->tabWidget->tabText(ui->tabWidget->currentIndex());
335 myOutputFolder+="/"+QString(fromTo).replace(" / ","_").replace(" > "," - ");
336 }
337 return Util::insertQuotes(myOutputFolder+"/");
338 }
339
340 void MainWindow::addFilesSource(DropTableWidget *myTable, QStringList files){
341
342 //Get Conversion pretended
343 QString from,to;
344
345 QString fromTo = getTypeConversion(myTable);
346
347 from = QString(fromTo).remove(fromTo.indexOf(" >"),fromTo.size()-1); //parse the string to get the from, only 1 time parsed by each group of files = very fast
348 to = QString(fromTo).remove(0,fromTo.lastIndexOf("> ")+2); //+2 to start after "> "
349
350 //Pre-processing (check if the files/folders received are valid), e.g. check for ONI->DAT if are only given folders and not files
351 if(from=="ONI FILES" && to=="DAT"){
352 //check if it's a folder
353 foreach(QString myFile, files){
354 if(!QDir(myFile).exists()){
355 showErrStatusMessage("Only folders are allowed for this operation.");
356 return;
357 }
358 }
359
360 }
361 else{
362 foreach(QString myFile, files){
363 //check if it's a file
364 if(QDir(myFile).exists()){
365 showErrStatusMessage("Only files are allowed for this operation.");
366 return;
367 }
368 }
369 }
370
371 //Build command
372 QString command, lastFileName;
373
374 QString myOutputFolder=getFileOutputFolder(fromTo);
375
376 //if folder doesn't exist onisplit will create it for us :)
377 foreach(QString currentFile, files){
378
379 currentFile=Util::normalizeAndQuote(currentFile); //insert quotes ("") in file
380
381 if(lastFileName.isEmpty()){ //Optimization: all commands are the same for each file, just replace the filename
382
383 command=getCommand(myTable,myOutputFolder,from,to,currentFile);
384
385 if(command.isEmpty()){ //something wrong was happening (not inputted a texture name?)
386 return; //stop adding files
387 }
388 currentFile=Util::cutName(currentFile);
389 }else{ //one parsing was already made just replace the filename by the old one in the command
390
391 currentFile=Util::cutName(currentFile);
392
393 command.replace(lastFileName,currentFile,Qt::CaseSensitive); //case sentive is faster
394 }
395
396 lastFileName=currentFile;
397
398 addRowTable(myTable,lastFileName,fromTo,command);
399 }
400 updateItemsLoaded(myTable);
401 }
402
403 QString MainWindow::fileParsingXML(QString tabTitle, QString myOutputFolder, QString from, QString to , QString file){
404
405 QString command;
406
407 if(from=="ONI" && to=="XML"){
408 return command=this->commandMap.value(tabTitle+"->"+from+"->"+to)+" "+myOutputFolder+" "+file;
409 }
410 else if(from=="XML" && to=="ONI"){
411 return command=this->commandMap.value(tabTitle+"->"+from+"->"+to)+" "+myOutputFolder+" "+file;
412 }
413
414 return "";
415
416 }
417
418 QString MainWindow::fileParsingTextures(QString tabTitle, QString myOutputFolder, QString from, QString to , QString file){
419
420 QString command=this->commandMap.value(tabTitle+"->"+from+"->"+to)+" "+myOutputFolder;
421
422 if(ui->gbTextures->isEnabled()){ //faster than compare strings (if is DAT/ONI)
423
424 if(ui->cbMipMapsTextures->isChecked()){
425 command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbMipMapsTextures->text());
426 }
427
428 if(ui->cbNoUwrap->isChecked()){
429 command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbNoUwrap->text());
430 }
431
432 if(ui->cbNoVwrap->isChecked()){
433 command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbNoVwrap->text());
434 }
435
436 if(ui->cbLarge->isChecked()){
437 command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbLarge->text());
438 }
439
440 if(ui->rbBGR32->isChecked()){
441 command+=" "+this->commandMap.value(tabTitle+"->"+ui->rbBGR32->text());
442 }
443 else if(ui->rbBGRA32->isChecked()){
444 command+=" "+this->commandMap.value(tabTitle+"->"+ui->rbBGRA32->text());
445 }
446 else if(ui->rbBGR555->isChecked()){
447 command+=" "+this->commandMap.value(tabTitle+"->"+ui->rbBGR555->text());
448 }
449 else if(ui->rbBGRA5551->isChecked()){
450 command+=" "+this->commandMap.value(tabTitle+"->"+ui->rbBGRA5551->text());
451 }
452 else if(ui->rbBGRA444->isChecked()){
453 command+=" "+this->commandMap.value(tabTitle+"->"+ui->rbBGRA444->text());
454 }
455 else{ //dxt1 checked
456 command+=" "+this->commandMap.value(tabTitle+"->"+ui->rbDxt1->text());
457 }
458
459 if(ui->cbEnvMap->isChecked()){
460 if(ui->leEnvMapTexture->text().isEmpty()){
461 showErrStatusMessage("Checkbox '"+ui->cbEnvMap->text()+"' is selected. The name texture name cannot be empty.");
462 return "";
463 }
464 command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbEnvMap->text()) + ui->leEnvMapTexture->text().remove(".oni",Qt::CaseInsensitive);
465 }
466 }
467
468 return command+=" "+file; //add source
469 }
470
471 QString MainWindow::fileParsingCharacters(QString tabTitle, QString myOutputFolder, QString from, QString to , QString file){
472
473 QString command=this->commandMap.value(tabTitle+"->"+from+"->"+to)+" "+myOutputFolder + " " + file ;
474
475
476 if(ui->cbCellShading->isChecked()){
477 command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbCellShading->text());
478 }
479
480 if(ui->cbNormals->isChecked()){
481 command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbNormals->text());
482 }
483
484 if(ui->cbWithTRBS_ONCC->isChecked()){
485 if(ui->leTRBS_ONCC->text().isEmpty()){
486 showErrStatusMessage("Checkbox '"+ui->cbWithTRBS_ONCC->text()+"' is selected. The name cannot be empty.");
487 return "";
488 }
489
490 command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbWithTRBS_ONCC->text())+Util::normalizeAndQuote(ui->leTRBS_ONCC->text());
491 }
492
493 return command;
494 }
495
496
497 QString MainWindow::fileParsingObjects(QString tabTitle, QString myOutputFolder, QString from, QString to , QString file){
498
499 QString command=this->commandMap.value(tabTitle+"->"+from+"->"+to)+" "+myOutputFolder;
500
501 //TODO: This can be optimized. When some are not enable others are.
502 if(ui->cbTexture->isChecked()){
503 if(ui->leTextureName->text().isEmpty()){
504 showErrStatusMessage("Checkbox '"+ui->cbTexture->text()+"' is selected. The file source cannot be empty.");
505 return "";
506 }
507 command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbTexture->text()) + ui->leTextureName->text();
508 }
509 else if(ui->cbWithAnimation->isChecked()){
510 if(ui->leAnimationName->text().isEmpty()){
511 showErrStatusMessage("Checkbox '"+ui->cbWithAnimation->text()+"' is selected. The file source cannot be empty.");
512 return "";
513 }
514 command+=" "+Util::normalizeAndQuote(ui->leAnimationName->text()) + " " + this->commandMap.value(tabTitle+"->"+ui->cbWithAnimation->text()) + file;
515 return command;
516 }
517
518 if(from=="OBAN ONI (cam)"){
519 command+=" -geom:camera";
520 }
521
522 return command+=" "+file; //add source
523 }
524
525 QString MainWindow::fileParsingLevels(QString tabTitle, QString myOutputFolder, QString from, QString to , QString file){
526
527 QString datName, command;
528
529 if(!(from=="ONI FILES" && to=="DAT")){ // to all except this one
530
531 command=this->commandMap.value(tabTitle+"->"+from+"->"+to);
532
533 if(ui->cbSpecificFilesLevels->isChecked()){
534
535 if(ui->leSpecificFilesLevels->text().isEmpty()){
536 showErrStatusMessage("Checkbox '"+ui->cbSpecificFilesLevels->text()+"' is selected. The files pattern cannot be empty.");
537 return "";
538 }
539
540 command+=":"+ui->leSpecificFilesLevels->text();
541 }
542
543 if(from=="DAT" && to=="ONI FILES"){ // extract files to a subdir with the files name ex: level0_Final
544 command += " " + myOutputFolder.insert(myOutputFolder.size()-2,QString(Util::cutName(file)).replace(".dat","")) + " " + file;
545 }
546 else{
547 command+=" "+myOutputFolder+" "+file;
548 }
549
550 }
551
552 if((from=="ONI FILES" || from=="MASTER XML") && to=="DAT"){ // almost the same command for both
553 QString datName;
554
555 if(from=="MASTER XML"){
556 command+=GlobalVars::OniSplitProcSeparator; //insert mark so we know this action will take 2 commands
557 }
558
559 if(ui->cbDatLevels->isChecked()){
560 if(ui->leTargetDatLevels->text().isEmpty()){
561 showErrStatusMessage("Checkbox '"+ui->cbDatLevels->text()+"' is selected. The name cannot be empty.");
562 return "";
563 }
564 datName+=QString(myOutputFolder).insert(myOutputFolder.size()-1,ui->leTargetDatLevels->text()); //set name inputted by user
565 if(!ui->leTargetDatLevels->text().toUpper().endsWith(".DAT")){
566 datName.insert(datName.size()-1,".dat"); //append extension if necessary (-1 to maintain final quote)
567 }
568 }
569 else{
570 if(from=="ONI FILES"){
571 datName=QString(myOutputFolder).insert(myOutputFolder.size()-1,Util::cutName(file).remove("/")+".dat"); //if none iputted set the same name of input file
572 }
573 else if(from=="MASTER XML"){
574 datName=QString(myOutputFolder).insert(myOutputFolder.size()-1,Util::cutName(file).remove("/").replace(".xml",".dat",Qt::CaseInsensitive)); //if none iputted set the same name of input file
575 }
576 }
577 if(from=="ONI FILES"){
578 if(ui->actionWindows->isChecked()){ //is target plataform select windows?
579 return command=this->commandMap.value(tabTitle+"->"+from+"->"+to+"(PC)")+" "+ file + " "+datName;
580 }
581 else{
582 return command=this->commandMap.value(tabTitle+"->"+from+"->"+to+"(demoPCMAC)")+" "+ file + " "+datName;
583 }
584 }
585 else if(from=="MASTER XML"){
586 if(ui->actionWindows->isChecked()){ //is target plataform select windows?
587 command+=this->commandMap.value(tabTitle+"->ONI FILES->"+to+"(PC)")+" "+myOutputFolder+" "+datName; //add second command
588 }
589 else{
590 command+=this->commandMap.value(tabTitle+"->ONI FILES->"+to+"(demoPCMAC)")+" "+myOutputFolder+" "+datName; //add second command
591 }
592 }
593 }
594
595 if(ui->cbBnvLevels->isChecked()){
596
597 if(ui->leBnvLevels->text().isEmpty()){
598 showErrStatusMessage("Checkbox '"+ui->cbBnvLevels->text()+"' is selected. The BNV file cannot be empty.");
599 return "";
600 }
601 command+=" "+Util::normalizeAndQuote(ui->leBnvLevels->text());
602 }
603
604 if(ui->cbAdditionalSourcesLevels->isChecked()){
605
606 if(ui->leAdditSourcesLevels->text().isEmpty()){
607 showErrStatusMessage("Checkbox '"+ui->cbAdditionalSourcesLevels->text()+"' is selected. The source files cannot be empty.");
608 return "";
609 }
610
611 QString additionalFiles=ui->leAdditSourcesLevels->text();
612
613 int currentIndex=0, nextIndex=0;
614
615 //parse all files (separated by spaces)
616 while(true){
617 nextIndex=additionalFiles.indexOf(";",currentIndex+1);
618
619 command += " "+Util::normalizeAndQuote(additionalFiles.mid(currentIndex,(nextIndex-currentIndex)));
620
621 if(nextIndex==-1){ //we got to the end, stop parsing
622 break;
623 }
624 currentIndex=nextIndex+1; //update currentIndex +1 for start after the separator
625 }
626 }
627
628 if(ui->cbGridsLevels->isChecked()){
629 command+=GlobalVars::OniSplitProcSeparator+this->commandMap.value(tabTitle+"->"+ui->cbGridsLevels->text())+" "+Util::normalizeAndQuote(ui->leBnvLevels->text())+" "+file+" -out:"+myOutputFolder;
630 }
631
632 return command;
633 }
634
635 QString MainWindow::fileParsingMisc(QString myOutputFolder, QString from, QString to , QString file){
636 return this->commandMap.value("misc->"+from+"->"+to)+" "+myOutputFolder+" "+file;
637 }
638
639 void MainWindow::addRowTable(DropTableWidget *myTable, QString fileName, QString fromTo, QString command){
640 //Get actual number rows
641 int twSize=myTable->rowCount();
642
643 //increase the rows for the new item
644 myTable->setRowCount(twSize+1);
645
646 //Add to table and list to
647 QTableWidgetItem *newFile = new QTableWidgetItem(fileName);
648 QTableWidgetItem *newConversion = new QTableWidgetItem(fromTo);
649 QTableWidgetItem *newCommand = new QTableWidgetItem(command);
650
651 myTable->setItem(twSize,0,newFile);
652 myTable->setItem(twSize,1,newConversion);
653 myTable->setItem(twSize,2,newCommand);
654
655 myTable->updateTableToolTips(twSize); //Update tool tips
656 }
657
658 void MainWindow::on_pbConvertXML_clicked()
659 {
660 startConversion(ui->twSourcesXML);
661 }
662
663 void MainWindow::on_pbConvertTextures_clicked()
664 {
665 startConversion(ui->twSourcesTextures);
666 }
667
668 void MainWindow::on_pbConvertObjects_clicked()
669 {
670 startConversion(ui->twSourcesObjects);
671 }
672
673 void MainWindow::on_pbConvertCharacters_clicked()
674 {
675 startConversion(ui->twSourcesCharacters);
676 }
677
678 void MainWindow::on_pbConvertLevels_clicked()
679 {
680 startConversion(ui->twSourcesLevels);
681 }
682
683 void MainWindow::on_pbConvertMisc_clicked()
684 {
685 startConversion(ui->twSourcesMisc);
686 }
687
688 void MainWindow::startConversion(DropTableWidget *myTable){
689
690 bool ready=false;
691 for(int i=0; i<myTable->rowCount(); i++){ //There are items to process?
692 if(myTable->item(i,2)->background()!=myTable->disabledBackStyle){
693 ready=true;
694 break;
695 }
696 }
697
698 if(!ready){
699 showErrStatusMessage("Please add sources to convert first.");
700 return;
701 }
702
703 if(this->myBar->isVisible()){
704 Util::showErrorPopUp("Another conversion is progress. Please wait until it finishes.");
705 return;
706 }
707
708 for(int i=0; i<myTable->rowCount(); i++){
709 //Only process enabled items
710 if(myTable->item(i,2)->background()!=myTable->disabledBackStyle){
711 this->listToProccess->append(myTable->item(i,2)->text());
712 }
713 }
714
715 this->myConverter->start();
716 }
717
718 void MainWindow::TsetupProgressBar(int max){
719 this->myBar->setValue(0);
720 this->myBar->show();
721 this->myBar->setMaximum(max);
722 ui->tbAbortConversion->show();
723 }
724
725 void MainWindow::TupdateProgressBar(){
726 this->myBar->setValue(this->myBar->value()+1); //more one task done
727 }
728
729 void MainWindow::TresultConversion(QString result, int numErrors){
730 QApplication::alert(this); //Show a notification if window is not active
731 this->myBar->hide();
732 ui->tbAbortConversion->hide();
733
734 if(numErrors!=0){
735 QString sNumErrors=QString::number(numErrors);
736 if(numErrors>1){
737 Util::showErrorLogPopUp(result+"\n This is the last of "+sNumErrors+" Errors.");
738 showErrStatusMessage("Something gone wrong. Check log file ("+sNumErrors+" Errors).");
739 }
740 else{
741 Util::showErrorLogPopUp(result);
742 showErrStatusMessage("Something gone wrong. Check log file.");
743 }
744
745 }
746 else{
747 showSuccessStatusMessage("Everything went well!");
748 }
749 }
750
751 void MainWindow::TconversionAborted(){
752 this->myBar->hide();
753 ui->tbAbortConversion->hide();
754
755 showErrStatusMessage("Conversion was aborted.");
756 }
757
758 void MainWindow::showErrStatusMessage(QString message){
759
760 QPalette myPalete = QPalette();
761 myPalete.setColor( QPalette::WindowText, QColor(255,0,0));
762 statusBar()->setPalette( myPalete );
763 ui->statusBar->showMessage(message,10000); //display by 10 seconds
764
765 }
766
767 void MainWindow::showSuccessStatusMessage(QString message){
768
769 QPalette myPalete = QPalette();
770 myPalete.setColor( QPalette::WindowText, QColor(0,150,0));
771 statusBar()->setPalette( myPalete );
772 ui->statusBar->showMessage(message,10000); //display by 10 seconds
773
774 }
775
776 void MainWindow::mapCommands(){
777 ////////////////////////////////////////////////////////////////////////XML Commands
778 this->commandMap.insert("xml->ONI->XML","-extract:xml");
779 this->commandMap.insert("xml->XML->ONI","-create");
780 //######################General Options
781
782 //Possible Combinations
783 this->commandMap.insertMulti("xml->ONI","XML");
784 this->commandMap.insertMulti("xml->XML","ONI");
785
786 ////////////////////////////////////////////////////////////////////////Textures Commands
787 this->commandMap.insert("textures->DAT / TXMP ONI->DDS","-extract:dds");
788 this->commandMap.insert("textures->DAT / TXMP ONI->TGA","-extract:tga");
789 this->commandMap.insert("textures->DAT / TXMP ONI->PNG","-extract:png");
790 this->commandMap.insert("textures->DAT / TXMP ONI->JPG","-extract:jpg");
791 this->commandMap.insert("textures->TGA / DDS / PNG / JPG->TXMP ONI","-create:txmp");
792 //######################Textures Options
793 this->commandMap.insert("textures->"+ui->rbBGR32->text(),"-format:bgr32");
794 this->commandMap.insert("textures->"+ui->rbBGRA32->text(),"-format:bgra32");
795 this->commandMap.insert("textures->"+ui->rbBGR555->text(),"-format:bgr555");
796 this->commandMap.insert("textures->"+ui->rbBGRA5551->text(),"-format:bgra5551");
797 this->commandMap.insert("textures->"+ui->rbBGRA444->text(),"-format:bgra4444");
798 this->commandMap.insert("textures->"+ui->rbDxt1->text(),"-format:dxt1");
799 this->commandMap.insert("textures->"+ui->cbMipMapsTextures->text(),"-genmipmaps");
800 this->commandMap.insert("textures->"+ui->cbNoUwrap->text(),"-nouwrap");
801 this->commandMap.insert("textures->"+ui->cbNoVwrap->text(),"-novwrap");
802 this->commandMap.insert("textures->"+ui->cbLarge->text(),"-large");
803 this->commandMap.insert("textures->"+ui->cbEnvMap->text(),"-envmap:");
804 //Possible Combinations
805 this->commandMap.insertMulti("textures->DAT / TXMP ONI","TGA");
806 this->commandMap.insertMulti("textures->DAT / TXMP ONI","DDS");
807 this->commandMap.insertMulti("textures->DAT / TXMP ONI","PNG");
808 this->commandMap.insertMulti("textures->DAT / TXMP ONI","JPG");
809 this->commandMap.insertMulti("textures->TGA / DDS / PNG / JPG","TXMP ONI");
810
811 ////////////////////////////////////////////////////////////////////////Characters Commands
812 this->commandMap.insert("characters->TRAM ONI->XML / XML & DAE","-extract:xml");
813 this->commandMap.insert("characters->TRBS / ONCC ONI->DAE","-extract:dae");
814 this->commandMap.insert("characters->TRBS XML->TRBS ONI","-create");
815 this->commandMap.insert("characters->TRBS DAE->TRBS ONI","-create:trbs");
816 this->commandMap.insert("characters->FILM DAT->XML","film2xml");
817
818 //######################Characters Options
819 this->commandMap.insert("characters->"+ui->cbWithTRBS_ONCC->text(),"-anim-body:");
820 this->commandMap.insert("characters->"+ui->cbCellShading->text(),"-cel");
821 this->commandMap.insert("characters->"+ui->cbNormals->text(),"-normals");
822 //Possible Combinations
823 this->commandMap.insertMulti("characters->TRAM ONI","XML / XML & DAE");
824 this->commandMap.insertMulti("characters->TRBS / ONCC ONI","DAE");
825 this->commandMap.insertMulti("characters->DAE","TRBS ONI");
826 this->commandMap.insertMulti("characters->TRBS DAE","TRBS ONI");
827 this->commandMap.insertMulti("characters->TRBS XML","TRBS ONI");
828 this->commandMap.insertMulti("characters->FILM DAT","XML");
829
830 ////////////////////////////////////////////////////////////////////////Objects Commands
831 this->commandMap.insert("objects->M3GM ONI->OBJ","-extract:obj");
832 this->commandMap.insert("objects->M3GM ONI->DAE","-extract:dae");
833 this->commandMap.insert("objects->ONWC ONI->OBJ","-extract:obj");
834 this->commandMap.insert("objects->ONWC ONI->DAE","-extract:dae");
835 this->commandMap.insert("objects->OBAN ONI (cam)->DAE","-extract:dae");
836 this->commandMap.insert("objects->OBJ->M3GM ONI","-create:m3gm");
837 //######################Characters Options
838 this->commandMap.insert("objects->"+ui->cbTexture->text(),"-tex:");
839 this->commandMap.insert("objects->"+ui->cbWithAnimation->text(),"-geom:");
840 //Possible Combinations
841 this->commandMap.insertMulti("objects->M3GM ONI","OBJ");
842 this->commandMap.insertMulti("objects->M3GM ONI","DAE");
843 this->commandMap.insertMulti("objects->ONWC ONI","OBJ");
844 this->commandMap.insertMulti("objects->ONWC ONI","DAE");
845 this->commandMap.insertMulti("objects->OBAN ONI (cam)","DAE");
846 this->commandMap.insertMulti("objects->OBJ","M3GM ONI");
847
848
849 ////////////////////////////////////////////////////////////////////////Levels Commands
850 this->commandMap.insert("levels->DAT->ONI FILES","-export");
851 //this->commandMap.insert("levels->ONI FILES->DAT","-import"); //Not used.
852 this->commandMap.insert("levels->ONI FILES->DAT(PC)","-import:nosep");
853 this->commandMap.insert("levels->ONI FILES->DAT(demoPCMAC)","-import:sep");
854 this->commandMap.insert("levels->AKEV ONI->DAE","-extract:dae");
855 this->commandMap.insert("levels->DAE->AKEV ONI","-create:akev");
856 this->commandMap.insert("levels->MASTER XML->DAT","-create:level");
857 this->commandMap.insert("levels->MASTER XML->ONI FILES","-create:level");
858 //######################Levels Options
859 this->commandMap.insert("levels->"+ui->cbGridsLevels->text(),"-grid:create");
860 //Possible Combinations
861 this->commandMap.insertMulti("levels->DAT","ONI FILES");
862 this->commandMap.insertMulti("levels->ONI FILES","DAT");
863 this->commandMap.insertMulti("levels->AKEV ONI","DAE");
864 this->commandMap.insertMulti("levels->DAE","AKEV ONI");
865 this->commandMap.insertMulti("levels->MASTER XML","DAT");
866 this->commandMap.insertMulti("levels->MASTER XML","ONI FILES");
867
868 ////////////////////////////////////////////////////////////////////////Misc Commands
869 this->commandMap.insert("misc->DAT / SNDD ONI->WAV","-extract:wav");
870 this->commandMap.insert("misc->DAT / SNDD ONI->AIF","-extract:aif");
871 this->commandMap.insert("misc->DAT / SUBT ONI->TXT","-extract:txt");
872 this->commandMap.insert("misc->WAV / AIF->SNDD ONI","-create");
873 this->commandMap.insert("misc->TXT->SUBT ONI","-create:subt");
874 //Possible Combinations
875 this->commandMap.insertMulti("misc->DAT / SNDD ONI","WAV");
876 this->commandMap.insertMulti("misc->DAT / SNDD ONI","AIF");
877 this->commandMap.insertMulti("misc->DAT / SUBT ONI","TXT");
878 this->commandMap.insertMulti("misc->WAV / AIF","SNDD ONI");
879 this->commandMap.insertMulti("misc->TXT","SUBT ONI");
880
881 }
882
883 void MainWindow::on_cbFromXML_currentIndexChanged(const QString &arg1)
884 {
885 updateComboBox(arg1, ui->cbToXML);
886 }
887
888
889 void MainWindow::on_cbFromTextures_currentIndexChanged(const QString &arg1)
890 {
891 //Options are only used for DAT/ONI -> Image
892 if(QString::compare(arg1,"DAT / ONI",Qt::CaseSensitive)==0){ //case sensitive is faster
893 ui->gbTextures->setEnabled(false);
894 }
895 else{
896 ui->gbTextures->setEnabled(true);
897 }
898
899 updateComboBox(arg1, ui->cbToTextures);
900 }
901
902 void MainWindow::on_cbFromObjects_currentIndexChanged(const QString &arg1)
903 {
904 ui->cbTexture->setEnabled(false);
905 ui->cbTexture->setChecked(false);
906 ui->cbWithAnimation->setEnabled(false);
907 ui->cbWithAnimation->setChecked(false);
908
909 if(QString::compare(arg1,"M3GM ONI",Qt::CaseSensitive)==0){ //case sensitive is faster
910 ui->cbWithAnimation->setEnabled(true);
911 }
912 else if(QString::compare(arg1,"OBJ",Qt::CaseSensitive)==0){
913 ui->cbTexture->setEnabled(true);
914 }
915
916 updateComboBox(arg1, ui->cbToObjects);
917 }
918
919 void MainWindow::on_cbFromCharacters_currentIndexChanged(const QString &arg1)
920 {
921 ui->cbWithTRBS_ONCC->setEnabled(false);
922 ui->cbWithTRBS_ONCC->setChecked(false);
923 ui->cbCellShading->setEnabled(false);
924 ui->cbCellShading->setChecked(false);
925 ui->cbNormals->setEnabled(false);
926 ui->cbNormals->setChecked(false);
927
928 if(QString::compare(arg1,"TRAM ONI",Qt::CaseSensitive)==0){ //case sensitive is faster
929 ui->cbWithTRBS_ONCC->setEnabled(true);
930 }
931 else if(QString::compare(arg1,"TRBS DAE",Qt::CaseSensitive)==0){
932 ui->cbNormals->setEnabled(true);
933 ui->cbCellShading->setEnabled(true);
934 }
935
936 updateComboBox(arg1, ui->cbToCharacters);
937 }
938
939 void MainWindow::on_cbFromLevels_currentIndexChanged(const QString &arg1)
940 {
941
942 ui->cbSpecificFilesLevels->setEnabled(false);
943 ui->cbSpecificFilesLevels->setChecked(false);
944 ui->cbDatLevels->setEnabled(false);
945 ui->cbDatLevels->setChecked(false);
946 ui->cbBnvLevels->setEnabled(false);
947 ui->cbBnvLevels->setChecked(false);
948 ui->cbAdditionalSourcesLevels->setEnabled(false);
949 ui->cbAdditionalSourcesLevels->setChecked(false);
950 ui->cbGridsLevels->setEnabled(false);
951 ui->cbGridsLevels->setChecked(false);
952
953 if(arg1=="DAT"){ //case sensitive is faster
954 ui->cbSpecificFilesLevels->setEnabled(true);
955 }
956 else if(arg1=="ONI FILES"){ //case sensitive is faster
957 ui->cbDatLevels->setEnabled(true);
958 }
959 else if(arg1=="DAE"){
960 ui->cbBnvLevels->setEnabled(true);
961 ui->cbAdditionalSourcesLevels->setEnabled(true);
962 }
963
964 updateComboBox(arg1, ui->cbToLevels);
965 }
966
967 void MainWindow::on_cbFromMisc_currentIndexChanged(const QString &arg1)
968 {
969 updateComboBox(arg1, ui->cbToMisc);
970 }
971
972 void MainWindow::updateComboBox(const QString &arg1, QComboBox *comboBox){
973 QString identifier=ui->tabWidget->tabText(ui->tabWidget->currentIndex()).toLower(); // get current tab title text (lower case)
974
975 comboBox->clear();
976
977 QStringList toUpdate=QStringList();
978
979 QStringList values=commandMap.values(identifier+"->"+arg1);
980
981 for (int i = values.size()-1; i >= 0; i--){ //By defaut MultiItems have the inversed order (http://qt-project.org/doc/qt-4.8/qhash.html#insertMulti)
982 toUpdate << values.at(i);
983 }
984
985 comboBox->addItems(toUpdate);
986 }
987
988
989 void MainWindow::on_actionWindows_triggered()
990 {
991 ui->actionWindows->setChecked(true);
992 ui->actionMac_Windows_demo->setChecked(false);
993 }
994
995 void MainWindow::on_actionMac_Windows_demo_triggered()
996 {
997 ui->actionMac_Windows_demo->setChecked(true);
998 ui->actionWindows->setChecked(false);
999 }
1000
1001 void MainWindow::on_pbRemoveSourceXML_clicked()
1002 {
1003 removeTableContents( ui->twSourcesXML);
1004 }
1005
1006 void MainWindow::on_pbRemoveSourceTextures_clicked()
1007 {
1008 removeTableContents(ui->twSourcesTextures);
1009 }
1010
1011 void MainWindow::on_pbRemoveSourceObjects_clicked()
1012 {
1013 removeTableContents(ui->twSourcesObjects);
1014 }
1015
1016 void MainWindow::on_pbRemoveSourceCharacters_clicked()
1017 {
1018 removeTableContents(ui->twSourcesCharacters);
1019 }
1020
1021 void MainWindow::on_pbRemoveSourceLevels_clicked()
1022 {
1023 removeTableContents(ui->twSourcesLevels);
1024 }
1025
1026 void MainWindow::on_pbRemoveSourceMisc_clicked()
1027 {
1028 removeTableContents(ui->twSourcesMisc);
1029 }
1030
1031 void MainWindow::on_pbClearSourcesXML_clicked()
1032 {
1033 clearTableContents(ui->twSourcesXML);
1034 }
1035
1036 void MainWindow::on_pbClearSourcesTextures_clicked()
1037 {
1038 clearTableContents(ui->twSourcesTextures);
1039 }
1040
1041 void MainWindow::on_pbClearSourcesObjects_clicked()
1042 {
1043 clearTableContents(ui->twSourcesObjects);
1044 }
1045
1046 void MainWindow::on_pbClearSourcesCharacters_clicked()
1047 {
1048 clearTableContents(ui->twSourcesCharacters);
1049 }
1050
1051 void MainWindow::on_pbClearSourcesLevels_clicked()
1052 {
1053 clearTableContents(ui->twSourcesLevels);
1054 }
1055
1056 void MainWindow::on_pbClearSourcesMisc_clicked()
1057 {
1058 clearTableContents(ui->twSourcesMisc);
1059 }
1060
1061 void MainWindow::removeTableContents(DropTableWidget *myTable){
1062 int size = myTable->selectionModel()->selectedRows().size();
1063
1064 QMessageBox::StandardButton defaultButton = QMessageBox::NoButton; // default button for clear asking question, only customizable in mac os
1065
1066 if(size==0){
1067 Util::showPopUp("Select a row first.");
1068 return;
1069 }
1070
1071 #ifdef Q_OS_MAC
1072 if(this->useYesAsDefaultWhenRemovingItems){
1073 defaultButton = QMessageBox::Yes;
1074 }
1075 else{
1076 defaultButton = QMessageBox::No;
1077 }
1078 #endif
1079
1080
1081 if(Util::showQuestionPopUp(this,"Are you sure you want to delete the selected rows?",defaultButton)){
1082 for(int i=0; i<size; i++){
1083 //myTable->removeRow(myTable->selectedItems().at(size-i-1)->row());
1084 myTable->removeRow(myTable->selectionModel()->selectedRows().at(size-i-1).row());
1085 }
1086 updateItemsLoaded(myTable);
1087 }
1088 }
1089
1090 void MainWindow::clearTableContents(DropTableWidget *myTable){
1091
1092 QMessageBox::StandardButton defaultButton = QMessageBox::NoButton; // default button for clear asking question, only customizable in mac os
1093
1094 if(myTable->rowCount()==0){
1095 Util::showPopUp("Nothing to clear.");
1096 return;
1097 }
1098
1099 #ifdef Q_OS_MAC
1100 if(this->useYesAsDefaultWhenRemovingItems){
1101 defaultButton = QMessageBox::Yes;
1102 }
1103 else{
1104 defaultButton = QMessageBox::No;
1105 }
1106 #endif
1107
1108 if(Util::showQuestionPopUp(this,"Are you sure you want to clear the content?",defaultButton)){
1109 myTable->clearContents();
1110 myTable->setRowCount(0);
1111 }
1112 updateItemsLoaded(myTable);
1113 }
1114
1115
1116 void MainWindow::on_actionPreferences_triggered()
1117 {
1118 //Show preferences
1119 Preferences *preferencesWindow = new Preferences(this,this->vagoSettings);
1120 preferencesWindow->exec(); //it destroys itself when finished.
1121 }
1122
1123
1124 void MainWindow::closeEvent(QCloseEvent *event){
1125 if(this->vagoSettings->value("ConfirmExit").toBool()){
1126 if(!Util::showQuestionPopUp(this,"Exit Vago?")){
1127 event->ignore();
1128 }
1129 }
1130 }
1131
1132 void MainWindow::on_cbToLevels_currentIndexChanged(const QString &arg1)
1133 {
1134
1135 if(ui->cbFromLevels->currentText()=="MASTER XML" && arg1=="DAT"){
1136 ui->cbDatLevels->setEnabled(true);
1137 }
1138 else if(ui->cbFromLevels->currentText()=="MASTER XML" && arg1=="ONI FILES"){
1139 ui->cbDatLevels->setEnabled(false);
1140 ui->cbDatLevels->setChecked(false);
1141 }
1142
1143 }
1144
1145 void MainWindow::on_cbDatLevels_toggled(bool checked)
1146 {
1147 ui->leTargetDatLevels->setEnabled(checked);
1148 }
1149
1150 void MainWindow::on_cbBnvLevels_toggled(bool checked)
1151 {
1152 ui->leBnvLevels->setEnabled(checked);
1153 ui->cbGridsLevels->setEnabled(checked);
1154 ui->cbGridsLevels->setChecked(checked);
1155 if(checked){
1156 QString file=QFileDialog::getOpenFileName(this,"Choose the BNV.dae file...","./" , "All Files (*.*)");
1157 if(!file.isEmpty()){
1158 ui->leBnvLevels->setText(file);
1159 }
1160 }
1161 }
1162
1163 void MainWindow::on_cbAdditionalSourcesLevels_toggled(bool checked)
1164 {
1165 ui->leAdditSourcesLevels->setEnabled(checked);
1166
1167 if(checked){
1168 QStringList filesSelected=QFileDialog::getOpenFileNames(this,"Choose the additional .dae files...","./" , "All Files (*.*)");
1169 QString filesJoined;
1170 int size=filesSelected.size();
1171
1172 if(!filesSelected.isEmpty()){
1173 for(int i=0; i<size-1; i++){
1174 filesJoined+=filesSelected.at(i)+" ";
1175 }
1176 filesJoined+=filesSelected.at(size-1); //last doesn't have space after
1177 ui->leAdditSourcesLevels->setText(filesJoined);
1178 }
1179
1180 }
1181 }
1182
1183 void MainWindow::on_cbWithTRBS_ONCC_toggled(bool checked)
1184 {
1185 ui->leTRBS_ONCC->setEnabled(checked);
1186 }
1187
1188 void MainWindow::on_actionCheck_OniSplit_version_triggered()
1189 {
1190 QProcess *myProcess = new QProcess();
1191 myProcess->setWorkingDirectory(this->AppDir);
1192 myProcess->start(GlobalVars::OniSplitExeName+" -version");
1193 myProcess->waitForFinished(-1);
1194 QString result=myProcess->readAllStandardOutput();
1195 delete myProcess;
1196 Util::showPopUp("This Vago version was built with base in OniSplit version "+GlobalVars::BuiltOniSplitVersion+"\n\nActual version is:\n"+result);
1197 }
1198
1199 void MainWindow::on_actionCheck_xmlTools_version_triggered()
1200 {
1201 QProcess *myProcess = new QProcess();
1202 myProcess->setWorkingDirectory(this->AppDir);
1203 myProcess->start(GlobalVars::XmlToolsExeName+" version");
1204 myProcess->waitForFinished(-1);
1205 QString result=myProcess->readLine();
1206 delete myProcess;
1207 Util::showPopUp("This Vago version was built with base in xmlTools version "+GlobalVars::BuiltXmlToolsVersion+"\n\nActual version is:\n"+result);
1208 }
1209
1210 /**
1211 Update items loaded
1212 **/
1213 void MainWindow::on_tabWidget_currentChanged(int index)
1214 {
1215 QString tabtext = ui->tabWidget->tabText(index);
1216
1217 if(tabtext.compare("XML",Qt::CaseSensitive)==0){ //case sentive is faster
1218 updateItemsLoaded(ui->twSourcesXML);
1219 }
1220 else if(tabtext.compare("Textures",Qt::CaseSensitive)==0){
1221 updateItemsLoaded(ui->twSourcesTextures);
1222 }
1223 else if(tabtext.compare("Characters",Qt::CaseSensitive)==0){
1224 updateItemsLoaded(ui->twSourcesCharacters);
1225 }
1226 else if(tabtext.compare("Objects",Qt::CaseSensitive)==0){
1227 updateItemsLoaded(ui->twSourcesObjects);
1228 }
1229 else if(tabtext.compare("Levels",Qt::CaseSensitive)==0){
1230 updateItemsLoaded(ui->twSourcesLevels);
1231 }
1232 else{
1233 updateItemsLoaded(ui->twSourcesMisc);
1234 }
1235 }
1236
1237 void MainWindow::updateItemsLoaded(DropTableWidget *currentTable){
1238
1239 int numItems=currentTable->rowCount();
1240
1241 this->itemsLoaded->setText(QString().setNum(numItems)+ (numItems==1?" item ":" items ") +"loaded");
1242 }
1243
1244 void MainWindow::on_tbCommand_clicked()
1245 {
1246 //Show preferences
1247 ManualCommands *commandsWindow = new ManualCommands(this);
1248 commandsWindow->show(); //it destroys itself when finished.
1249 }
1250
1251 void MainWindow::on_actionWorkspace_triggered()
1252 {
1253 ui->actionWorkspace->setChecked(true);
1254 ui->actionOther->setChecked(false);
1255 this->outputFolder=this->workspaceLocation;
1256 ui->tbOpenFolder->setToolTip("Open Vago workspace");
1257 showSuccessStatusMessage("Vago is now outputting the NEW items for Vago workspace.");
1258 }
1259
1260 void MainWindow::on_actionOther_triggered()
1261 {
1262 QString newDir=QFileDialog::getExistingDirectory(this,"Choose the folder for output NEW files directly...",this->AeLocation+"/GameDataFolder");
1263 newDir=Util::normalizePath(newDir);
1264
1265 if(newDir.isEmpty()){
1266 ui->actionOther->setChecked(false);
1267 return; //do nothing
1268 }
1269
1270 if(newDir==this->workspaceLocation){
1271 on_actionWorkspace_triggered(); //set it to vago workspace
1272 return;
1273 }
1274
1275 ui->actionOther->setChecked(true);
1276 ui->actionWorkspace->setChecked(false);
1277
1278 this->outputFolder=newDir;
1279
1280 QString newDirName=Util::cutName(newDir);
1281 ui->tbOpenFolder->setToolTip("Open "+newDirName+" output folder");
1282 showSuccessStatusMessage("Vago is now outputting the NEW items for "+newDirName+".");
1283 }
1284
1285 void MainWindow::on_actionView_log_triggered()
1286 {
1287 Util::openLogFile();
1288 }
1289
1290 void MainWindow::on_actionOpen_AE_folder_triggered()
1291 {
1292 QDesktopServices::openUrl(QUrl("file:///"+this->AeLocation));
1293 }
1294
1295 QString MainWindow::getTypeConversion(DropTableWidget *myTable){
1296 QString from,to;
1297
1298 if(myTable==ui->twSourcesXML){
1299 from=ui->cbFromXML->currentText();
1300 to=ui->cbToXML->currentText();
1301 }
1302 else if(myTable==ui->twSourcesTextures){
1303 from=ui->cbFromTextures->currentText();
1304 to=ui->cbToTextures->currentText();
1305 }
1306 else if(myTable==ui->twSourcesObjects){
1307 from=ui->cbFromObjects->currentText();
1308 to=ui->cbToObjects->currentText();
1309 }
1310 else if(myTable==ui->twSourcesCharacters){
1311 from=ui->cbFromCharacters->currentText();
1312 to=ui->cbToCharacters->currentText();
1313 }
1314 else if(myTable==ui->twSourcesLevels){
1315 from=ui->cbFromLevels->currentText();
1316 to=ui->cbToLevels->currentText();
1317 }
1318 else{
1319 from=ui->cbFromMisc->currentText();
1320 to=ui->cbToMisc->currentText();
1321 }
1322
1323 return from + " > " + to;
1324 }
1325
1326 //Drop table widget context menu
1327 void MainWindow::dtContextMenu(DropTableWidget* myTable, QContextMenuEvent *event){
1328 QModelIndex index = myTable->indexAt(event->pos());
1329
1330 //item exists?
1331 if(!index.isValid())
1332 return;
1333
1334 if(myTable->selectionModel()->selectedRows().size()==0){ //No multiple rows selected
1335 myTable->selectRow(myTable->itemAt(event->pos())->row()); //select all the row of the item clicked
1336 }
1337
1338 QList<int> selectedRows = QList<int>();
1339
1340 foreach(QModelIndex rowItem, myTable->selectionModel()->selectedRows()){
1341 selectedRows << rowItem.row();
1342 }
1343
1344 QMenu *menu = new QMenu();
1345 QAction *copy = new QAction("Copy",myTable);
1346 QAction *moveUp = new QAction("Move Up",myTable);
1347 QAction *moveDown = new QAction("Move Down",myTable);
1348 QAction *changeOptions = new QAction("Change To Current Options",myTable);
1349 QMenu *changeOutput = new QMenu("Change Output for:");
1350 QAction *outWorkspace = new QAction("Workspace",myTable);
1351 QAction *outCurrOutput = new QAction("Current Output Folder",myTable);
1352 QAction *outOther = new QAction("Other...",myTable);
1353 QAction *edisable = new QAction("Enable/Disable",myTable);
1354
1355 menu->addAction(copy);
1356 menu->addSeparator();
1357 menu->addAction(moveUp);
1358 menu->addAction(moveDown);
1359 menu->addSeparator();
1360 menu->addAction(changeOptions);
1361 menu->addMenu(changeOutput);
1362 changeOutput->addActions(QList<QAction*>() << outWorkspace << outCurrOutput << outOther);
1363 menu->addAction(edisable);
1364
1365
1366 //if it's in the first row it can't be setted up
1367 if(selectedRows.at(0)==0){
1368 moveUp->setEnabled(false);
1369 }
1370
1371 //if we are at bottom we can't go down
1372 if(selectedRows.at(selectedRows.size()-1)==myTable->rowCount()-1){
1373 moveDown->setEnabled(false);
1374 }
1375
1376 //Can we change the settings? (the conversion must be the same)
1377 QString currentSettings = (getTypeConversion(myTable)); //call function at the mainWindow with a signal (different threads?)
1378 foreach(int row, selectedRows){
1379 if( myTable->item(row,1)->text() != currentSettings){ //If we find out any of the selected items can't be convert disable operation
1380 changeOptions->setEnabled(false);
1381 break;
1382 }
1383 }
1384
1385 QAction* selectedOption = menu->exec(event->globalPos());
1386
1387 if(selectedOption==copy){
1388 //Let's copy the contents to the clipboard
1389
1390 QString toCopy;
1391
1392 int size=selectedRows.size();
1393
1394 //Let's format it a bit...
1395 for(int i=0; i<size; i++){
1396 for(int j=0; j<myTable->columnCount(); j++){
1397 toCopy+=myTable->item(selectedRows.at(i),j)->text();
1398 if(j!=myTable->columnCount()-1){
1399 toCopy+="\t";
1400 }
1401 }
1402 if(i!=size-1){
1403 toCopy+="\n";
1404 }
1405 }
1406
1407 QApplication::clipboard()->setText(toCopy);
1408 showSuccessStatusMessage(QString::number(size) + (size==1?" item ":" items ")+ "copied to the clipboard");
1409 }
1410 else if(selectedOption==moveUp){
1411 qSort(selectedRows); //let's order the selections by the row number, so we know exactly how to swap it
1412 myTable->swapPositions(selectedRows,-1);
1413 }
1414 else if(selectedOption==moveDown){
1415 qSort(selectedRows);
1416 myTable->swapPositions(selectedRows,+1);
1417 }
1418 else if(selectedOption==changeOptions){
1419 changeToCurrentSettings(selectedRows,myTable);
1420 }
1421 else if(selectedOption==outWorkspace){
1422 changeItemsOutput(myTable,selectedRows,this->workspaceLocation);
1423 }
1424 else if(selectedOption==outCurrOutput){
1425 changeItemsOutput(myTable,selectedRows,this->outputFolder);
1426 }
1427 else if(selectedOption==outOther){
1428
1429 QString newDir=QFileDialog::getExistingDirectory(this,"Choose the folder for the output of the files selected...",this->AeLocation+"/GameDataFolder");
1430 newDir=Util::normalizePath(newDir);
1431
1432 if(newDir.isEmpty()){
1433 return; //do nothing
1434 }
1435
1436 changeItemsOutput(myTable,selectedRows,newDir);
1437
1438 }
1439 else if(selectedOption==edisable){
1440
1441 int enabledCount=0, disabledCount=0;
1442
1443 for(int i=0; i<selectedRows.size(); i++){
1444
1445 for(int j=0; j<myTable->columnCount(); j++){
1446 QTableWidgetItem *currentItem=myTable->item(selectedRows.at(i),j);
1447
1448 if(currentItem->background()!=myTable->disabledBackStyle){
1449 myTable->setDisableStyleWidgetItem(currentItem);
1450 if(j==0){ //Only count the row, not the columns
1451 disabledCount++;
1452 }
1453 }
1454 else{ //reset to initial state (enable)
1455 myTable->resetStyleWidgetItem(currentItem);
1456 if(j==0){
1457 enabledCount++;
1458 }
1459 }
1460 }
1461 }
1462
1463 QString result;
1464
1465 if(enabledCount!=0){
1466 result+=QString::number(enabledCount) + (enabledCount==1?" item ":" items ") + "Enabled";
1467 }
1468 if(enabledCount!=0 && disabledCount!=0){
1469 result+=" and ";
1470 }
1471 if(disabledCount!=0){
1472 result+=QString::number(disabledCount) + (disabledCount==1?" item ":" items ") + "Disabled";
1473 }
1474
1475 showSuccessStatusMessage(result);
1476 }
1477
1478 delete copy;
1479 delete moveUp;
1480 delete moveDown;
1481 delete changeOptions;
1482 delete outWorkspace;
1483 delete outCurrOutput;
1484 delete outOther;
1485 delete changeOutput;
1486 delete edisable;
1487 delete menu;
1488 }
1489
1490 void MainWindow::changeToCurrentSettings(QList<int> rows, DropTableWidget* myTable){
1491 //construct a command for each one
1492 //Output a status message saying the number of changed files
1493 QString fromTo=getTypeConversion(myTable);
1494 QString from = QString(fromTo).remove(fromTo.indexOf(" >"),fromTo.size()-1); //parse the string to get the from, only 1 time parsed by each group of files = very fast
1495 QString to = QString(fromTo).remove(0,fromTo.lastIndexOf("> ")+2); //+2 to start after "> "
1496
1497 QString command;
1498
1499 foreach(int row, rows){
1500
1501 command=getCommand(myTable,getFileOutputFolder(fromTo,myTable->getOutputAbsolute(row)),from,to,myTable->getFileAbsolute(row));
1502
1503 if(command.isEmpty()){ //something wrong was happening (not inputted a texture name?)
1504 return; //stop changing settings
1505 }
1506
1507 myTable->item(row,2)->setText(command); //update settings to the current row
1508 myTable->updateTableToolTips(row);
1509 }
1510
1511 showSuccessStatusMessage(QString::number(rows.size()) + (rows.size()==1?" item ":" items ")+ "changed to the current settings");
1512 }
1513
1514 void MainWindow::changeItemsOutput(DropTableWidget* myTable, QList<int> rows, QString newOutput){
1515
1516 QString command, currentAbsoluteFile, fromTo, from, to;
1517
1518 foreach(int row, rows){ //No optimization possible here, commands may be different
1519 fromTo=myTable->item(row,1)->text();
1520 from = QString(fromTo).remove(fromTo.indexOf(" >"),fromTo.size()-1); //parse the string to get the from
1521 to = QString(fromTo).remove(0,fromTo.lastIndexOf("> ")+2); //+2 to start after "> "
1522
1523 currentAbsoluteFile=myTable->getFileAbsolute(row);
1524 command=getCommand(myTable,getFileOutputFolder(fromTo,newOutput),from,to,currentAbsoluteFile);
1525
1526 if(command.isEmpty()){ //something wrong was happening (not inputted a texture name?)
1527 return; //stop changing output
1528 }
1529
1530 myTable->item(row,2)->setText(command); //update command to the current row
1531 myTable->updateTableToolTips(row);
1532 }
1533
1534 showSuccessStatusMessage(QString::number(rows.size()) + (rows.size()==1?" item ":" items ")+ "changed the output to "+(newOutput!=this->workspaceLocation?Util::cutName(newOutput):"Vago workspace"));
1535 }
1536
1537 QString MainWindow::getCommand(DropTableWidget* myTable, QString myOutputFolder, QString from, QString to , QString file){
1538
1539 QString tabTitle=ui->tabWidget->tabText(ui->tabWidget->currentIndex()).toLower(); // get current tab title
1540
1541 if(myTable==ui->twSourcesXML){ //So we only need to parse one command.
1542 return fileParsingXML(tabTitle, myOutputFolder,from,to,file);
1543 }
1544 else if(myTable==ui->twSourcesTextures){
1545 return fileParsingTextures(tabTitle, myOutputFolder,from,to,file);
1546 }
1547 else if(myTable==ui->twSourcesObjects){
1548 return fileParsingObjects(tabTitle, myOutputFolder,from,to,file);
1549 }
1550 else if(myTable==ui->twSourcesCharacters){
1551 return fileParsingCharacters(tabTitle, myOutputFolder,from,to,file);
1552 }
1553 else if(myTable==ui->twSourcesLevels){
1554 return fileParsingLevels(tabTitle, myOutputFolder,from,to,file);
1555 }
1556 else{
1557 return fileParsingMisc(myOutputFolder,from,to,file);
1558 }
1559
1560 }
1561
1562 /**
1563 This is OS indepented. It maintain size ratio over the Windows and Mac.
1564 **/
1565 void MainWindow::setConverterButtonsSize(){
1566 int height=ui->pbConvertXML->sizeHint().height()*1.3;
1567 ui->pbConvertXML->setMinimumHeight(height);
1568 ui->pbConvertTextures->setMinimumHeight(height);
1569 ui->pbConvertObjects->setMinimumHeight(height);
1570 ui->pbConvertCharacters->setMinimumHeight(height);
1571 ui->pbConvertLevels->setMinimumHeight(height);
1572 ui->pbConvertMisc->setMinimumHeight(height);
1573 }
1574
1575 /**
1576 Gets application directory. In mac os gets the .app directory
1577 **/
1578 QString MainWindow::getOSIndependentAppPath(){
1579 #ifdef Q_OS_MAC
1580 QDir dir = QDir::current();
1581 if(dir.absolutePath().contains(".app")){ // include bundle, but we don't want it
1582 dir.cdUp();
1583 dir.cdUp();
1584 dir.cdUp();
1585 }
1586 return dir.absolutePath();
1587 #else
1588 return QDir::currentPath();
1589 #endif
1590 }
1591
1592 void MainWindow::connectSlots(){
1593
1594 //This signal is for thread that is working setup the progress bar (make it visible and set it's min-max)
1595 connect(myConverter, SIGNAL(setupPB(int)), this, SLOT(TsetupProgressBar(int)), Qt::BlockingQueuedConnection);
1596
1597 //This signal is for thread that is working can update the progress bar of the gui
1598 connect(myConverter, SIGNAL(taskDone()), this, SLOT(TupdateProgressBar()),Qt::BlockingQueuedConnection);
1599
1600 //This signal is for thread that is working can show the result of a conversion
1601 connect(myConverter, SIGNAL(resultConversion(QString,int)), this, SLOT(TresultConversion(QString,int)));
1602
1603 //This signal is for thread that is working notify the gui thread that the conversion was aborted with sucess
1604 connect(myConverter, SIGNAL(conversionAborted()), this, SLOT(TconversionAborted()));
1605
1606 // This signal is to the user be able to terminate a conversion (OniSplit process in class myConverter will be terminated)
1607 connect(this, SIGNAL(terminateCurrProcess()), myConverter, SLOT(terminateCurrProcess()));
1608
1609 //Drop signal for General table
1610 connect(ui->twSourcesXML, SIGNAL(dropped(DropTableWidget*,QStringList)), this, SLOT(addFilesSource(DropTableWidget*,QStringList)));
1611
1612 //Drop signal for Textures table
1613 connect(ui->twSourcesTextures, SIGNAL(dropped(DropTableWidget*,QStringList)), this, SLOT(addFilesSource(DropTableWidget*,QStringList)));
1614
1615 //Drop signal for Objects table
1616 connect(ui->twSourcesObjects, SIGNAL(dropped(DropTableWidget*,QStringList)), this, SLOT(addFilesSource(DropTableWidget*,QStringList)));
1617
1618 //Drop signal for Characters table
1619 connect(ui->twSourcesCharacters, SIGNAL(dropped(DropTableWidget*,QStringList)), this, SLOT(addFilesSource(DropTableWidget*,QStringList)));
1620
1621 //Drop signal for Levels table
1622 connect(ui->twSourcesLevels, SIGNAL(dropped(DropTableWidget*,QStringList)), this, SLOT(addFilesSource(DropTableWidget*,QStringList)));
1623
1624 //Drop signal for Misc table
1625 connect(ui->twSourcesMisc, SIGNAL(dropped(DropTableWidget*,QStringList)), this, SLOT(addFilesSource(DropTableWidget*,QStringList)));
1626
1627 //Context menu for General table
1628 connect(ui->twSourcesXML, SIGNAL(dtContextMenu(DropTableWidget*,QContextMenuEvent*)), this, SLOT(dtContextMenu(DropTableWidget*,QContextMenuEvent*)));
1629
1630 //Context menu for Textures table
1631 connect(ui->twSourcesTextures, SIGNAL(dtContextMenu(DropTableWidget*,QContextMenuEvent*)), this, SLOT(dtContextMenu(DropTableWidget*,QContextMenuEvent*)));
1632
1633 //Context menu for Objects table
1634 connect(ui->twSourcesObjects, SIGNAL(dtContextMenu(DropTableWidget*,QContextMenuEvent*)), this, SLOT(dtContextMenu(DropTableWidget*,QContextMenuEvent*)));
1635
1636 //Context menu for Characters table
1637 connect(ui->twSourcesCharacters, SIGNAL(dtContextMenu(DropTableWidget*,QContextMenuEvent*)), this, SLOT(dtContextMenu(DropTableWidget*,QContextMenuEvent*)));
1638
1639 //Context menu for Levels table
1640 connect(ui->twSourcesLevels, SIGNAL(dtContextMenu(DropTableWidget*,QContextMenuEvent*)), this, SLOT(dtContextMenu(DropTableWidget*,QContextMenuEvent*)));
1641
1642 //Context menu for Misc table
1643 connect(ui->twSourcesMisc, SIGNAL(dtContextMenu(DropTableWidget*,QContextMenuEvent*)), this, SLOT(dtContextMenu(DropTableWidget*,QContextMenuEvent*)));
1644 }