ViewVC Help
View File | Revision Log | View Changeset | Root Listing
root/Oni2/s10k/Vago/mainwindow.cpp
(Generate patch)

Comparing Vago/trunk/Vago/mainwindow.cpp (file contents):
Revision 793 by s10k, Sat Apr 6 23:30:00 2013 UTC vs.
Revision 1047 by s10k, Fri Sep 16 22:51:26 2016 UTC

# Line 9 | Line 9 | MainWindow::MainWindow(QWidget *parent)
9   {
10      ui->setupUi(this);
11  
12 <    this->setWindowTitle("Vago v"+GlobalVars::AppVersion);
12 >    this->myLogger = new Logger(UtilVago::getAppPath(), GlobalVars::AppLogName); //start logger
13  
14 <    if(!QFile::exists(QDir::currentPath()+"/"+GlobalVars::OniSplitString)){
15 <        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.");
14 >    this->myLogger->writeString("Detected AppDir: "+UtilVago::getAppPath());
15 >    this->myLogger->writeString("True app dir: "+QDir::currentPath());
16 >
17 >    setVagoWindowTitle();
18 >
19 >    if(!QFile::exists(UtilVago::getOniSplitExeAbsolutePath())){
20 >        UtilVago::showAndLogErrorPopUp(this->myLogger, "OniSplit not found. Please download it at "+GlobalVars::ModsDomain+" and put it the Vago's tools folder. \n\nProgram will now exit.");
21          exit(1);
22      }
23  
24 <    if(!QFile::exists(QDir::currentPath()+"/"+GlobalVars::XmlToolsString)){
25 <        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.");
24 >    if(!QFile::exists(UtilVago::getXmlToolsExeAbsolutePath())){
25 >        UtilVago::showAndLogErrorPopUp(this->myLogger, "XmlTools not found. Please download it at "+GlobalVars::ModsDomain+" and put it the Vago's tools folder. \n\nProgram will now exit.");
26          exit(1);
27      }
28  
29 <    this->vagoSettings = new QSettings(QDir::currentPath() + "/" + this->VagoSettingsName, QSettings::IniFormat);
29 >    this->vagoSettings = new QSettings(UtilVago::getAppPath() + "/" + this->VagoSettingsName, QSettings::IniFormat);
30  
31      //First Execution? Old configuration? Settings missed?
32      bool iniChanged=false;
# Line 30 | Line 35 | MainWindow::MainWindow(QWidget *parent)
35          iniChanged=true;
36      }
37      if(!this->vagoSettings->contains("Workspace")){
38 <        this->vagoSettings->setValue("Workspace", QDir::currentPath()+"/VagoWorkspace");
38 >        this->vagoSettings->setValue("Workspace", UtilVago::getAppPath()+"/VagoWorkspace");
39          iniChanged=true;
40      }
41      if(!this->vagoSettings->contains("AeFolder")){
# Line 39 | Line 44 | MainWindow::MainWindow(QWidget *parent)
44          QString aefolder=Util::normalizePath(QFileDialog::getExistingDirectory(this,"Choose Anniversary Edition (AE) folder..."));
45  
46          if(aefolder.isEmpty()){
47 <            Util::showErrorPopUp("AE folder is mandatory. Application will now exit.");
47 >            UtilVago::showAndLogErrorPopUp(this->myLogger, "AE folder is mandatory. Application will now exit.");
48              exit(1);
49          }
50  
# Line 50 | Line 55 | MainWindow::MainWindow(QWidget *parent)
55          this->vagoSettings->setValue("AeFolder", aefolder);
56          iniChanged=true;
57      }
58 +    if(!this->vagoSettings->contains("WindowWidth")){
59 +        this->vagoSettings->setValue("WindowWidth", GlobalVars::DefaultWindowWidth);
60 +        iniChanged=true;
61 +    }
62 +    if(!this->vagoSettings->contains("WindowHeight")){
63 +        this->vagoSettings->setValue("WindowHeight", GlobalVars::DefaultWindowHeight);
64 +        iniChanged=true;
65 +    }
66      if(!this->vagoSettings->contains("OniWindow")){
67          this->vagoSettings->setValue("OniWindow", true);
68          iniChanged=true;
# Line 62 | Line 75 | MainWindow::MainWindow(QWidget *parent)
75          this->vagoSettings->setValue("ConfirmExit", false);
76          iniChanged=true;
77      }
78 +    if(!this->vagoSettings->contains("LastProjectPath")){
79 +        this->vagoSettings->setValue("LastProjectPath", this->vagoSettings->value("Workspace"));
80 +        iniChanged=true;
81 +    }
82 +    for(int i=0; i<this->recentProjectsMaxSize; i++){
83 +        if(!this->vagoSettings->contains("RecentProject" + QString::number(i+1))){
84 +            this->vagoSettings->setValue("RecentProject" + QString::number(i+1), "");
85 +            iniChanged=true;
86 +        }
87 +    }
88 + #ifdef Q_OS_MAC
89 +    if(!this->vagoSettings->contains("useYesAsDefaultWhenRemovingItems")){
90 +        this->vagoSettings->setValue("useYesAsDefaultWhenRemovingItems", false);
91 +        iniChanged=true;
92 +    }
93 + #endif
94  
95      if(iniChanged){
96          this->vagoSettings->sync();
# Line 72 | Line 101 | MainWindow::MainWindow(QWidget *parent)
101      this->workspaceWizardsLocation=this->workspaceLocation+"/Wizards";
102      this->AeLocation=this->vagoSettings->value("AeFolder").toString();
103      this->outputFolder=this->workspaceLocation;
104 +    this->startedWindowWidth=this->vagoSettings->value("WindowWidth").toInt();
105 +    this->startedWindowHeight=this->vagoSettings->value("WindowHeight").toInt();
106 + #ifdef Q_OS_MAC
107 +    this->useYesAsDefaultWhenRemovingItems=this->vagoSettings->value("useYesAsDefaultWhenRemovingItems").toBool();
108 + #endif
109  
110      //Create our workspace if it doesn't exists yet
111      if(!QDir(this->workspaceLocation).exists()){
# Line 85 | Line 119 | MainWindow::MainWindow(QWidget *parent)
119      this->myBar->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Fixed);
120      this->myBar->setMinimumWidth(150);
121      this->myBar->hide(); //hide while not being used
122 +    ui->tbAbortConversion->hide(); //hide while not being used
123  
124 <    ui->statusBar->addPermanentWidget(myBar); //this adds automatically in right
125 <
91 <    this->myLogger = new Logger(); //start logger
124 >    ui->statusBar->addPermanentWidget(this->myBar); //this adds automatically in right
125 >    ui->statusBar->addPermanentWidget(ui->tbAbortConversion);
126  
127      //Initialize list pointers
128      this->listToProccess = new QStringList;
129  
96    //Create a thread for do the conversion in background
97    this->myConverter = new Converter(this->myLogger,this->listToProccess);
98
130      // User interface
131      ui->mainToolBar->addWidget(ui->tbAE); //add ae installer launch button
132      ui->mainToolBar->addWidget(ui->emptySpacerLabel); //trick, we can't add directly a space so we add an empty
# Line 107 | Line 138 | MainWindow::MainWindow(QWidget *parent)
138  
139      ui->mainToolBar->setLayoutDirection(Qt::RightToLeft);
140  
141 <    setConverterButtonsSize();
141 >    ui->pbConvert->setMinimumHeight(ui->pbConvert->sizeHint().height()*1.5); // This is OS indepented. It maintain size ratio over the Windows and Mac.
142  
143 < #ifdef Q_WS_MAC
143 >
144 > #ifdef Q_OS_MAC
145      // 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
146      ui->tbOni->setIcon(QIcon(":/new/icons/oni_icon_mac.png")); // Oni executable on mac have a different icon than windows
147      // Set mac platform the first one in the menu, and also make it checkable by default
# Line 117 | Line 149 | MainWindow::MainWindow(QWidget *parent)
149      ui->menuTarget_Platform->addAction(ui->actionWindows);
150      ui->actionWindows->setChecked(false);
151      ui->actionMac_Windows_demo->setChecked(true);
152 <    resize(800,600); // Mac OS pcs should be able to render this resolution without any problem. It's also better
153 <    // because the components on mac use more space
152 >    // resize(800,600); // Mac OS pcs should be able to render this resolution without any problem. It's also better
153 >    //// because the components on mac use more space
154   #endif
155  
156 <    connectSlots();
156 >    resize(this->startedWindowWidth,this->startedWindowHeight);
157 >
158 > #ifdef Q_OS_MAC
159 >    ui->pbConvert->setToolTip(ui->pbConvert->toolTip() + " (⌘ + Enter)");
160 > #else
161 >    ui->pbConvert->setToolTip(ui->pbConvert->toolTip() + " (Ctrl + Enter)");
162 > #endif
163  
164      //Commands Mapping
165      this->commandMap = QHash<QString, QString>();
166      mapCommands();
167  
168 <    updateItemsLoaded(ui->twSourcesGeneral);
168 >    updateItemsLoaded(ui->twSourcesXML);
169  
170 <    this->myLogger->writeString("Application started.");
170 >    loadRecentProjects();
171   }
172  
173   MainWindow::~MainWindow()
# Line 138 | Line 176 | MainWindow::~MainWindow()
176      this->myLogger->writeString("Application Exited.");
177   }
178  
179 +
180 + void MainWindow::showEvent(QShowEvent *e)
181 + {
182 +    #ifdef Q_OS_WIN
183 +    // QProgressBar only works after the windows was shown
184 +    // http://stackoverflow.com/questions/24840941/qwintaskbarprogress-wont-show (Kervala answer)
185 +
186 +    this->win7TaskBarButton = new QWinTaskbarButton();
187 +
188 +    this->win7TaskBarButton->setWindow(this->windowHandle());
189 +
190 +    this->win7TaskBarProgress = this->win7TaskBarButton->progress();
191 +
192 +    //Create a thread for do the conversion in background
193 +    this->myConverter = new Converter(UtilVago::getAppPath(), this->myLogger, this->listToProccess, this->win7TaskBarProgress);
194 +    #else
195 +    this->myConverter = new Converter(UtilVago::getAppPath(), this->myLogger, this->listToProccess);
196 +    #endif
197 +
198 +    connectSlots();
199 +
200 +    this->myLogger->writeString("Application started.");
201 +
202 +    e->accept();
203 + }
204 +
205 +
206   void MainWindow::on_actionExit_triggered()
207   {
208      close();
# Line 158 | Line 223 | void MainWindow::on_actionAE_Package_Cre
223  
224   void MainWindow::on_actionSound_Wizard_triggered()
225   {
226 <    SoundWizard myWizard (this->workspaceWizardsLocation, this->myLogger, &this->commandMap);
226 >    SoundWizard myWizard (UtilVago::getAppPath(), this->workspaceWizardsLocation, this->myLogger, &this->commandMap);
227      myWizard.exec();
228   }
229  
# Line 169 | Line 234 | void MainWindow::on_tbOni_clicked()
234      if(this->vagoSettings->value("OniWindow").toBool()){ // Run in a window?
235          arguments << "-noswitch";
236      }
237 < #ifdef Q_WS_WIN
237 > #ifdef Q_OS_WIN
238      else{
239          arguments << "-switch"; // only supported on windows. Was added by daodan dll.
240      }
# Line 196 | Line 261 | void MainWindow::on_tbOpenFolder_clicked
261      QDesktopServices::openUrl(QUrl("file:///"+this->outputFolder));
262   }
263  
264 + void MainWindow::on_tbAbortConversion_clicked()
265 + {
266 +    if(Util::showQuestionPopUp(this,"Are you sure you want to abort the current conversion?")){
267 +        emit terminateCurrProcess();
268 +    }
269 + }
270 +
271   void MainWindow::on_cbEnvMap_toggled(bool checked)
272   {
273      ui->leEnvMapTexture->setEnabled(checked);
# Line 211 | Line 283 | void MainWindow::on_cbWithAnimation_togg
283      ui->leAnimationName->setEnabled(checked);
284   }
285  
286 < void MainWindow::on_cbCamera_toggled(bool checked)
215 < {
216 <    if(checked){
217 <        ui->cbGeometry->setChecked(false);
218 <    }
219 < }
220 <
221 < void MainWindow::on_cbGeometry_toggled(bool checked)
286 > void MainWindow::on_cbSpecificFilesLevels_toggled(bool checked)
287   {
288 <    ui->leGeometryName->setEnabled(checked);
224 <    if(checked){
225 <        ui->cbCamera->setChecked(false);
226 <    }
288 >    ui->leSpecificFilesLevels->setEnabled(checked);
289   }
290  
291   void MainWindow::on_actionCheck_For_Updates_triggered()
# Line 257 | Line 319 | void MainWindow::checkVagoLastVersion(QN
319          }
320      }
321      else{
322 <        Util::showErrorPopUp("An error occurred checking last version:\n\n"+result->errorString());
322 >        UtilVago::showAndLogErrorPopUp(this->myLogger, "An error occurred checking last version:\n\n"+result->errorString());
323      }
324      result->deleteLater();
325   }
326  
327 < void MainWindow::on_pbAddSourceGeneral_clicked()
327 > void MainWindow::on_pbAddSourceXML_clicked()
328   {
329 <    if(QString::compare(ui->cbFromGeneral->currentText(),"ONI",Qt::CaseSensitive)==0 && QString::compare(ui->cbToGeneral->currentText(),"DAT",Qt::CaseSensitive)==0){ //CaseSensitive is faster)
268 <        addFilesSource(ui->twSourcesGeneral,Util::multipleDirDialog("Choose folders with ONIs..."));
269 <    }
270 <    else{
271 <        addFilesSource( ui->twSourcesGeneral,QFileDialog::getOpenFileNames(this,"Choose the files...","./" , "All Files (*.*)"));
272 <    }
329 >    addFilesSource( ui->twSourcesXML,QFileDialog::getOpenFileNames(this,"Choose the files...","./" , "All Files (*.*)"));
330   }
331  
332   void MainWindow::on_pbAddSourceTextures_clicked()
# Line 277 | Line 334 | void MainWindow::on_pbAddSourceTextures_
334      addFilesSource( ui->twSourcesTextures, QFileDialog::getOpenFileNames(this,"Choose the files...","./" , "All Files (*.*)"));
335   }
336  
337 < void MainWindow::on_pbAddSourceModels_clicked()
337 > void MainWindow::on_pbAddSourceObjects_clicked()
338   {
339 <    addFilesSource( ui->twSourcesModels,QFileDialog::getOpenFileNames(this,"Choose the files...","./" , "All Files (*.*)"));
339 >    addFilesSource( ui->twSourcesObjects,QFileDialog::getOpenFileNames(this,"Choose the files...","./" , "All Files (*.*)"));
340   }
341  
342 < void MainWindow::on_pbAddSourceAnimations_clicked()
342 > void MainWindow::on_pbAddSourceCharacters_clicked()
343   {
344 <    addFilesSource( ui->twSourcesAnimations,QFileDialog::getOpenFileNames(this,"Choose the files...","./" , "All Files (*.*)"));
344 >    addFilesSource( ui->twSourcesCharacters,QFileDialog::getOpenFileNames(this,"Choose the files...","./" , "All Files (*.*)"));
345   }
346  
347   void MainWindow::on_pbAddSourceLevels_clicked()
348   {
349 <    addFilesSource( ui->twSourcesLevels,QFileDialog::getOpenFileNames(this,"Choose the files...","./" , "All Files (*.*)"));
349 >    if(QString::compare(ui->cbFromLevels->currentText(),"ONI FILES",Qt::CaseSensitive)==0 && QString::compare(ui->cbToLevels->currentText(),"DAT",Qt::CaseSensitive)==0){ //CaseSensitive is faster)
350 >        addFilesSource(ui->twSourcesLevels,Util::multipleDirDialog("Choose folders with ONIs..."));
351 >    }
352 >    else{
353 >        addFilesSource(ui->twSourcesLevels,QFileDialog::getOpenFileNames(this,"Choose the files...","./" , "All Files (*.*)"));
354 >    }
355   }
356  
357   void MainWindow::on_pbAddSourceMisc_clicked()
# Line 321 | Line 383 | void MainWindow::addFilesSource(DropTabl
383      to = QString(fromTo).remove(0,fromTo.lastIndexOf("> ")+2); //+2 to start after "> "
384  
385      //Pre-processing (check if the files/folders received are valid), e.g. check for ONI->DAT if are only given folders and not files
386 <    if(QString::compare(from,"ONI",Qt::CaseSensitive)==0 && QString::compare(to,"DAT",Qt::CaseSensitive)==0){
386 >    if(from=="ONI FILES" && to=="DAT"){
387          //check if it's a folder
388          foreach(QString myFile, files){
389              if(!QDir(myFile).exists()){
# Line 373 | Line 435 | void MainWindow::addFilesSource(DropTabl
435      updateItemsLoaded(myTable);
436   }
437  
438 < QString MainWindow::fileParsingGeneral(QString myOutputFolder, QString from, QString to , QString file){
438 > QString MainWindow::fileParsingXML(QString tabTitle, QString myOutputFolder, QString from, QString to , QString file){
439  
440      QString command;
441  
442 <    if(QString::compare(from,"ONI",Qt::CaseSensitive)==0 && QString::compare(to,"DAT",Qt::CaseSensitive)==0){ //CaseSensitive is faster
443 <
382 <        QString datName;
383 <
384 <        if(ui->cbDatGeneral->isChecked()){
385 <            if(ui->leTargetDatGeneral->text().isEmpty()){
386 <                showErrStatusMessage("Checkbox '"+ui->cbDatGeneral->text()+"' is selected. The name cannot be empty.");
387 <                return "";
388 <            }
389 <            datName+=QString(myOutputFolder).insert(myOutputFolder.size()-1,ui->leTargetDatGeneral->text()); //set name inputted by user
390 <            if(!ui->leTargetDatGeneral->text().toUpper().endsWith(".DAT")){
391 <                datName.insert(datName.size()-1,".dat"); //append extension if necessary (-1 to maintain final quote)
392 <            }
393 <        }
394 <        else{
395 <            datName=QString(myOutputFolder).insert(myOutputFolder.size()-1,Util::cutName(file).remove("/")+".dat"); //if none iputted set the same name of input file
396 <        }
397 <
398 <        if(ui->actionWindows->isChecked()){ //is target plataform select windows?
399 <            return command=this->commandMap.value("general->"+from+"->"+to+"(PC)")+" "+ file + " "+datName;
400 <        }
401 <        else{
402 <            return command=this->commandMap.value("general->"+from+"->"+to+"(demoPCMAC)")+" "+ file + " "+datName;
403 <        }
442 >    if(from=="ONI" && to=="XML"){
443 >        return command=this->commandMap.value(tabTitle+"->"+from+"->"+to)+" "+myOutputFolder+" "+file;
444      }
445 <    else if(QString::compare(from,"ONI",Qt::CaseSensitive)==0 && QString::compare(to,"XML",Qt::CaseSensitive)==0 && ui->cbTRAMGeneral->isChecked()){
446 <        if(ui->leTRAMGeneral->text().isEmpty()){
407 <            showErrStatusMessage("Checkbox '"+ui->cbTRAMGeneral->text()+"' is selected. The source cannot be empty.");
408 <            return "";
409 <        }
410 <        return command=this->commandMap.value("general->"+from+"->"+to)+" "+myOutputFolder+" "+this->commandMap.value("general->"+ui->cbTRAMGeneral->text())+file + " "+ Util::normalizeAndQuote(ui->leTRAMGeneral->text());
411 <    }
412 <    else{
413 <        return command=this->commandMap.value("general->"+from+"->"+to)+" "+myOutputFolder+" "+file;
445 >    else if(from=="XML" && to=="ONI"){
446 >        return command=this->commandMap.value(tabTitle+"->"+from+"->"+to)+" "+myOutputFolder+" "+file;
447      }
448  
449 +    return "";
450 +
451   }
452  
453 < QString MainWindow::fileParsingTextures(QString myOutputFolder, QString from, QString to , QString file){
453 > QString MainWindow::fileParsingTextures(QString tabTitle, QString myOutputFolder, QString from, QString to , QString file){
454  
455 <    QString command=this->commandMap.value("textures->"+from+"->"+to)+" "+myOutputFolder;
455 >    QString command=this->commandMap.value(tabTitle+"->"+from+"->"+to)+" "+myOutputFolder;
456  
457      if(ui->gbTextures->isEnabled()){ //faster than compare strings (if is DAT/ONI)
458  
459          if(ui->cbMipMapsTextures->isChecked()){
460 <            command+=" "+this->commandMap.value("textures->"+ui->cbMipMapsTextures->text());
460 >            command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbMipMapsTextures->text());
461          }
462  
463          if(ui->cbNoUwrap->isChecked()){
464 <            command+=" "+this->commandMap.value("textures->"+ui->cbNoUwrap->text());
464 >            command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbNoUwrap->text());
465          }
466  
467          if(ui->cbNoVwrap->isChecked()){
468 <            command+=" "+this->commandMap.value("textures->"+ui->cbNoVwrap->text());
468 >            command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbNoVwrap->text());
469          }
470  
471          if(ui->cbLarge->isChecked()){
472 <            command+=" "+this->commandMap.value("textures->"+ui->cbLarge->text());
472 >            command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbLarge->text());
473          }
474  
475 <        if(ui->rbBGR32->isChecked()){
441 <            command+=" "+this->commandMap.value("textures->"+ui->rbBGR32->text());
442 <        }
443 <        else if(ui->rbBGRA32->isChecked()){
444 <            command+=" "+this->commandMap.value("textures->"+ui->rbBGRA32->text());
445 <        }
446 <        else if(ui->rbBGR555->isChecked()){
447 <            command+=" "+this->commandMap.value("textures->"+ui->rbBGR555->text());
448 <        }
449 <        else if(ui->rbBGRA5551->isChecked()){
450 <            command+=" "+this->commandMap.value("textures->"+ui->rbBGRA5551->text());
451 <        }
452 <        else if(ui->rbBGRA444->isChecked()){
453 <            command+=" "+this->commandMap.value("textures->"+ui->rbBGRA444->text());
454 <        }
455 <        else{ //dxt1 checked
456 <            command+=" "+this->commandMap.value("textures->"+ui->rbDxt1->text());
457 <        }
475 >        command+=" "+this->commandMap.value(tabTitle+"->"+getTextureRBCheckedTypeTexture()->text());
476  
477          if(ui->cbEnvMap->isChecked()){
478              if(ui->leEnvMapTexture->text().isEmpty()){
479                  showErrStatusMessage("Checkbox '"+ui->cbEnvMap->text()+"' is selected. The name texture name cannot be empty.");
480                  return "";
481              }
482 <            command+=" "+this->commandMap.value("textures->"+ui->cbEnvMap->text()) + ui->leEnvMapTexture->text().remove(".oni",Qt::CaseInsensitive);
482 >            command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbEnvMap->text()) + ui->leEnvMapTexture->text().remove(".oni",Qt::CaseInsensitive);
483          }
484      }
485  
486      return command+=" "+file; //add source
487   }
488  
489 < QString MainWindow::fileParsingModels(QString myOutputFolder, QString from, QString to , QString file){
489 > QString MainWindow::fileParsingCharacters(QString tabTitle, QString myOutputFolder, QString from, QString to , QString file){
490  
491 <    QString command=this->commandMap.value("models->"+from+"->"+to)+" "+myOutputFolder;
491 >    QString command=this->commandMap.value(tabTitle+"->"+from+"->"+to)+" "+myOutputFolder + " " + file ;
492  
475    //TODO: This can be optimized. When some are not enable others are.
476    if(ui->cbTexture->isChecked()){
477        if(ui->leTextureName->text().isEmpty()){
478            showErrStatusMessage("Checkbox '"+ui->cbTexture->text()+"' is selected. The name cannot be empty.");
479            return "";
480        }
481        command+=" "+this->commandMap.value("models->"+ui->cbTexture->text()) + ui->leTextureName->text().remove(".oni",Qt::CaseInsensitive);
482    }
493  
494      if(ui->cbCellShading->isChecked()){
495 <        command+=" "+this->commandMap.value("models->"+ui->cbCellShading->text());
495 >        command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbCellShading->text());
496      }
497  
498      if(ui->cbNormals->isChecked()){
499 <        command+=" "+this->commandMap.value("models->"+ui->cbNormals->text());
499 >        command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbNormals->text());
500      }
501  
502 <    if(ui->cbWithAnimation->isEnabled()){
503 <        if(ui->cbWithAnimation->isChecked()){
504 <            command+=" "+this->commandMap.value("models->"+ui->cbWithAnimation->text())+ui->leAnimationName->text().remove(".oni",Qt::CaseInsensitive);
505 <        }
496 <        else{
497 <            command+=" "+this->commandMap.value("models->No Animation");
502 >    if(ui->cbWithTRBS_ONCC->isChecked()){
503 >        if(ui->leTRBS_ONCC->text().isEmpty()){
504 >            showErrStatusMessage("Checkbox '"+ui->cbWithTRBS_ONCC->text()+"' is selected. The name cannot be empty.");
505 >            return "";
506          }
499    }
507  
508 +        command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbWithTRBS_ONCC->text())+Util::normalizeAndQuote(ui->leTRBS_ONCC->text());
509 +    }
510  
511 <    return command+=" "+file; //add source
511 >    return command;
512   }
513  
505 QString MainWindow::fileParsingAnimations(QString myOutputFolder, QString from, QString to , QString file){
514  
515 <    QString command=this->commandMap.value("animations->"+from+"->"+to)+" "+myOutputFolder + " " + file ;
515 > QString MainWindow::fileParsingObjects(QString tabTitle, QString myOutputFolder, QString from, QString to , QString file){
516  
517 <    if(ui->cbCamera->isChecked()){
518 <        command+=" "+this->commandMap.value("animations->"+ui->cbCamera->text());
517 >    QString command=this->commandMap.value(tabTitle+"->"+from+"->"+to)+" "+myOutputFolder;
518 >
519 >    //TODO: This can be optimized. When some are not enable others are.
520 >    if(ui->cbTexture->isChecked()){
521 >        if(ui->leTextureName->text().isEmpty()){
522 >            showErrStatusMessage("Checkbox '"+ui->cbTexture->text()+"' is selected. The file source cannot be empty.");
523 >            return "";
524 >        }
525 >        command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbTexture->text()) + ui->leTextureName->text();
526      }
527 <    else if(ui->cbGeometry->isChecked()){
528 <        if(ui->leGeometryName->text().isEmpty()){
529 <            showErrStatusMessage("Checkbox '"+ui->cbGeometry->text()+"' is selected. The geometry file path cannot be empty.");
527 >    else if(ui->cbWithAnimation->isChecked()){
528 >        if(ui->leAnimationName->text().isEmpty()){
529 >            showErrStatusMessage("Checkbox '"+ui->cbWithAnimation->text()+"' is selected. The file source cannot be empty.");
530              return "";
531          }
532 <        command+=" "+this->commandMap.value("animations->"+ui->cbGeometry->text()) + (ui->leGeometryName->text().startsWith('"')?ui->leGeometryName->text():Util::insertQuotes(ui->leGeometryName->text()));
532 >        command+=" "+Util::normalizeAndQuote(ui->leAnimationName->text()) + " " + this->commandMap.value(tabTitle+"->"+ui->cbWithAnimation->text()) + file;
533 >        return command;
534      }
535  
536 <    return command;
536 >    if(from=="OBAN ONI (cam)"){
537 >        command+=" -geom:camera";
538 >    }
539 >
540 >    return command+=" "+file; //add source
541   }
542  
543 < QString MainWindow::fileParsingLevels(QString myOutputFolder, QString from, QString to , QString file){
543 > QString MainWindow::fileParsingLevels(QString tabTitle, QString myOutputFolder, QString from, QString to , QString file){
544  
545      QString datName, command;
546  
547 <    command=this->commandMap.value("levels->"+from+"->"+to)+" "+myOutputFolder+" "+file;
547 >    if(!(from=="ONI FILES" && to=="DAT")){ // to all except this one
548 >
549 >        command=this->commandMap.value(tabTitle+"->"+from+"->"+to);
550 >
551 >        if(ui->cbSpecificFilesLevels->isChecked()){
552 >
553 >            if(ui->leSpecificFilesLevels->text().isEmpty()){
554 >                showErrStatusMessage("Checkbox '"+ui->cbSpecificFilesLevels->text()+"' is selected. The files pattern cannot be empty.");
555 >                return "";
556 >            }
557 >
558 >            command+=":"+ui->leSpecificFilesLevels->text();
559 >        }
560  
561 <    if(from=="MASTER XML" && to=="DAT"){
562 <        command+=GlobalVars::OniSplitProcSeparator; //insert mark so we know this action will take 2 commands
561 >        if(from=="DAT" && to=="ONI FILES"){ // extract files to a subdir with the files name ex: level0_Final
562 >            command += " " + myOutputFolder.insert(myOutputFolder.size()-2,QString(Util::cutName(file)).replace(".dat","")) + " " + file;
563 >        }
564 >        else{
565 >            command+=" "+myOutputFolder+" "+file;
566 >        }
567  
568 +    }
569 +
570 +    if((from=="ONI FILES" || from=="MASTER XML") && to=="DAT"){ // almost the same command for both
571          QString datName;
572 +
573 +        if(from=="MASTER XML"){
574 +            command+=GlobalVars::OniSplitProcSeparator; //insert mark so we know this action will take 2 commands
575 +        }
576 +
577          if(ui->cbDatLevels->isChecked()){
578              if(ui->leTargetDatLevels->text().isEmpty()){
579                  showErrStatusMessage("Checkbox '"+ui->cbDatLevels->text()+"' is selected. The name cannot be empty.");
# Line 541 | Line 585 | QString MainWindow::fileParsingLevels(QS
585              }
586          }
587          else{
588 <            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
588 >            if(from=="ONI FILES"){
589 >                datName=QString(myOutputFolder).insert(myOutputFolder.size()-1,Util::cutName(file).remove("/")+".dat"); //if none iputted set the same name of input file
590 >            }
591 >            else if(from=="MASTER XML"){
592 >                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
593 >            }
594          }
595 <
596 <        if(ui->actionWindows->isChecked()){ //is target plataform select windows?
597 <            command+=this->commandMap.value("general->ONI->"+to+"(PC)")+" "+myOutputFolder+" "+datName; //add second command
595 >        if(from=="ONI FILES"){
596 >            if(ui->actionWindows->isChecked()){ //is target plataform select windows?
597 >                return command=this->commandMap.value(tabTitle+"->"+from+"->"+to+"(PC)")+" "+ file + " "+datName;
598 >            }
599 >            else{
600 >                return command=this->commandMap.value(tabTitle+"->"+from+"->"+to+"(demoPCMAC)")+" "+ file + " "+datName;
601 >            }
602          }
603 <        else{
604 <            command+=this->commandMap.value("general->ONI->"+to+"(demoPCMAC)")+" "+myOutputFolder+" "+datName; //add second command
603 >        else if(from=="MASTER XML"){
604 >            if(ui->actionWindows->isChecked()){ //is target plataform select windows?
605 >                command+=this->commandMap.value(tabTitle+"->ONI FILES->"+to+"(PC)")+" "+myOutputFolder+" "+datName; //add second command
606 >            }
607 >            else{
608 >                command+=this->commandMap.value(tabTitle+"->ONI FILES->"+to+"(demoPCMAC)")+" "+myOutputFolder+" "+datName; //add second command
609 >            }
610          }
611      }
612  
# Line 574 | Line 632 | QString MainWindow::fileParsingLevels(QS
632  
633          //parse all files (separated by spaces)
634          while(true){
635 <            nextIndex=additionalFiles.indexOf(" ",currentIndex+1);
635 >            nextIndex=additionalFiles.indexOf(";",currentIndex+1);
636  
637              command += " "+Util::normalizeAndQuote(additionalFiles.mid(currentIndex,(nextIndex-currentIndex)));
638  
# Line 586 | Line 644 | QString MainWindow::fileParsingLevels(QS
644      }
645  
646      if(ui->cbGridsLevels->isChecked()){
647 <        command+=GlobalVars::OniSplitProcSeparator+this->commandMap.value("levels->"+ui->cbGridsLevels->text())+" "+Util::normalizeAndQuote(ui->leBnvLevels->text())+" "+file+" -out:"+myOutputFolder;
647 >        command+=GlobalVars::OniSplitProcSeparator+this->commandMap.value(tabTitle+"->"+ui->cbGridsLevels->text())+" "+Util::normalizeAndQuote(ui->leBnvLevels->text())+" "+file+" -out:"+myOutputFolder;
648      }
649  
650      return command;
# Line 596 | Line 654 | QString MainWindow::fileParsingMisc(QStr
654      return this->commandMap.value("misc->"+from+"->"+to)+" "+myOutputFolder+" "+file;
655   }
656  
657 < void MainWindow::addRowTable(DropTableWidget *myTable, QString fileName, QString fromTo, QString command){
657 > void MainWindow::addRowTable(DropTableWidget *myTable, QString fileName, QString fromTo, QString command, bool isToDisabled){
658      //Get actual number rows
659      int twSize=myTable->rowCount();
660  
# Line 608 | Line 666 | void MainWindow::addRowTable(DropTableWi
666      QTableWidgetItem *newConversion = new QTableWidgetItem(fromTo);
667      QTableWidgetItem *newCommand = new QTableWidgetItem(command);
668  
669 +    if(isToDisabled){
670 +        myTable->setDisableStyleWidgetItem(newFile);
671 +        myTable->setDisableStyleWidgetItem(newConversion);
672 +        myTable->setDisableStyleWidgetItem(newCommand);
673 +    }
674 +
675      myTable->setItem(twSize,0,newFile);
676      myTable->setItem(twSize,1,newConversion);
677      myTable->setItem(twSize,2,newCommand);
# Line 615 | Line 679 | void MainWindow::addRowTable(DropTableWi
679      myTable->updateTableToolTips(twSize); //Update tool tips
680   }
681  
682 < void MainWindow::on_pbConvertGeneral_clicked()
619 < {
620 <    startConversion(ui->twSourcesGeneral);
621 < }
622 <
623 < void MainWindow::on_pbConvertTextures_clicked()
624 < {
625 <    startConversion(ui->twSourcesTextures);
626 < }
627 <
628 < void MainWindow::on_pbConvertModels_clicked()
629 < {
630 <    startConversion(ui->twSourcesModels);
631 < }
632 <
633 < void MainWindow::on_pbConvertAnimations_clicked()
634 < {
635 <    startConversion(ui->twSourcesAnimations);
636 < }
637 <
638 < void MainWindow::on_pbConvertLevels_clicked()
682 > void MainWindow::on_pbConvert_clicked()
683   {
684 <    startConversion(ui->twSourcesLevels);
684 >    startConversion();
685   }
686  
687 < void MainWindow::on_pbConvertMisc_clicked()
644 < {
645 <    startConversion(ui->twSourcesMisc);
646 < }
687 > void MainWindow::startConversion(){
688  
689 < void MainWindow::startConversion(DropTableWidget *myTable){
689 >    DropTableWidget* currTable = getCurrentTableWidget();
690  
691      bool ready=false;
692 <    for(int i=0; i<myTable->rowCount(); i++){ //There are items to process?
693 <        if(myTable->item(i,2)->background()!=myTable->disabledBackStyle){
692 >    for(int i=0; i<currTable->rowCount(); i++){ //There are items to process?
693 >        if(currTable->item(i,2)->background()!=currTable->disabledBackStyle){
694              ready=true;
695              break;
696          }
# Line 660 | Line 701 | void MainWindow::startConversion(DropTab
701          return;
702      }
703  
704 <    if(myBar->isVisible()){
704 >    if(this->myBar->isVisible()){
705          Util::showErrorPopUp("Another conversion is progress. Please wait until it finishes.");
706          return;
707      }
708  
709 <    for(int i=0; i<myTable->rowCount(); i++){
709 >    for(int i=0; i<currTable->rowCount(); i++){
710          //Only process enabled items
711 <        if(myTable->item(i,2)->background()!=myTable->disabledBackStyle){
712 <            this->listToProccess->append(myTable->item(i,2)->text());
711 >        if(currTable->item(i,2)->background()!=currTable->disabledBackStyle){
712 >            this->listToProccess->append(currTable->item(i,2)->text());
713          }
714      }
715  
# Line 679 | Line 720 | void MainWindow::TsetupProgressBar(int m
720      this->myBar->setValue(0);
721      this->myBar->show();
722      this->myBar->setMaximum(max);
723 +    ui->tbAbortConversion->show();
724   }
725  
726   void  MainWindow::TupdateProgressBar(){
# Line 688 | Line 730 | void  MainWindow::TupdateProgressBar(){
730   void MainWindow::TresultConversion(QString result, int numErrors){
731      QApplication::alert(this); //Show a notification if window is not active
732      this->myBar->hide();
733 +    ui->tbAbortConversion->hide();
734  
735      if(numErrors!=0){
736          QString sNumErrors=QString::number(numErrors);
737          if(numErrors>1){
738 <            Util::showErrorLogPopUp(result+"\n This is the last of "+sNumErrors+" Errors.");
738 >            UtilVago::showErrorPopUpLogButton(result+"\n This is the last of "+sNumErrors+" Errors.");
739              showErrStatusMessage("Something gone wrong. Check log file ("+sNumErrors+" Errors).");
740          }
741          else{
742 <            Util::showErrorLogPopUp(result);
742 >            UtilVago::showErrorPopUpLogButton(result);
743              showErrStatusMessage("Something gone wrong. Check log file.");
744          }
745  
# Line 706 | Line 749 | void MainWindow::TresultConversion(QStri
749      }
750   }
751  
752 + void MainWindow::TconversionAborted(){
753 +    this->myBar->hide();
754 +    ui->tbAbortConversion->hide();
755 +
756 +    showErrStatusMessage("Conversion was aborted.");
757 + }
758 +
759   void MainWindow::showErrStatusMessage(QString message){
760  
761      QPalette myPalete = QPalette();
# Line 725 | Line 775 | void MainWindow::showSuccessStatusMessag
775   }
776  
777   void MainWindow::mapCommands(){
778 <    ////////////////////////////////////////////////////////////////////////General Commands
779 <    this->commandMap.insert("general->DAT->ONI","-export");
780 <    //this->commandMap.insert("general->ONI->DAT","-import"); //Not used.
731 <    this->commandMap.insert("general->ONI->DAT(PC)","-import:nosep");
732 <    this->commandMap.insert("general->ONI->DAT(demoPCMAC)","-import:sep");
733 <    this->commandMap.insert("general->ONI->XML","-extract:xml");
734 <    this->commandMap.insert("general->XML->ONI","-create");
778 >    ////////////////////////////////////////////////////////////////////////XML Commands
779 >    this->commandMap.insert("xml->ONI->XML","-extract:xml");
780 >    this->commandMap.insert("xml->XML->ONI","-create");
781      //######################General Options
782 <    this->commandMap.insert("general->"+ui->cbTRAMGeneral->text(),"-anim-body:");
782 >
783      //Possible Combinations
784 <    this->commandMap.insertMulti("general->DAT","ONI");
785 <    this->commandMap.insertMulti("general->ONI","DAT");
740 <    this->commandMap.insertMulti("general->ONI","XML");
741 <    this->commandMap.insertMulti("general->XML","ONI");
784 >    this->commandMap.insertMulti("xml->ONI","XML");
785 >    this->commandMap.insertMulti("xml->XML","ONI");
786  
787      ////////////////////////////////////////////////////////////////////////Textures Commands
788 <    this->commandMap.insert("textures->DAT / ONI->DDS","-extract:dds");
789 <    this->commandMap.insert("textures->DAT / ONI->TGA","-extract:tga");
790 <    this->commandMap.insert("textures->DAT / ONI->PNG","-extract:png");
791 <    this->commandMap.insert("textures->DAT / ONI->JPG","-extract:jpg");
792 <    this->commandMap.insert("textures->DDS / TGA / PNG / JPG->ONI","-create:txmp");
788 >    this->commandMap.insert("textures->DAT / TXMP ONI->DDS","-extract:dds");
789 >    this->commandMap.insert("textures->DAT / TXMP ONI->TGA","-extract:tga");
790 >    this->commandMap.insert("textures->DAT / TXMP ONI->PNG","-extract:png");
791 >    this->commandMap.insert("textures->DAT / TXMP ONI->JPG","-extract:jpg");
792 >    this->commandMap.insert("textures->TGA / DDS / PNG / JPG->TXMP ONI","-create:txmp");
793      //######################Textures Options
794      this->commandMap.insert("textures->"+ui->rbBGR32->text(),"-format:bgr32");
795      this->commandMap.insert("textures->"+ui->rbBGRA32->text(),"-format:bgra32");
# Line 759 | Line 803 | void MainWindow::mapCommands(){
803      this->commandMap.insert("textures->"+ui->cbLarge->text(),"-large");
804      this->commandMap.insert("textures->"+ui->cbEnvMap->text(),"-envmap:");
805      //Possible Combinations
806 <    this->commandMap.insertMulti("textures->DAT / ONI","DDS");
807 <    this->commandMap.insertMulti("textures->DAT / ONI","TGA");
808 <    this->commandMap.insertMulti("textures->DAT / ONI","PNG");
809 <    this->commandMap.insertMulti("textures->DAT / ONI","JPG");
810 <    this->commandMap.insertMulti("textures->DDS / TGA / PNG / JPG","ONI");
811 <
812 <    ////////////////////////////////////////////////////////////////////////Models Commands
813 <    this->commandMap.insert("models->ONI->OBJ","-extract:obj");
814 <    this->commandMap.insert("models->ONI->DAE","-extract:dae -search "+Util::insertQuotes(this->AeLocation+"/GameDataFolder/level0_Final"));
815 <    this->commandMap.insert("models->OBJ->ONI","-create:m3gm");
816 <    this->commandMap.insert("models->DAE->ONI","-create:trbs");
817 <    //######################Models Options
818 <    this->commandMap.insert("models->"+ui->cbCellShading->text(),"-cel");
819 <    this->commandMap.insert("models->"+ui->cbNormals->text(),"-normals");
820 <    this->commandMap.insert("models->"+ui->cbTexture->text(),"-tex:");
821 <    this->commandMap.insert("models->"+ui->cbWithAnimation->text(),"-anim:");
822 <    this->commandMap.insert("models->No Animation","-noanim"); //No label with this name so can't be dynamic
806 >    this->commandMap.insertMulti("textures->DAT / TXMP ONI","TGA");
807 >    this->commandMap.insertMulti("textures->DAT / TXMP ONI","DDS");
808 >    this->commandMap.insertMulti("textures->DAT / TXMP ONI","PNG");
809 >    this->commandMap.insertMulti("textures->DAT / TXMP ONI","JPG");
810 >    this->commandMap.insertMulti("textures->TGA / DDS / PNG / JPG","TXMP ONI");
811 >
812 >    ////////////////////////////////////////////////////////////////////////Characters Commands
813 >    this->commandMap.insert("characters->TRAM ONI->XML / XML & DAE","-extract:xml");
814 >    this->commandMap.insert("characters->TRBS / ONCC ONI->DAE","-extract:dae");
815 >    this->commandMap.insert("characters->TRBS XML->TRBS ONI","-create");
816 >    this->commandMap.insert("characters->TRBS DAE->TRBS ONI","-create:trbs");
817 >    this->commandMap.insert("characters->FILM DAT->XML","film2xml");
818 >
819 >    //######################Characters Options
820 >    this->commandMap.insert("characters->"+ui->cbWithTRBS_ONCC->text(),"-anim-body:");
821 >    this->commandMap.insert("characters->"+ui->cbCellShading->text(),"-cel");
822 >    this->commandMap.insert("characters->"+ui->cbNormals->text(),"-normals");
823      //Possible Combinations
824 <    this->commandMap.insertMulti("models->ONI","OBJ");
825 <    this->commandMap.insertMulti("models->ONI","DAE");
826 <    this->commandMap.insertMulti("models->OBJ","ONI");
827 <    this->commandMap.insertMulti("models->DAE","ONI");
828 <
829 <    ////////////////////////////////////////////////////////////////////////Animations Commands
830 <    this->commandMap.insert("animations->ONI->DAE","-extract:dae");
831 <    this->commandMap.insert("animations->FILM DAT->XML","film2xml");
832 <    //######################Animations Options
833 <    this->commandMap.insert("animations->"+ui->cbCamera->text(),"-geom:camera");
834 <    this->commandMap.insert("animations->"+ui->cbGeometry->text(),"-geom:");
824 >    this->commandMap.insertMulti("characters->TRAM ONI","XML / XML & DAE");
825 >    this->commandMap.insertMulti("characters->TRBS / ONCC ONI","DAE");
826 >    this->commandMap.insertMulti("characters->DAE","TRBS ONI");
827 >    this->commandMap.insertMulti("characters->TRBS DAE","TRBS ONI");
828 >    this->commandMap.insertMulti("characters->TRBS XML","TRBS ONI");
829 >    this->commandMap.insertMulti("characters->FILM DAT","XML");
830 >
831 >    ////////////////////////////////////////////////////////////////////////Objects Commands
832 >    this->commandMap.insert("objects->M3GM ONI->OBJ","-extract:obj");
833 >    this->commandMap.insert("objects->M3GM ONI->DAE","-extract:dae");
834 >    this->commandMap.insert("objects->ONWC ONI->OBJ","-extract:obj");
835 >    this->commandMap.insert("objects->ONWC ONI->DAE","-extract:dae");
836 >    this->commandMap.insert("objects->OBAN ONI (cam)->DAE","-extract:dae");
837 >    this->commandMap.insert("objects->OBJ->M3GM ONI","-create:m3gm");
838 >    //######################Characters Options
839 >    this->commandMap.insert("objects->"+ui->cbTexture->text(),"-tex:");
840 >    this->commandMap.insert("objects->"+ui->cbWithAnimation->text(),"-geom:");
841      //Possible Combinations
842 <    this->commandMap.insertMulti("animations->ONI","DAE");
843 <    this->commandMap.insertMulti("animations->DAE","ONI");
844 <    this->commandMap.insertMulti("animations->FILM DAT","XML");
842 >    this->commandMap.insertMulti("objects->M3GM ONI","OBJ");
843 >    this->commandMap.insertMulti("objects->M3GM ONI","DAE");
844 >    this->commandMap.insertMulti("objects->ONWC ONI","OBJ");
845 >    this->commandMap.insertMulti("objects->ONWC ONI","DAE");
846 >    this->commandMap.insertMulti("objects->OBAN ONI (cam)","DAE");
847 >    this->commandMap.insertMulti("objects->OBJ","M3GM ONI");
848 >
849  
850      ////////////////////////////////////////////////////////////////////////Levels Commands
851 <    this->commandMap.insert("levels->ONI->DAE","-extract:dae -search "+Util::insertQuotes(this->AeLocation+"/GameDataFolder/level0_Final"));
852 <    this->commandMap.insert("levels->DAE->ONI","-create:akev");
851 >    this->commandMap.insert("levels->DAT->ONI FILES","-export");
852 >    //this->commandMap.insert("levels->ONI FILES->DAT","-import"); //Not used.
853 >    this->commandMap.insert("levels->ONI FILES->DAT(PC)","-import:nosep");
854 >    this->commandMap.insert("levels->ONI FILES->DAT(demoPCMAC)","-import:sep");
855 >    this->commandMap.insert("levels->AKEV ONI->DAE","-extract:dae");
856 >    this->commandMap.insert("levels->DAE->AKEV ONI","-create:akev");
857      this->commandMap.insert("levels->MASTER XML->DAT","-create:level");
858      this->commandMap.insert("levels->MASTER XML->ONI FILES","-create:level");
859      //######################Levels Options
860      this->commandMap.insert("levels->"+ui->cbGridsLevels->text(),"-grid:create");
861      //Possible Combinations
862 <    this->commandMap.insertMulti("levels->ONI","DAE");
863 <    this->commandMap.insertMulti("levels->DAE","ONI");
862 >    this->commandMap.insertMulti("levels->DAT","ONI FILES");
863 >    this->commandMap.insertMulti("levels->ONI FILES","DAT");
864 >    this->commandMap.insertMulti("levels->AKEV ONI","DAE");
865 >    this->commandMap.insertMulti("levels->DAE","AKEV ONI");
866      this->commandMap.insertMulti("levels->MASTER XML","DAT");
867      this->commandMap.insertMulti("levels->MASTER XML","ONI FILES");
868  
869      ////////////////////////////////////////////////////////////////////////Misc Commands
870 <    this->commandMap.insert("misc->DAT / ONI->WAV","-extract:wav");
871 <    this->commandMap.insert("misc->DAT / ONI->AIF","-extract:aif");
872 <    this->commandMap.insert("misc->DAT / ONI->TXT","-extract:txt");
873 <    this->commandMap.insert("misc->WAV / AIF->ONI","-create");
874 <    this->commandMap.insert("misc->TXT->ONI","-create:subt");
870 >    this->commandMap.insert("misc->DAT / SNDD ONI->WAV","-extract:wav");
871 >    this->commandMap.insert("misc->DAT / SNDD ONI->AIF","-extract:aif");
872 >    this->commandMap.insert("misc->DAT / SUBT ONI->TXT","-extract:txt");
873 >    this->commandMap.insert("misc->WAV / AIF->SNDD ONI","-create");
874 >    this->commandMap.insert("misc->TXT->SUBT ONI","-create:subt");
875      //Possible Combinations
876 <    this->commandMap.insertMulti("misc->DAT / ONI","WAV");
877 <    this->commandMap.insertMulti("misc->DAT / ONI","AIF");
878 <    this->commandMap.insertMulti("misc->DAT / ONI","TXT");
879 <    this->commandMap.insertMulti("misc->WAV / AIF","ONI");
880 <    this->commandMap.insertMulti("misc->TXT","ONI");
876 >    this->commandMap.insertMulti("misc->DAT / SNDD ONI","WAV");
877 >    this->commandMap.insertMulti("misc->DAT / SNDD ONI","AIF");
878 >    this->commandMap.insertMulti("misc->DAT / SUBT ONI","TXT");
879 >    this->commandMap.insertMulti("misc->WAV / AIF","SNDD ONI");
880 >    this->commandMap.insertMulti("misc->TXT","SUBT ONI");
881  
882   }
883  
884 < void MainWindow::on_cbFromGeneral_currentIndexChanged(const QString &arg1)
884 > void MainWindow::on_cbFromXML_currentIndexChanged(const QString &arg1)
885   {
886 <    updateComboBox(arg1, ui->cbToGeneral, "general");
886 >    updateComboBox(arg1, ui->cbToXML);
887   }
888  
889 +
890   void MainWindow::on_cbFromTextures_currentIndexChanged(const QString &arg1)
891   {
892 <    //Options are only used for DAT/ONI -> Image
832 <    if(QString::compare(arg1,"DAT / ONI",Qt::CaseSensitive)==0){ //case sensitive is faster
833 <        ui->gbTextures->setEnabled(false);
834 <    }
835 <    else{
836 <        ui->gbTextures->setEnabled(true);
837 <    }
838 <
839 <    updateComboBox(arg1, ui->cbToTextures, "textures");
892 >    updateComboBox(arg1, ui->cbToTextures);
893   }
894  
895 < void MainWindow::on_cbFromModels_currentIndexChanged(const QString &arg1)
895 > void MainWindow::on_cbFromObjects_currentIndexChanged(const QString &arg1)
896   {
897 <
845 <    ui->cbCellShading->setEnabled(false);
846 <    ui->cbCellShading->setChecked(false);
847 <    ui->cbNormals->setEnabled(false);
848 <    ui->cbNormals->setChecked(false);
849 <    ui->cbTexture->setEnabled(false);
850 <    ui->cbTexture->setChecked(false);
851 <    ui->cbWithAnimation->setEnabled(false);
852 <    ui->cbWithAnimation->setChecked(false);
853 <
854 <    if(QString::compare(arg1,"OBJ",Qt::CaseSensitive)==0){ //case sensitive is faster
855 <        ui->cbTexture->setEnabled(true);
856 <    }
857 <    else if(QString::compare(arg1,"DAE",Qt::CaseSensitive)==0){
858 <        ui->cbCellShading->setEnabled(true);
859 <        ui->cbNormals->setEnabled(true);
860 <    }
861 <
862 <    updateComboBox(arg1, ui->cbToModels, "models");
897 >    updateComboBox(arg1, ui->cbToObjects);
898   }
899  
900 < void MainWindow::on_cbFromAnimations_currentIndexChanged(const QString &arg1)
900 > void MainWindow::on_cbFromCharacters_currentIndexChanged(const QString &arg1)
901   {
902 <    ui->cbCamera->setEnabled(false);
868 <    ui->cbCamera->setChecked(false);
869 <    ui->cbGeometry->setEnabled(false);
870 <    ui->cbGeometry->setChecked(false);
871 <
872 <    if(QString::compare(arg1,"ONI",Qt::CaseSensitive)==0){ //case sensitive is faster
873 <        ui->cbCamera->setEnabled(true);
874 <        ui->cbGeometry->setEnabled(true);
875 <    }
876 <
877 <    updateComboBox(arg1, ui->cbToAnimations, "animations");
902 >    updateComboBox(arg1, ui->cbToCharacters);
903   }
904  
905   void MainWindow::on_cbFromLevels_currentIndexChanged(const QString &arg1)
906   {
907 <    updateComboBox(arg1, ui->cbToLevels, "levels");
907 >    updateComboBox(arg1, ui->cbToLevels);
908   }
909  
910   void MainWindow::on_cbFromMisc_currentIndexChanged(const QString &arg1)
911   {
912 <    updateComboBox(arg1, ui->cbToMisc, "misc");
912 >    updateComboBox(arg1, ui->cbToMisc);
913   }
914  
915 < void MainWindow::updateComboBox(const QString &arg1, QComboBox *comboBox, const QString &identifier){
915 > void MainWindow::updateComboBox(const QString &arg1, QComboBox *comboBox){
916 >
917 >    QString identifier;
918 >
919 >    if(comboBox == ui->cbToXML){
920 >        identifier = ui->tabWidget->tabText(XMLTabIndex);
921 >    }
922 >    else if(comboBox == ui->cbToTextures){
923 >        identifier = ui->tabWidget->tabText(TexturesTabIndex);
924 >
925 >        //Options are only used for DAT/ONI -> Image
926 >        if(QString::compare(arg1,"DAT / ONI",Qt::CaseSensitive)==0){ //case sensitive is faster
927 >            ui->gbTextures->setEnabled(false);
928 >        }
929 >        else{
930 >            ui->gbTextures->setEnabled(true);
931 >        }
932 >    }
933 >    else if(comboBox == ui->cbToCharacters){
934 >        identifier = ui->tabWidget->tabText(CharactersTabIndex);
935 >
936 >        ui->cbWithTRBS_ONCC->setEnabled(false);
937 >        ui->cbWithTRBS_ONCC->setChecked(false);
938 >        ui->cbCellShading->setEnabled(false);
939 >        ui->cbCellShading->setChecked(false);
940 >        ui->cbNormals->setEnabled(false);
941 >        ui->cbNormals->setChecked(false);
942 >
943 >        if(QString::compare(arg1,"TRAM ONI",Qt::CaseSensitive)==0){ //case sensitive is faster
944 >            ui->cbWithTRBS_ONCC->setEnabled(true);
945 >        }
946 >        else if(QString::compare(arg1,"TRBS DAE",Qt::CaseSensitive)==0){
947 >            ui->cbNormals->setEnabled(true);
948 >            ui->cbCellShading->setEnabled(true);
949 >        }
950 >
951 >    }
952 >    else if(comboBox == ui->cbToObjects){
953 >        identifier = ui->tabWidget->tabText(ObjectsTabIndex);
954 >
955 >        ui->cbTexture->setEnabled(false);
956 >        ui->cbTexture->setChecked(false);
957 >        ui->cbWithAnimation->setEnabled(false);
958 >        ui->cbWithAnimation->setChecked(false);
959 >
960 >        if(QString::compare(arg1,"M3GM ONI",Qt::CaseSensitive)==0){ //case sensitive is faster
961 >            ui->cbWithAnimation->setEnabled(true);
962 >        }
963 >        else if(QString::compare(arg1,"OBJ",Qt::CaseSensitive)==0){
964 >            ui->cbTexture->setEnabled(true);
965 >        }
966 >    }
967 >    else if(comboBox == ui->cbToLevels){
968 >        identifier = ui->tabWidget->tabText(LevelsTabIndex);
969 >
970 >        ui->cbSpecificFilesLevels->setEnabled(false);
971 >        ui->cbSpecificFilesLevels->setChecked(false);
972 >        ui->cbDatLevels->setEnabled(false);
973 >        ui->cbDatLevels->setChecked(false);
974 >        ui->cbBnvLevels->setEnabled(false);
975 >        ui->cbBnvLevels->setChecked(false);
976 >        ui->cbAdditionalSourcesLevels->setEnabled(false);
977 >        ui->cbAdditionalSourcesLevels->setChecked(false);
978 >        ui->cbGridsLevels->setEnabled(false);
979 >        ui->cbGridsLevels->setChecked(false);
980 >
981 >        if(arg1=="DAT"){ //case sensitive is faster
982 >            ui->cbSpecificFilesLevels->setEnabled(true);
983 >        }
984 >        else if(arg1=="ONI FILES"){ //case sensitive is faster
985 >            ui->cbDatLevels->setEnabled(true);
986 >        }
987 >        else if(arg1=="DAE"){
988 >            ui->cbBnvLevels->setEnabled(true);
989 >            ui->cbAdditionalSourcesLevels->setEnabled(true);
990 >        }
991 >    }
992 >    else{ // Misc
993 >        identifier = ui->tabWidget->tabText(MiscTabIndex);
994 >    }
995 >
996 >    identifier = identifier.toLower(); // get current tab title text (lower case)
997 >
998      comboBox->clear();
999  
1000      QStringList toUpdate=QStringList();
# Line 914 | Line 1021 | void MainWindow::on_actionMac_Windows_de
1021      ui->actionWindows->setChecked(false);
1022   }
1023  
1024 < void MainWindow::on_pbRemoveSourceGeneral_clicked()
1024 > void MainWindow::on_pbRemoveSourceXML_clicked()
1025   {
1026 <    removeTableContents( ui->twSourcesGeneral);
1026 >    removeTableContents( ui->twSourcesXML);
1027   }
1028  
1029   void MainWindow::on_pbRemoveSourceTextures_clicked()
# Line 924 | Line 1031 | void MainWindow::on_pbRemoveSourceTextur
1031      removeTableContents(ui->twSourcesTextures);
1032   }
1033  
1034 < void MainWindow::on_pbRemoveSourceModels_clicked()
1034 > void MainWindow::on_pbRemoveSourceObjects_clicked()
1035   {
1036 <    removeTableContents(ui->twSourcesModels);
1036 >    removeTableContents(ui->twSourcesObjects);
1037   }
1038  
1039 < void MainWindow::on_pbRemoveSourceAnimations_clicked()
1039 > void MainWindow::on_pbRemoveSourceCharacters_clicked()
1040   {
1041 <    removeTableContents(ui->twSourcesAnimations);
1041 >    removeTableContents(ui->twSourcesCharacters);
1042   }
1043  
1044   void MainWindow::on_pbRemoveSourceLevels_clicked()
# Line 944 | Line 1051 | void MainWindow::on_pbRemoveSourceMisc_c
1051      removeTableContents(ui->twSourcesMisc);
1052   }
1053  
1054 < void MainWindow::on_pbClearSourcesGeneral_clicked()
1054 > void MainWindow::on_pbClearSourcesXML_clicked()
1055   {
1056 <    clearTableContents(ui->twSourcesGeneral);
1056 >    clearTableContents(ui->twSourcesXML);
1057   }
1058  
1059   void MainWindow::on_pbClearSourcesTextures_clicked()
# Line 954 | Line 1061 | void MainWindow::on_pbClearSourcesTextur
1061      clearTableContents(ui->twSourcesTextures);
1062   }
1063  
1064 < void MainWindow::on_pbClearSourcesModels_clicked()
1064 > void MainWindow::on_pbClearSourcesObjects_clicked()
1065   {
1066 <    clearTableContents(ui->twSourcesModels);
1066 >    clearTableContents(ui->twSourcesObjects);
1067   }
1068  
1069 < void MainWindow::on_pbClearSourcesAnimations_clicked()
1069 > void MainWindow::on_pbClearSourcesCharacters_clicked()
1070   {
1071 <    clearTableContents(ui->twSourcesAnimations);
1071 >    clearTableContents(ui->twSourcesCharacters);
1072   }
1073  
1074   void MainWindow::on_pbClearSourcesLevels_clicked()
# Line 977 | Line 1084 | void MainWindow::on_pbClearSourcesMisc_c
1084   void MainWindow::removeTableContents(DropTableWidget *myTable){
1085      int size = myTable->selectionModel()->selectedRows().size();
1086  
1087 +    QMessageBox::StandardButton defaultButton = QMessageBox::NoButton; // default button for clear asking question, only customizable in mac os
1088 +
1089      if(size==0){
1090          Util::showPopUp("Select a row first.");
1091          return;
1092      }
1093  
1094 <    if(Util::showQuestionPopUp(this,"Are you sure you want to delete the selected rows?")){
1094 > #ifdef Q_OS_MAC
1095 >    if(this->useYesAsDefaultWhenRemovingItems){
1096 >        defaultButton = QMessageBox::Yes;
1097 >    }
1098 >    else{
1099 >        defaultButton = QMessageBox::No;
1100 >    }
1101 > #endif
1102 >
1103 >
1104 >    if(Util::showQuestionPopUp(this,"Are you sure you want to delete the selected rows?",defaultButton)){
1105          for(int i=0; i<size; i++){
1106              //myTable->removeRow(myTable->selectedItems().at(size-i-1)->row());
1107              myTable->removeRow(myTable->selectionModel()->selectedRows().at(size-i-1).row());
# Line 992 | Line 1111 | void MainWindow::removeTableContents(Dro
1111   }
1112  
1113   void MainWindow::clearTableContents(DropTableWidget *myTable){
1114 +
1115 +    QMessageBox::StandardButton defaultButton = QMessageBox::NoButton; // default button for clear asking question, only customizable in mac os
1116 +
1117      if(myTable->rowCount()==0){
1118          Util::showPopUp("Nothing to clear.");
1119          return;
1120      }
1121  
1122 <    if(Util::showQuestionPopUp(this,"Are you sure you want to clear the content?")){
1123 <        myTable->clearContents();
1124 <        myTable->setRowCount(0);
1122 > #ifdef Q_OS_MAC
1123 >    if(this->useYesAsDefaultWhenRemovingItems){
1124 >        defaultButton = QMessageBox::Yes;
1125 >    }
1126 >    else{
1127 >        defaultButton = QMessageBox::No;
1128 >    }
1129 > #endif
1130 >
1131 >    if(Util::showQuestionPopUp(this,"Are you sure you want to clear the content?",defaultButton)){
1132 >        clearTableNoPrompt(myTable);
1133      }
1134      updateItemsLoaded(myTable);
1135   }
1136  
1137 + void MainWindow::clearTableNoPrompt(DropTableWidget *myTable){
1138 +    myTable->clearContents();
1139 +    myTable->setRowCount(0);
1140 + }
1141  
1142   void MainWindow::on_actionPreferences_triggered()
1143   {
# Line 1021 | Line 1155 | void MainWindow::closeEvent(QCloseEvent
1155      }
1156   }
1157  
1024 void MainWindow::on_cbToGeneral_currentIndexChanged(const QString &arg1)
1025 {
1026
1027    ui->cbDatGeneral->setEnabled(false);
1028    ui->cbDatGeneral->setChecked(false);
1029    ui->cbTRAMGeneral->setEnabled(false);
1030    ui->cbTRAMGeneral->setChecked(false);
1031
1032    if(QString::compare(ui->cbFromGeneral->currentText(),"ONI",Qt::CaseSensitive)==0){
1033        if(QString::compare(arg1,"DAT",Qt::CaseSensitive)==0){
1034            ui->cbDatGeneral->setEnabled(true);
1035        }
1036        else{
1037            ui->cbTRAMGeneral->setEnabled(true);
1038        }
1039    }
1040
1041 }
1042
1043 void MainWindow::on_cbToModels_currentIndexChanged(const QString &arg1)
1044 {
1045    ui->cbWithAnimation->setEnabled(false);
1046    ui->cbWithAnimation->setChecked(false);
1047
1048    if(arg1=="DAE"){
1049        ui->cbWithAnimation->setEnabled(true);
1050    }
1051 }
1052
1158   void MainWindow::on_cbToLevels_currentIndexChanged(const QString &arg1)
1159   {
1160  
1056    ui->cbDatLevels->setEnabled(false);
1057    ui->cbDatLevels->setChecked(false);
1058    ui->cbBnvLevels->setEnabled(false);
1059    ui->cbBnvLevels->setChecked(false);
1060    ui->cbAdditionalSourcesLevels->setEnabled(false);
1061    ui->cbAdditionalSourcesLevels->setChecked(false);
1062    ui->cbGridsLevels->setEnabled(false);
1063    ui->cbGridsLevels->setChecked(false);
1064
1161      if(ui->cbFromLevels->currentText()=="MASTER XML" && arg1=="DAT"){
1162          ui->cbDatLevels->setEnabled(true);
1163      }
1164 <    else if(ui->cbFromLevels->currentText()=="DAE" && arg1=="ONI"){
1165 <        ui->cbBnvLevels->setEnabled(true);
1166 <        ui->cbAdditionalSourcesLevels->setEnabled(true);
1164 >    else if(ui->cbFromLevels->currentText()=="MASTER XML" && arg1=="ONI FILES"){
1165 >        ui->cbDatLevels->setEnabled(false);
1166 >        ui->cbDatLevels->setChecked(false);
1167      }
1072 }
1168  
1074 void MainWindow::on_cbDatGeneral_toggled(bool checked)
1075 {
1076    ui->leTargetDatGeneral->setEnabled(checked);
1077 }
1078
1079 void MainWindow::on_cbTRAMGeneral_toggled(bool checked)
1080 {
1081    ui->leTRAMGeneral->setEnabled(checked);
1082    if(checked){
1083        QString file=QFileDialog::getOpenFileName(this,"Choose the TRAM.oni file...","./" , "All Files (*.*)");
1084        if(!file.isEmpty()){
1085            ui->leTRAMGeneral->setText(file);
1086        }
1087    }
1169   }
1170  
1171   void MainWindow::on_cbDatLevels_toggled(bool checked)
# Line 1125 | Line 1206 | void MainWindow::on_cbAdditionalSourcesL
1206      }
1207   }
1208  
1209 + void MainWindow::on_cbWithTRBS_ONCC_toggled(bool checked)
1210 + {
1211 +    ui->leTRBS_ONCC->setEnabled(checked);
1212 + }
1213 +
1214   void MainWindow::on_actionCheck_OniSplit_version_triggered()
1215   {
1216 <    QProcess *myProcess = new QProcess();
1217 <    myProcess->start(GlobalVars::OniSplitExeName+" -version");
1218 <    myProcess->waitForFinished(-1);
1219 <    QString result=myProcess->readAllStandardOutput();
1220 <    delete myProcess;
1221 <    Util::showPopUp("This Vago version was built with base in OniSplit version "+GlobalVars::BuiltOniSplitVersion+"\n\nActual version is:\n"+result);
1216 >    QProcess myProcess;
1217 >    myProcess.setWorkingDirectory(UtilVago::getAppPath());
1218 >    myProcess.start(UtilVago::getOniSplitExeAbsolutePath()+" -version");
1219 >    myProcess.waitForFinished();
1220 >
1221 >    QString result=myProcess.readAllStandardOutput();
1222 >
1223 >    Util::showPopUp("This Vago version was built with base in OniSplit version "+GlobalVars::BuiltOniSplitVersion+"\n\nCurrent version is:\n"+result.trimmed());
1224   }
1225  
1226   void MainWindow::on_actionCheck_xmlTools_version_triggered()
1227   {
1228 <    QProcess *myProcess = new QProcess();
1229 <    myProcess->start(GlobalVars::XmlToolsExeName+" version");
1230 <    myProcess->waitForFinished(-1);
1231 <    QString result=myProcess->readLine();
1232 <    delete myProcess;
1233 <    Util::showPopUp("This Vago version was built with base in xmlTools version "+GlobalVars::BuiltXmlToolsVersion+"\n\nActual version is:\n"+result);
1228 >    QProcess myProcess;
1229 >    myProcess.setWorkingDirectory(UtilVago::getAppPath());
1230 >    myProcess.start(UtilVago::getXmlToolsExeAbsolutePath()+" --version");
1231 >    myProcess.waitForFinished();
1232 >    QString result=myProcess.readLine();
1233 >
1234 >    Util::showPopUp("This Vago version was built with base in XmlTools version "+GlobalVars::BuiltXmlToolsVersion+"\n\nCurrent version is:\n"+result.trimmed());
1235   }
1236  
1237   /**
1238    Update items loaded
1239 <  **/
1240 < void MainWindow::on_tabWidget_selected(const QString &arg1)
1239 > **/
1240 > void MainWindow::on_tabWidget_currentChanged(int)
1241   {
1242 <    if(arg1.compare("General",Qt::CaseSensitive)==0){ //case sentive is faster
1154 <        updateItemsLoaded(ui->twSourcesGeneral);
1155 <    }
1156 <    else if(arg1.compare("Textures",Qt::CaseSensitive)==0){
1157 <        updateItemsLoaded(ui->twSourcesTextures);
1158 <    }
1159 <    else if(arg1.compare("Models",Qt::CaseSensitive)==0){
1160 <        updateItemsLoaded(ui->twSourcesModels);
1161 <    }
1162 <    else if(arg1.compare("Levels",Qt::CaseSensitive)==0){
1163 <        updateItemsLoaded(ui->twSourcesLevels);
1164 <    }
1165 <    else{
1166 <        updateItemsLoaded(ui->twSourcesMisc);
1167 <    }
1242 >    updateItemsLoaded(getCurrentTableWidget());
1243   }
1244  
1245   void MainWindow::updateItemsLoaded(DropTableWidget *currentTable){
# Line 1217 | Line 1292 | void MainWindow::on_actionOther_triggere
1292  
1293   void MainWindow::on_actionView_log_triggered()
1294   {
1295 <    Util::openLogFile();
1295 >    UtilVago::openLogFile();
1296 > }
1297 >
1298 > void MainWindow::on_actionOpen_AE_folder_triggered()
1299 > {
1300 >    QDesktopServices::openUrl(QUrl("file:///"+this->AeLocation));
1301 > }
1302 >
1303 > void MainWindow::on_actionSave_Project_triggered()
1304 > {
1305 >
1306 >    QString filePath = QFileDialog::getSaveFileName(this, tr("Save File"),
1307 >                                                    this->vagoSettings->value("LastProjectPath").toString(),
1308 >                                                    tr("Vago project files (*.vgp)"));
1309 >
1310 >    if(!filePath.isEmpty()){
1311 >        saveProjectState(filePath);
1312 >    }
1313 >
1314 > }
1315 >
1316 > void MainWindow::on_actionSave_triggered()
1317 > {
1318 >    if(this->lastProjectFilePath.isEmpty()){
1319 >        on_actionSave_Project_triggered();
1320 >        return;
1321 >    }
1322 >
1323 >    saveProjectState(this->lastProjectFilePath);
1324 > }
1325 >
1326 > void MainWindow::on_actionLoad_Project_triggered()
1327 > {
1328 >
1329 >    QString filePath = QFileDialog::getOpenFileName(this, tr("Load File"),
1330 >                                                    this->vagoSettings->value("LastProjectPath").toString(),
1331 >                                                    tr("Vago project files (*.vgp)"));
1332 >    if(!filePath.isEmpty()){
1333 >        loadProjectState(filePath);
1334 >    }
1335 > }
1336 >
1337 > void MainWindow::on_actionProject1_triggered()
1338 > {
1339 >    loadProjectState(this->ui->actionProject1->text());
1340 > }
1341 >
1342 > void MainWindow::on_actionProject2_triggered()
1343 > {
1344 >    loadProjectState(this->ui->actionProject2->text());
1345 > }
1346 >
1347 > void MainWindow::on_actionProject3_triggered()
1348 > {
1349 >    loadProjectState(this->ui->actionProject3->text());
1350 > }
1351 >
1352 > void MainWindow::on_actionProject4_triggered()
1353 > {
1354 >    loadProjectState(this->ui->actionProject4->text());
1355 > }
1356 >
1357 > void MainWindow::on_actionProject5_triggered()
1358 > {
1359 >    loadProjectState(this->ui->actionProject5->text());
1360   }
1361  
1362   QString MainWindow::getTypeConversion(DropTableWidget *myTable){
1363      QString from,to;
1364  
1365 <    if(myTable==ui->twSourcesGeneral){
1366 <        from=ui->cbFromGeneral->currentText();
1367 <        to=ui->cbToGeneral->currentText();
1365 >    if(myTable==ui->twSourcesXML){
1366 >        from=ui->cbFromXML->currentText();
1367 >        to=ui->cbToXML->currentText();
1368      }
1369      else if(myTable==ui->twSourcesTextures){
1370          from=ui->cbFromTextures->currentText();
1371          to=ui->cbToTextures->currentText();
1372      }
1373 <    else if(myTable==ui->twSourcesModels){
1374 <        from=ui->cbFromModels->currentText();
1375 <        to=ui->cbToModels->currentText();
1376 <    }
1377 <    else if(myTable==ui->twSourcesAnimations){
1378 <        from=ui->cbFromAnimations->currentText();
1379 <        to=ui->cbToAnimations->currentText();
1373 >    else if(myTable==ui->twSourcesObjects){
1374 >        from=ui->cbFromObjects->currentText();
1375 >        to=ui->cbToObjects->currentText();
1376 >    }
1377 >    else if(myTable==ui->twSourcesCharacters){
1378 >        from=ui->cbFromCharacters->currentText();
1379 >        to=ui->cbToCharacters->currentText();
1380      }
1381      else if(myTable==ui->twSourcesLevels){
1382          from=ui->cbFromLevels->currentText();
# Line 1269 | Line 1408 | void MainWindow::dtContextMenu(DropTable
1408          selectedRows << rowItem.row();
1409      }
1410  
1411 <    QMenu *menu = new QMenu();
1412 <    QAction *copy = new QAction("Copy",myTable);
1413 <    QAction *moveUp = new QAction("Move Up",myTable);
1414 <    QAction *moveDown = new QAction("Move Down",myTable);
1415 <    QAction *changeOptions = new QAction("Change To Current Options",myTable);
1416 <    QMenu *changeOutput = new QMenu("Change Output for:");
1417 <    QAction *outWorkspace = new QAction("Workspace",myTable);
1418 <    QAction *outCurrOutput = new QAction("Current Output Folder",myTable);
1419 <    QAction *outOther = new QAction("Other...",myTable);
1420 <    QAction *edisable = new QAction("Enable/Disable",myTable);
1411 >    std::unique_ptr<QMenu> menu = std::make_unique<QMenu>();
1412 >    std::unique_ptr<QAction> copy =  std::make_unique<QAction>("Copy",myTable);
1413 >    std::unique_ptr<QAction> moveUp = std::make_unique<QAction>("Move Up",myTable);
1414 >    std::unique_ptr<QAction> moveDown = std::make_unique<QAction>("Move Down",myTable);
1415 >    std::unique_ptr<QAction> changeOptions = std::make_unique<QAction>("Change To Current Options",myTable);
1416 >    std::unique_ptr<QMenu> changeOutput = std::make_unique<QMenu>("Change Output for:");
1417 >    std::unique_ptr<QAction> outWorkspace = std::make_unique<QAction>("Workspace",myTable);
1418 >    std::unique_ptr<QAction> outCurrOutput = std::make_unique<QAction>("Current Output Folder",myTable);
1419 >    std::unique_ptr<QAction> outOther = std::make_unique<QAction>("Other...",myTable);
1420 >    std::unique_ptr<QAction> edisable = std::make_unique<QAction>("Enable/Disable",myTable);
1421  
1422 <    menu->addAction(copy);
1422 >    menu->addAction(copy.get());
1423      menu->addSeparator();
1424 <    menu->addAction(moveUp);
1425 <    menu->addAction(moveDown);
1424 >    menu->addAction(moveUp.get());
1425 >    menu->addAction(moveDown.get());
1426      menu->addSeparator();
1427 <    menu->addAction(changeOptions);
1428 <    menu->addMenu(changeOutput);
1429 <    changeOutput->addActions(QList<QAction*>() << outWorkspace << outCurrOutput << outOther);
1430 <    menu->addAction(edisable);
1427 >    menu->addAction(changeOptions.get());
1428 >    menu->addMenu(changeOutput.get());
1429 >    changeOutput->addActions(QList<QAction*>() << outWorkspace.get() << outCurrOutput.get() << outOther.get());
1430 >    menu->addAction(edisable.get());
1431  
1432  
1433      //if it's in the first row it can't be setted up
# Line 1312 | Line 1451 | void MainWindow::dtContextMenu(DropTable
1451  
1452      QAction* selectedOption = menu->exec(event->globalPos());
1453  
1454 <    if(selectedOption==copy){
1454 >    if(selectedOption==copy.get()){
1455          //Let's copy the contents to the clipboard
1456  
1457          QString toCopy;
# Line 1335 | Line 1474 | void MainWindow::dtContextMenu(DropTable
1474          QApplication::clipboard()->setText(toCopy);
1475          showSuccessStatusMessage(QString::number(size) + (size==1?" item ":" items ")+ "copied to the clipboard");
1476      }
1477 <    else if(selectedOption==moveUp){
1477 >    else if(selectedOption==moveUp.get()){
1478          qSort(selectedRows); //let's order the selections by the row number, so we know exactly how to swap it
1479          myTable->swapPositions(selectedRows,-1);
1480      }
1481 <    else if(selectedOption==moveDown){
1481 >    else if(selectedOption==moveDown.get()){
1482          qSort(selectedRows);
1483          myTable->swapPositions(selectedRows,+1);
1484      }
1485 <    else if(selectedOption==changeOptions){
1485 >    else if(selectedOption==changeOptions.get()){
1486          changeToCurrentSettings(selectedRows,myTable);
1487      }
1488 <    else if(selectedOption==outWorkspace){
1488 >    else if(selectedOption==outWorkspace.get()){
1489          changeItemsOutput(myTable,selectedRows,this->workspaceLocation);
1490      }
1491 <    else if(selectedOption==outCurrOutput){
1491 >    else if(selectedOption==outCurrOutput.get()){
1492          changeItemsOutput(myTable,selectedRows,this->outputFolder);
1493      }
1494 <    else if(selectedOption==outOther){
1494 >    else if(selectedOption==outOther.get()){
1495  
1496          QString newDir=QFileDialog::getExistingDirectory(this,"Choose the folder for the output of the files selected...",this->AeLocation+"/GameDataFolder");
1497          newDir=Util::normalizePath(newDir);
# Line 1364 | Line 1503 | void MainWindow::dtContextMenu(DropTable
1503          changeItemsOutput(myTable,selectedRows,newDir);
1504  
1505      }
1506 <    else if(selectedOption==edisable){
1506 >    else if(selectedOption==edisable.get()){
1507  
1508          int enabledCount=0, disabledCount=0;
1509  
# Line 1402 | Line 1541 | void MainWindow::dtContextMenu(DropTable
1541  
1542          showSuccessStatusMessage(result);
1543      }
1405
1406    delete copy;
1407    delete moveUp;
1408    delete moveDown;
1409    delete changeOptions;
1410    delete outWorkspace;
1411    delete outCurrOutput;
1412    delete outOther;
1413    delete changeOutput;
1414    delete edisable;
1415    delete menu;
1544   }
1545  
1546   void MainWindow::changeToCurrentSettings(QList<int> rows, DropTableWidget* myTable){
# Line 1463 | Line 1591 | void MainWindow::changeItemsOutput(DropT
1591   }
1592  
1593   QString MainWindow::getCommand(DropTableWidget* myTable, QString myOutputFolder, QString from, QString to , QString file){
1594 <    if(myTable==ui->twSourcesGeneral){ //So we only need to parse one command.
1595 <        return fileParsingGeneral(myOutputFolder,from,to,file);
1594 >
1595 >    QString tabTitle=ui->tabWidget->tabText(ui->tabWidget->currentIndex()).toLower(); // get current tab title
1596 >
1597 >    if(myTable==ui->twSourcesXML){ //So we only need to parse one command.
1598 >        return fileParsingXML(tabTitle, myOutputFolder,from,to,file);
1599      }
1600      else if(myTable==ui->twSourcesTextures){
1601 <        return fileParsingTextures(myOutputFolder,from,to,file);
1601 >        return fileParsingTextures(tabTitle, myOutputFolder,from,to,file);
1602      }
1603 <    else if(myTable==ui->twSourcesModels){
1604 <        return fileParsingModels(myOutputFolder,from,to,file);
1603 >    else if(myTable==ui->twSourcesObjects){
1604 >        return fileParsingObjects(tabTitle, myOutputFolder,from,to,file);
1605      }
1606 <    else if(myTable==ui->twSourcesAnimations){
1607 <        return fileParsingAnimations(myOutputFolder,from,to,file);
1606 >    else if(myTable==ui->twSourcesCharacters){
1607 >        return fileParsingCharacters(tabTitle, myOutputFolder,from,to,file);
1608      }
1609      else if(myTable==ui->twSourcesLevels){
1610 <        return fileParsingLevels(myOutputFolder,from,to,file);
1610 >        return fileParsingLevels(tabTitle, myOutputFolder,from,to,file);
1611      }
1612      else{
1613          return fileParsingMisc(myOutputFolder,from,to,file);
# Line 1484 | Line 1615 | QString MainWindow::getCommand(DropTable
1615  
1616   }
1617  
1487 /**
1488  This is OS indepented. It maintain size ratio over the Windows and Mac.
1489  **/
1490 void MainWindow::setConverterButtonsSize(){
1491    int height=ui->pbConvertGeneral->sizeHint().height()*1.3;
1492    ui->pbConvertGeneral->setMinimumHeight(height);
1493    ui->pbConvertTextures->setMinimumHeight(height);
1494    ui->pbConvertModels->setMinimumHeight(height);
1495    ui->pbConvertAnimations->setMinimumHeight(height);
1496    ui->pbConvertLevels->setMinimumHeight(height);
1497    ui->pbConvertMisc->setMinimumHeight(height);
1498 }
1499
1618   void MainWindow::connectSlots(){
1619  
1620      //This signal is for thread that is working setup the progress bar (make it visible and set it's min-max)
# Line 1508 | Line 1626 | void MainWindow::connectSlots(){
1626      //This signal is for thread that is working can show the result of a conversion
1627      connect(myConverter, SIGNAL(resultConversion(QString,int)), this, SLOT(TresultConversion(QString,int)));
1628  
1629 +    //This signal is for thread that is working notify the gui thread that the conversion was aborted with sucess
1630 +    connect(myConverter, SIGNAL(conversionAborted()), this, SLOT(TconversionAborted()));
1631 +
1632 +    // This signal is to the user be able to terminate a conversion (OniSplit process in class myConverter will be terminated)
1633 +    connect(this, SIGNAL(terminateCurrProcess()), myConverter, SLOT(terminateCurrProcess()));
1634 +
1635      //Drop signal for General table
1636 <    connect(ui->twSourcesGeneral, SIGNAL(dropped(DropTableWidget*,QStringList)), this, SLOT(addFilesSource(DropTableWidget*,QStringList)));
1636 >    connect(ui->twSourcesXML, SIGNAL(dropped(DropTableWidget*,QStringList)), this, SLOT(addFilesSource(DropTableWidget*,QStringList)));
1637  
1638      //Drop signal for Textures table
1639      connect(ui->twSourcesTextures, SIGNAL(dropped(DropTableWidget*,QStringList)), this, SLOT(addFilesSource(DropTableWidget*,QStringList)));
1640  
1641 <    //Drop signal for Models table
1642 <    connect(ui->twSourcesModels, SIGNAL(dropped(DropTableWidget*,QStringList)), this, SLOT(addFilesSource(DropTableWidget*,QStringList)));
1641 >    //Drop signal for Objects table
1642 >    connect(ui->twSourcesObjects, SIGNAL(dropped(DropTableWidget*,QStringList)), this, SLOT(addFilesSource(DropTableWidget*,QStringList)));
1643  
1644 <    //Drop signal for Animations table
1645 <    connect(ui->twSourcesAnimations, SIGNAL(dropped(DropTableWidget*,QStringList)), this, SLOT(addFilesSource(DropTableWidget*,QStringList)));
1644 >    //Drop signal for Characters table
1645 >    connect(ui->twSourcesCharacters, SIGNAL(dropped(DropTableWidget*,QStringList)), this, SLOT(addFilesSource(DropTableWidget*,QStringList)));
1646  
1647      //Drop signal for Levels table
1648      connect(ui->twSourcesLevels, SIGNAL(dropped(DropTableWidget*,QStringList)), this, SLOT(addFilesSource(DropTableWidget*,QStringList)));
# Line 1527 | Line 1651 | void MainWindow::connectSlots(){
1651      connect(ui->twSourcesMisc, SIGNAL(dropped(DropTableWidget*,QStringList)), this, SLOT(addFilesSource(DropTableWidget*,QStringList)));
1652  
1653      //Context menu for General table
1654 <    connect(ui->twSourcesGeneral, SIGNAL(dtContextMenu(DropTableWidget*,QContextMenuEvent*)), this, SLOT(dtContextMenu(DropTableWidget*,QContextMenuEvent*)));
1654 >    connect(ui->twSourcesXML, SIGNAL(dtContextMenu(DropTableWidget*,QContextMenuEvent*)), this, SLOT(dtContextMenu(DropTableWidget*,QContextMenuEvent*)));
1655  
1656      //Context menu for Textures table
1657      connect(ui->twSourcesTextures, SIGNAL(dtContextMenu(DropTableWidget*,QContextMenuEvent*)), this, SLOT(dtContextMenu(DropTableWidget*,QContextMenuEvent*)));
1658  
1659 <    //Context menu for Models table
1660 <    connect(ui->twSourcesModels, SIGNAL(dtContextMenu(DropTableWidget*,QContextMenuEvent*)), this, SLOT(dtContextMenu(DropTableWidget*,QContextMenuEvent*)));
1659 >    //Context menu for Objects table
1660 >    connect(ui->twSourcesObjects, SIGNAL(dtContextMenu(DropTableWidget*,QContextMenuEvent*)), this, SLOT(dtContextMenu(DropTableWidget*,QContextMenuEvent*)));
1661  
1662 <    //Context menu for Animations table
1663 <    connect(ui->twSourcesAnimations, SIGNAL(dtContextMenu(DropTableWidget*,QContextMenuEvent*)), this, SLOT(dtContextMenu(DropTableWidget*,QContextMenuEvent*)));
1662 >    //Context menu for Characters table
1663 >    connect(ui->twSourcesCharacters, SIGNAL(dtContextMenu(DropTableWidget*,QContextMenuEvent*)), this, SLOT(dtContextMenu(DropTableWidget*,QContextMenuEvent*)));
1664  
1665      //Context menu for Levels table
1666      connect(ui->twSourcesLevels, SIGNAL(dtContextMenu(DropTableWidget*,QContextMenuEvent*)), this, SLOT(dtContextMenu(DropTableWidget*,QContextMenuEvent*)));
# Line 1545 | Line 1669 | void MainWindow::connectSlots(){
1669      connect(ui->twSourcesMisc, SIGNAL(dtContextMenu(DropTableWidget*,QContextMenuEvent*)), this, SLOT(dtContextMenu(DropTableWidget*,QContextMenuEvent*)));
1670   }
1671  
1672 + void MainWindow::saveProjectState(const QString &filePath)
1673 + {
1674 +
1675 +    QList<DropTableWidget*> tableWidgets = getAllTableWidgets();
1676 +
1677 +    pugi::xml_document doc;
1678 +
1679 +    pugi::xml_node rootNode = doc.append_child("VagoProject");
1680 +    rootNode.append_attribute("vagoVersion").set_value(GlobalVars::AppVersion.toUtf8().constData());
1681 +
1682 +    foreach(DropTableWidget* const &myTable, tableWidgets){
1683 +        saveProjectWidget(rootNode, myTable);
1684 +    }
1685 +
1686 +    if(!doc.save_file(filePath.toUtf8().constData(), PUGIXML_TEXT("\t"), pugi::format_default | pugi::format_write_bom, pugi::xml_encoding::encoding_utf8)){
1687 +        UtilVago::showAndLogErrorPopUpLogButton(this->myLogger, "An error ocurred while trying to save the project file. Please try another path.");
1688 +        return;
1689 +    }
1690 +
1691 +    this->vagoSettings->setValue("LastProjectPath",QFileInfo(filePath).absoluteDir().path());
1692 +
1693 +    this->lastProjectFilePath = filePath;
1694 +
1695 +    addNewRecentProject(filePath);
1696 +
1697 +    setVagoWindowTitle();
1698 + }
1699 +
1700 + void MainWindow::saveProjectWidget(pugi::xml_node &rootNode, DropTableWidget* table)
1701 + {
1702 +    QString from;
1703 +    QString to;
1704 +    QString tabName = getTabNameByTableWidget(table);
1705 +
1706 +    pugi::xml_node currentNodeTable = rootNode.append_child("tempName");
1707 +    pugi::xml_node options;
1708 +
1709 +    if(table==ui->twSourcesXML){ //So we only need to parse one command.
1710 +        from = ui->cbFromXML->currentText().toUtf8().constData();
1711 +        to = ui->cbToXML->currentText().toUtf8().constData();
1712 +    }
1713 +    else if(table==ui->twSourcesTextures){
1714 +        from = ui->cbFromTextures->currentText().toUtf8().constData();
1715 +        to = ui->cbToTextures->currentText().toUtf8().constData();
1716 +        options = currentNodeTable.append_child("Options");
1717 +        options.append_attribute("type").set_value(Util::qStrToCstr(getTextureRBCheckedTypeTexture()->text()));
1718 +        options.append_attribute("genMipMaps").set_value(Util::boolToCstr(ui->cbMipMapsTextures->isChecked()));
1719 +        options.append_attribute("noUwrap").set_value(Util::boolToCstr(ui->cbNoUwrap->isChecked()));
1720 +        options.append_attribute("noVwrap").set_value(Util::boolToCstr(ui->cbNoVwrap->isChecked()));
1721 +        options.append_attribute("large").set_value(Util::boolToCstr(ui->cbLarge->isChecked()));
1722 +        options.append_attribute("envMap").set_value(Util::boolToCstr(ui->cbEnvMap->isChecked()));
1723 +        options.append_attribute("envMapValue").set_value(Util::qStrToCstr(ui->leEnvMapTexture->text()));
1724 +    }
1725 +    else if(table==ui->twSourcesCharacters){
1726 +        from = ui->cbFromCharacters->currentText().toUtf8().constData();
1727 +        to = ui->cbToCharacters->currentText().toUtf8().constData();
1728 +        options = currentNodeTable.append_child("Options");
1729 +        options.append_attribute("cellShading").set_value(Util::boolToCstr(ui->cbCellShading->isChecked()));
1730 +        options.append_attribute("normals").set_value(Util::boolToCstr(ui->cbNormals->isChecked()));
1731 +        options.append_attribute("extractTRBSONCC").set_value(Util::boolToCstr(ui->cbWithTRBS_ONCC->isChecked()));
1732 +        options.append_attribute("extractTRBSONCCValue").set_value(Util::qStrToCstr(ui->leTRBS_ONCC->text()));
1733 +    }
1734 +    else if(table==ui->twSourcesObjects){
1735 +        from = ui->cbFromObjects->currentText().toUtf8().constData();
1736 +        to = ui->cbToObjects->currentText().toUtf8().constData();
1737 +        options = currentNodeTable.append_child("Options");
1738 +        options.append_attribute("texture").set_value(Util::boolToCstr(ui->cbTexture->isChecked()));
1739 +        options.append_attribute("textureValue").set_value(Util::qStrToCstr(ui->leTextureName->text()));
1740 +        options.append_attribute("withAnimation").set_value(Util::boolToCstr(ui->cbWithAnimation->isChecked()));
1741 +        options.append_attribute("withAnimationValue").set_value(Util::qStrToCstr(ui->leAnimationName->text()));
1742 +    }
1743 +    else if(table==ui->twSourcesLevels){
1744 +        from = ui->cbFromLevels->currentText().toUtf8().constData();
1745 +        to = ui->cbToLevels->currentText().toUtf8().constData();
1746 +        options = currentNodeTable.append_child("Options");
1747 +        options.append_attribute("extractWithFiles").set_value(Util::boolToCstr(ui->cbSpecificFilesLevels->isChecked()));
1748 +        options.append_attribute("extractWithFilesValue").set_value(Util::qStrToCstr(ui->leSpecificFilesLevels->text()));
1749 +        options.append_attribute("datFilename").set_value(Util::boolToCstr(ui->cbDatLevels->isChecked()));
1750 +        options.append_attribute("datFilenameValue").set_value(Util::qStrToCstr(ui->leTargetDatLevels->text()));
1751 +        options.append_attribute("bnvSource").set_value(Util::boolToCstr(ui->cbBnvLevels->isChecked()));
1752 +        options.append_attribute("bnvSourceValue").set_value(Util::qStrToCstr(ui->leBnvLevels->text()));
1753 +        options.append_attribute("generateGrids").set_value(Util::boolToCstr(ui->cbGridsLevels->isChecked()));
1754 +        options.append_attribute("additionalSources").set_value(Util::boolToCstr(ui->cbAdditionalSourcesLevels->isChecked()));
1755 +        options.append_attribute("additionalSourcesValue").set_value(Util::qStrToCstr(ui->leAdditSourcesLevels->text()));
1756 +    }
1757 +    else{
1758 +        from = ui->cbFromMisc->currentText().toUtf8().constData();
1759 +        to = ui->cbToMisc->currentText().toUtf8().constData();
1760 +    }
1761 +
1762 +    currentNodeTable.set_name(tabName.toUtf8().constData());
1763 +
1764 +    currentNodeTable.append_attribute("from").set_value(from.toUtf8().constData());
1765 +    currentNodeTable.append_attribute("to").set_value(to.toUtf8().constData());
1766 +
1767 +
1768 +    for(int i=0; i<table->rowCount(); i++){
1769 +
1770 +        QString currFileFolder = table->item(i,0)->text();
1771 +        QString currFromTo = table->item(i,1)->text();
1772 +        QString currCommand = table->item(i,2)->text();
1773 +
1774 +        pugi::xml_node currentRow = currentNodeTable.append_child("Row");
1775 +
1776 +
1777 +        currentRow.append_attribute("fileFolder").set_value(Util::qStrToCstr(currFileFolder));
1778 +        currentRow.append_attribute("fromTo").set_value(Util::qStrToCstr(currFromTo));
1779 +        currentRow.append_attribute("command").set_value(Util::qStrToCstr(currCommand));
1780 +
1781 +        if(table->item(i,2)->background()==table->disabledBackStyle){
1782 +            currentRow.append_attribute("disabled").set_value(true);
1783 +        }
1784 +
1785 +    }
1786 + }
1787 +
1788 + QRadioButton* MainWindow::getTextureRBCheckedTypeTexture()
1789 + {
1790 +    if(ui->rbBGR32->isChecked()){
1791 +        return ui->rbBGR32;
1792 +    }
1793 +    else if(ui->rbBGRA32->isChecked()){
1794 +        return ui->rbBGRA32;
1795 +    }
1796 +    else if(ui->rbBGR555->isChecked()){
1797 +        return ui->rbBGR555;
1798 +    }
1799 +    else if(ui->rbBGRA5551->isChecked()){
1800 +        return ui->rbBGRA5551;
1801 +    }
1802 +    else if(ui->rbBGRA444->isChecked()){
1803 +        return ui->rbBGRA444;
1804 +    }
1805 +    else{ //dxt1 checked
1806 +        return ui->rbDxt1;
1807 +    }
1808 + }
1809 +
1810 + QRadioButton* MainWindow::getTextureRBTypeTextureByName(const QString &texType)
1811 + {
1812 +    if(QString::compare(texType,ui->rbBGR32->text(),Qt::CaseSensitive)==0){
1813 +        return ui->rbBGR32;
1814 +    }
1815 +    else if(QString::compare(texType,ui->rbBGRA32->text(),Qt::CaseSensitive)==0){
1816 +        return ui->rbBGRA32;
1817 +    }
1818 +    else if(QString::compare(texType, ui->rbBGR555->text(),Qt::CaseSensitive)==0){
1819 +        return ui->rbBGR555;
1820 +    }
1821 +    else if(QString::compare(texType,ui->rbBGRA5551->text(),Qt::CaseSensitive)==0){
1822 +        return ui->rbBGRA5551;
1823 +    }
1824 +    else if(QString::compare(texType,ui->rbBGRA444->text(),Qt::CaseSensitive)==0){
1825 +        return ui->rbBGRA444;
1826 +    }
1827 +    else{ //dxt1
1828 +        return ui->rbDxt1;
1829 +    }
1830 +
1831 + }
1832 +
1833 + void MainWindow::setVagoWindowTitle(){
1834 +
1835 +    QString vagoTitle = "Vago v"+GlobalVars::AppVersion + " - ";
1836 +
1837 +    if(this->lastProjectFilePath.isEmpty()){
1838 +        vagoTitle += "Untitled";
1839 +    }
1840 +    else{
1841 +        vagoTitle += Util::cutNameWithoutBackSlash(this->lastProjectFilePath);
1842 +    }
1843 +
1844 +    setWindowTitle(vagoTitle);
1845 + }
1846 +
1847 + DropTableWidget* MainWindow::getCurrentTableWidget(){
1848 +
1849 +    return getTableWidgetByTabName(ui->tabWidget->tabText(ui->tabWidget->currentIndex()));
1850 +
1851 + }
1852 +
1853 + DropTableWidget* MainWindow::getTableWidgetByTabName(const QString &tabName){
1854 +
1855 +    if(tabName.compare("XML",Qt::CaseSensitive)==0){ //case sentive is faster
1856 +        return ui->twSourcesXML;
1857 +    }
1858 +    else if(tabName.compare("Textures",Qt::CaseSensitive)==0){
1859 +        return ui->twSourcesTextures;
1860 +    }
1861 +    else if(tabName.compare("Characters",Qt::CaseSensitive)==0){
1862 +        return ui->twSourcesCharacters;
1863 +    }
1864 +    else if(tabName.compare("Objects",Qt::CaseSensitive)==0){
1865 +        return ui->twSourcesObjects;
1866 +    }
1867 +    else if(tabName.compare("Levels",Qt::CaseSensitive)==0){
1868 +        return ui->twSourcesLevels;
1869 +    }
1870 +    else{
1871 +        return ui->twSourcesMisc;
1872 +    }
1873 +
1874 + }
1875 +
1876 + QString MainWindow::getCurrentTabName(){
1877 +    return ui->tabWidget->tabText(ui->tabWidget->currentIndex());
1878 + }
1879 +
1880 + QString MainWindow::getTabNameByTableWidget(DropTableWidget* table){
1881 +
1882 +    if(table == ui->twSourcesXML){
1883 +        return ui->tabWidget->tabText(XMLTabIndex);
1884 +    }
1885 +    else if(table == ui->twSourcesTextures){
1886 +        return ui->tabWidget->tabText(TexturesTabIndex);
1887 +    }
1888 +    else if(table == ui->twSourcesCharacters){
1889 +        return ui->tabWidget->tabText(CharactersTabIndex);
1890 +    }
1891 +    else if(table == ui->twSourcesObjects){
1892 +        return ui->tabWidget->tabText(ObjectsTabIndex);
1893 +    }
1894 +    else if(table == ui->twSourcesLevels){
1895 +        return ui->tabWidget->tabText(LevelsTabIndex);
1896 +    }
1897 +    else{
1898 +        return ui->tabWidget->tabText(MiscTabIndex);
1899 +    }
1900 +
1901 + }
1902 +
1903 + QList<DropTableWidget*> MainWindow::getAllTableWidgets()
1904 + {
1905 +    QList<DropTableWidget*> tableWidgets;
1906 +
1907 +    tableWidgets << ui->twSourcesXML << ui->twSourcesTextures << ui->twSourcesCharacters
1908 +                 << ui->twSourcesObjects << ui->twSourcesLevels << ui->twSourcesMisc;
1909 +
1910 +    return tableWidgets;
1911 + }
1912 +
1913 + void MainWindow::loadProjectState(const QString &filePath)
1914 + {
1915 +
1916 +    QString statusError = "Couldn't load project.";
1917 +
1918 +    pugi::xml_document doc;
1919 +
1920 +    pugi::xml_parse_result result = doc.load_file(Util::qStrToCstr(filePath));
1921 +
1922 +    if(result.status!=pugi::status_ok){
1923 +        UtilVago::showAndLogErrorPopUpLogButton(this->myLogger, "An error ocurred while loading project file.\n" + QString(result.description()));
1924 +        showErrStatusMessage(statusError);
1925 +        return;
1926 +    }
1927 +
1928 +
1929 +    if(QString(doc.root().first_child().name()) != "VagoProject"){
1930 +        UtilVago::showAndLogErrorPopUpLogButton(this->myLogger, QString(doc.root().name()) + "The file opened is not a valid VagoProject file. Load aborted.");
1931 +        showErrStatusMessage(statusError);
1932 +        return;
1933 +    }
1934 +
1935 +    QString projVagoVersion;
1936 +
1937 +    try{
1938 +        projVagoVersion = QString(doc.select_node("/VagoProject/@vagoVersion").attribute().value());
1939 +    }
1940 +    catch (const pugi::xpath_exception& e)
1941 +    {
1942 +        UtilVago::showAndLogErrorPopUpLogButton(this->myLogger, "Couldn't find the vagoVersion of the current project. Load aborted.\n" + QString(e.what()));
1943 +        showErrStatusMessage(statusError);
1944 +        return;
1945 +    }
1946 +
1947 +    if(!projVagoVersion.startsWith(GlobalVars::LastCompatibleVersion)){
1948 +        UtilVago::showAndLogErrorPopUpLogButton(this->myLogger, "The project that you are trying to load seems it is not compatible with your Vago Version. Please update Vago and try again.");
1949 +        showErrStatusMessage(statusError);
1950 +        return;
1951 +    }
1952 +
1953 +    // After the initial validations begin loading the project data
1954 +
1955 +    QList<DropTableWidget*> tableWidgets = getAllTableWidgets();
1956 +
1957 +    try{
1958 +        foreach(DropTableWidget* const &myTable, tableWidgets){
1959 +            loadProjectWidget(doc, myTable);
1960 +        }
1961 +    }
1962 +    catch(const std::exception& e){
1963 +        UtilVago::showAndLogErrorPopUpLogButton(this->myLogger, "Couldn't load the vago project. Error: " + QString(e.what()));
1964 +        showErrStatusMessage(statusError);
1965 +        return;
1966 +    }
1967 +
1968 +    this->vagoSettings->setValue("LastProjectPath",QFileInfo(filePath).absoluteDir().path());
1969 +
1970 +    this->lastProjectFilePath = filePath;
1971 +
1972 +    addNewRecentProject(filePath);
1973 +
1974 +    setVagoWindowTitle();
1975 +
1976 +    showSuccessStatusMessage("Project loaded sucessfully.");
1977 + }
1978 +
1979 +
1980 + void MainWindow::loadProjectWidget(pugi::xml_document &doc, DropTableWidget* table)
1981 + {
1982 +    QString tabName = getTabNameByTableWidget(table);
1983 +    QString from (doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/@from")).attribute().value());
1984 +    QString to (doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/@to")).attribute().value());
1985 +
1986 +    if(table==ui->twSourcesXML){
1987 +        ui->cbFromXML->setCurrentText(from);
1988 +        on_cbFromXML_currentIndexChanged(from);
1989 +        ui->cbToXML->setCurrentText(to);
1990 +    }
1991 +    else if(table==ui->twSourcesTextures){
1992 +        //ui->cbFromTextures->setCurrentText(from);
1993 +        on_cbFromTextures_currentIndexChanged(from);
1994 +        ui->cbToTextures->setCurrentText(to);
1995 +
1996 +        getTextureRBTypeTextureByName((doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@type")).attribute().value()))->setChecked(true);
1997 +        ui->cbMipMapsTextures->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@genMipMaps")).attribute().as_bool());
1998 +        ui->cbNoUwrap->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@noUwrap")).attribute().as_bool());
1999 +        ui->cbNoVwrap->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@noVwrap")).attribute().as_bool());
2000 +        ui->cbLarge->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@large")).attribute().as_bool());
2001 +        ui->cbEnvMap->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@envMap")).attribute().as_bool());
2002 +        ui->leEnvMapTexture->setText(QString(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@envMapValue")).attribute().value()));
2003 +    }
2004 +    else if(table==ui->twSourcesCharacters){
2005 +        ui->cbFromCharacters->setCurrentText(from);
2006 +        on_cbFromCharacters_currentIndexChanged(from);
2007 +        ui->cbToCharacters->setCurrentText(to);
2008 +
2009 +
2010 +        ui->cbCellShading->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@cellShading")).attribute().as_bool());
2011 +        ui->cbNormals->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@normals")).attribute().as_bool());
2012 +        ui->cbWithTRBS_ONCC->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@extractTRBSONCC")).attribute().as_bool());
2013 +        ui->leTRBS_ONCC->setText(QString(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@extractTRBSONCCValue")).attribute().value()));
2014 +    }
2015 +    else if(table==ui->twSourcesObjects){
2016 +        ui->cbFromObjects->setCurrentText(from);
2017 +        on_cbFromObjects_currentIndexChanged(from);
2018 +        ui->cbToObjects->setCurrentText(to);
2019  
2020 +        ui->cbTexture->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@texture")).attribute().as_bool());
2021 +        ui->leTextureName->setText(QString(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@textureValue")).attribute().value()));
2022 +        ui->cbWithAnimation->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@withAnimation")).attribute().as_bool());
2023 +        ui->leAnimationName->setText(QString(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@withAnimationValue")).attribute().value()));
2024 +    }
2025 +    else if(table==ui->twSourcesLevels){
2026 +        ui->cbFromLevels->setCurrentText(from);
2027 +        on_cbFromLevels_currentIndexChanged(from);
2028 +        ui->cbToLevels->setCurrentText(to);
2029 +
2030 +        ui->cbSpecificFilesLevels->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@extractWithFiles")).attribute().as_bool());
2031 +        ui->leSpecificFilesLevels->setText(QString(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@extractWithFilesValue")).attribute().value()));
2032 +        ui->cbDatLevels->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@datFilename")).attribute().as_bool());
2033 +        ui->leTargetDatLevels->setText(QString(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@datFilenameValue")).attribute().value()));
2034 +        ui->cbBnvLevels->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@bnvSource")).attribute().as_bool());
2035 +        ui->leBnvLevels->setText(QString(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@bnvSourceValue")).attribute().value()));
2036 +        ui->cbGridsLevels->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@generateGrids")).attribute().as_bool());
2037 +        ui->cbAdditionalSourcesLevels->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@additionalSources")).attribute().as_bool());
2038 +        ui->leAdditSourcesLevels->setText(QString(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@bnvSource")).attribute().value()));
2039 +    }
2040 +    else{
2041 +        ui->cbFromMisc->setCurrentText(from);
2042 +        on_cbFromMisc_currentIndexChanged(from);
2043 +        ui->cbToMisc->setCurrentText(to);
2044 +    }
2045 +
2046 +    // Clean previous rows
2047 +    clearTableNoPrompt(table);
2048 +
2049 +    for(const pugi::xpath_node &xPathNode : doc.select_nodes(Util::qStrToCstr("/VagoProject/"+tabName+"/Row"))){
2050 +        pugi::xml_node currNode = xPathNode.node();
2051 +
2052 +        QString currFileFolder = currNode.attribute("fileFolder").value();
2053 +        QString currFromTo = currNode.attribute("fromTo").value();
2054 +        QString currCommand = currNode.attribute("command").value();
2055 +
2056 +        bool isToDisable = false;
2057 +        pugi::xml_attribute disabledAttr = currNode.attribute("disabled");
2058 +        isToDisable = disabledAttr.empty() ? false : disabledAttr.as_bool();
2059 +
2060 +        addRowTable(table,currFileFolder,currFromTo,currCommand, isToDisable);
2061 +    }
2062 + }
2063 +
2064 + void MainWindow::saveRecentProjects(){
2065 +    for(int i=0; i<this->recentProjectsList.size(); i++){
2066 +        this->vagoSettings->setValue("RecentProject" + QString::number(i+1), recentProjectsList[i]);
2067 +    }
2068 + }
2069 +
2070 + void MainWindow::loadRecentProjects(){
2071 +    for(int i=0; i<this->recentProjectsMaxSize; i++){
2072 +
2073 +        QString currProj = this->vagoSettings->value("RecentProject" + QString::number(i+1)).toString();
2074 +
2075 +        if(!currProj.isEmpty()){
2076 +            recentProjectsList.append(currProj);
2077 +        }
2078 +        else{
2079 +            break;
2080 +        }
2081 +    }
2082 +
2083 +    reloadRecentProjectsMenu();
2084 +
2085 + }
2086 +
2087 + void MainWindow::addNewRecentProject(const QString &filePath){
2088 +
2089 +    // If the new project is equal to the last one simply ignore
2090 +    if(filePath == this->vagoSettings->value("RecentProject1").toString()){
2091 +        return;
2092 +    }
2093 +
2094 +    // If the item already exists in our list remove it, so it can go to the top again
2095 +    for(auto it = this->recentProjectsList.begin(); it != this->recentProjectsList.end();){
2096 +        if(*it == filePath){
2097 +            it = this->recentProjectsList.erase(it);
2098 +        }
2099 +        else{
2100 +            it++;
2101 +        }
2102 +    }
2103 +
2104 +    // if we gonna overflow our list, remove the older item to reserve space to the new one
2105 +    if(this->recentProjectsList.size()==this->recentProjectsMaxSize){
2106 +        this->recentProjectsList.removeLast();
2107 +    }
2108 +
2109 +    this->vagoSettings->setValue("LastProjectPath",QFileInfo(filePath).absoluteDir().path());
2110 +
2111 +    // add new recent file
2112 +    this->recentProjectsList.prepend(filePath);
2113 +
2114 +    reloadRecentProjectsMenu();
2115 +
2116 +    saveRecentProjects();
2117 + }
2118 +
2119 + void MainWindow::reloadRecentProjectsMenu(){
2120 +
2121 +    ui->menuRecent_Projects->setEnabled(false);
2122 +    ui->actionProject1->setVisible(false);
2123 +    ui->actionProject2->setVisible(false);
2124 +    ui->actionProject3->setVisible(false);
2125 +    ui->actionProject4->setVisible(false);
2126 +    ui->actionProject5->setVisible(false);
2127 +
2128 +    {
2129 +        QList<QString>::const_iterator it;
2130 +        int i;
2131 +        for(it = recentProjectsList.cbegin(), i=0; it != recentProjectsList.cend(); it++, i++){
2132 +
2133 +            QAction* currAction = nullptr;
2134 +
2135 +            switch (i){
2136 +            case 0:
2137 +                currAction = ui->actionProject1;
2138 +                break;
2139 +            case 1:
2140 +                currAction = ui->actionProject2;
2141 +                break;
2142 +            case 2:
2143 +                currAction = ui->actionProject3;
2144 +                break;
2145 +            case 3:
2146 +                currAction = ui->actionProject4;
2147 +                break;
2148 +            case 4:
2149 +                currAction = ui->actionProject5;
2150 +                break;
2151 +            }
2152 +
2153 +            if(currAction){
2154 +                ui->menuRecent_Projects->setEnabled(true);
2155 +                currAction->setText(*it);
2156 +                currAction->setVisible(true);
2157 +            }
2158 +        }
2159 +    }
2160 +
2161 + }

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)