source: s10k/Vago/mainwindow.cpp@ 1092

Last change on this file since 1092 was 1061, checked in by s10k, 8 years ago

Added Vago 1.3

File size: 88.0 KB
Line 
1#include "mainwindow.h"
2#include "ui_mainwindow.h"
3
4const QString MainWindow::VagoSettingsName = "settingsVago.ini";
5
6MainWindow::MainWindow(QWidget *parent) :
7 QMainWindow(parent),
8 ui(new Ui::MainWindow)
9{
10 ui->setupUi(this);
11
12 this->myLogger = new Logger(UtilVago::getAppPath(), GlobalVars::AppLogName); //start logger
13
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::getOniSplitExecutableAbsolutePath())){
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(UtilVago::getXmlToolsExecutableAbsolutePath())){
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(UtilVago::getAppPath() + "/" + this->VagoSettingsName, QSettings::IniFormat);
30
31 //First Execution? Old configuration? Settings missed?
32 bool iniChanged=false;
33 if(!this->vagoSettings->contains("VagoVersion") || this->vagoSettings->value("VagoVersion")!=GlobalVars::AppVersion){
34 this->vagoSettings->setValue("VagoVersion", GlobalVars::AppVersion);
35 iniChanged=true;
36 }
37 if(!this->vagoSettings->contains("Workspace")){
38 this->vagoSettings->setValue("Workspace", UtilVago::getAppPath()+"/VagoWorkspace");
39 iniChanged=true;
40 }
41 if(!this->vagoSettings->contains("AeFolder")){
42
43 Util::showPopUp("Seems it's the first time you are executing Vago. \n\nPlease input your Anniversary Edition (AE) Folder.");
44 QString aefolder=Util::normalizePath(QFileDialog::getExistingDirectory(this,"Choose Anniversary Edition (AE) folder..."));
45
46 if(aefolder.isEmpty()){
47 UtilVago::showAndLogErrorPopUp(this->myLogger, "AE folder is mandatory. Application will now exit.");
48 exit(1);
49 }
50
51 if(!aefolder.endsWith("AE")){
52 Util::showWarningPopUp("Seems the folder you selected isn't called 'AE'. \n\nIf you run in any problems you can always change it in Vago preferences window.");
53 }
54
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;
69 }
70 if(!this->vagoSettings->contains("SeparateInWorkspace")){
71 this->vagoSettings->setValue("SeparateInWorkspace",true);
72 iniChanged=true;
73 }
74 if(!this->vagoSettings->contains("AskSaveProject")){
75 this->vagoSettings->setValue("AskSaveProject", true);
76 iniChanged=true;
77 }
78 if(!this->vagoSettings->contains("AskToOpenLastProject")){
79 this->vagoSettings->setValue("AskToOpenLastProject", false);
80 iniChanged=true;
81 }
82 if(!this->vagoSettings->contains("LastProjectPath")){
83 this->vagoSettings->setValue("LastProjectPath", this->vagoSettings->value("Workspace"));
84 iniChanged=true;
85 }
86 for(int i=0; i<this->recentProjectsMaxSize; i++){
87 if(!this->vagoSettings->contains("RecentProject" + QString::number(i+1))){
88 this->vagoSettings->setValue("RecentProject" + QString::number(i+1), "");
89 iniChanged=true;
90 }
91 }
92#ifdef Q_OS_MAC
93 if(!this->vagoSettings->contains("useYesAsDefaultWhenRemovingItems")){
94 this->vagoSettings->setValue("useYesAsDefaultWhenRemovingItems", false);
95 iniChanged=true;
96 }
97#endif
98
99 if(iniChanged){
100 this->vagoSettings->sync();
101 }
102 ///
103
104 this->workspaceLocation=this->vagoSettings->value("Workspace").toString();
105 this->workspaceWizardsLocation=this->workspaceLocation+"/Wizards";
106 this->AeLocation=this->vagoSettings->value("AeFolder").toString();
107 this->outputFolder=this->workspaceLocation;
108 this->startedWindowWidth=this->vagoSettings->value("WindowWidth").toInt();
109 this->startedWindowHeight=this->vagoSettings->value("WindowHeight").toInt();
110#ifdef Q_OS_MAC
111 this->useYesAsDefaultWhenRemovingItems=this->vagoSettings->value("useYesAsDefaultWhenRemovingItems").toBool();
112#endif
113
114 //Create our workspace if it doesn't exists yet
115 if(!QDir(this->workspaceLocation).exists()){
116 QDir().mkdir(this->workspaceLocation);
117 }
118 this->itemsLoaded=new QLabel(this);
119 ui->statusBar->addWidget(this->itemsLoaded);
120 this->myBar = new QProgressBar(this);
121 this->myBar->setTextVisible(false); //hides text
122
123 this->myBar->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Fixed);
124 this->myBar->setMinimumWidth(150);
125 this->myBar->hide(); //hide while not being used
126 ui->tbAbortConversion->hide(); //hide while not being used
127
128 ui->statusBar->addPermanentWidget(this->myBar); //this adds automatically in right
129 ui->statusBar->addPermanentWidget(ui->tbAbortConversion);
130
131 // User interface
132 ui->mainToolBar->addWidget(ui->tbAE); //add ae installer launch button
133 ui->mainToolBar->addWidget(ui->emptySpacerLabel); //trick, we can't add directly a space so we add an empty
134 ui->mainToolBar->addWidget(ui->tbOni); //add oni launch buttonlabel
135 ui->mainToolBar->addWidget(ui->emptySpacerLabel2); //same as before
136 ui->mainToolBar->addWidget(ui->tbCommand); //add option to manual onisplit commands
137 ui->mainToolBar->addWidget(ui->emptySpacerLabel3); //same as before
138 ui->mainToolBar->addWidget(ui->tbXmlToolsInterface); //add option to manual onisplit commands
139 ui->mainToolBar->addWidget(ui->emptySpacerLabel4); //same as before
140 ui->mainToolBar->addWidget(ui->tbOpenFolder); //add option to open folder with files converted etc
141
142 ui->mainToolBar->setLayoutDirection(Qt::RightToLeft);
143
144 ui->pbConvert->setMinimumHeight(ui->pbConvert->sizeHint().height()*1.5); // This is OS indepented. It maintain size ratio over the Windows and Mac.
145
146
147#ifdef Q_OS_MAC
148 // 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
149 ui->tbOni->setIcon(QIcon(":/new/icons/oni_icon_mac.png")); // Oni executable on mac have a different icon than windows
150 // Set mac platform the first one in the menu, and also make it checkable by default
151 ui->menuTarget_Platform->removeAction(ui->actionWindows);
152 ui->menuTarget_Platform->addAction(ui->actionWindows);
153 ui->actionWindows->setChecked(false);
154 ui->actionMac_Windows_demo->setChecked(true);
155 // resize(800,600); // Mac OS pcs should be able to render this resolution without any problem. It's also better
156 //// because the components on mac use more space
157#endif
158
159 resize(this->startedWindowWidth,this->startedWindowHeight);
160
161#ifdef Q_OS_MAC
162 ui->pbConvert->setToolTip(ui->pbConvert->toolTip() + " (⌘ + Enter)");
163#else
164 ui->pbConvert->setToolTip(ui->pbConvert->toolTip() + " (Ctrl + Enter)");
165#endif
166
167 //Commands Mapping
168 this->commandMap = QHash<QString, QString>();
169 mapCommands();
170
171 updateItemsLoaded(ui->twSourcesXML);
172
173 loadRecentProjects();
174}
175
176MainWindow::~MainWindow()
177{
178 delete ui;
179 this->myLogger->writeString("Application Exited.");
180}
181
182
183void MainWindow::showEvent(QShowEvent *e)
184{
185 // If we don't have a converter yet, application wasn't started.
186 if(!this->applicationIsFullyLoaded)
187 {
188 // Apparently Qt doesn't contains a slot to when the application was fully load (mainwindow). So we do our own implementation instead.
189 connect(this, SIGNAL(signalAppIsLoaded()), this, SLOT(applicationWasLoaded()), Qt::ConnectionType::QueuedConnection);
190 emit signalAppIsLoaded();
191 }
192
193 e->accept();
194}
195
196// Called only when the MainWindow was fully loaded and painted on the screen. This slot is only called once.
197void MainWindow::applicationWasLoaded(){
198#ifdef Q_OS_WIN
199 // QProgressBar only works after the windows was shown
200 // http://stackoverflow.com/questions/24840941/qwintaskbarprogress-wont-show (Kervala answer)
201
202 this->win7TaskBarButton = new QWinTaskbarButton();
203
204 this->win7TaskBarButton->setWindow(this->windowHandle());
205
206 this->win7TaskBarProgress = this->win7TaskBarButton->progress();
207
208 //Create a thread for do the conversion in background
209 this->myConverter = new Converter(UtilVago::getAppPath(), this->myLogger, &this->listToProccess, this->win7TaskBarProgress);
210#else
211 this->myConverter = new Converter(UtilVago::getAppPath(), this->myLogger, &this->listToProccess);
212#endif
213
214 connectSlots();
215
216 this->myLogger->writeString("Application started.");
217
218 this->applicationIsFullyLoaded = true;
219
220 QString lastSavedProject = this->vagoSettings->value("RecentProject1").toString();
221
222 if(!lastSavedProject.isEmpty() && this->vagoSettings->value("AskToOpenLastProject").toBool()){
223 if(Util::showQuestionPopUp(this,"Do you want to load latest project?\n\nLatest project was '" + Util::cutNameWithoutBackSlash(lastSavedProject) + "'.")){
224 loadProjectState(lastSavedProject);
225 }
226 }
227}
228
229
230void MainWindow::on_actionExit_triggered()
231{
232 close();
233}
234
235void MainWindow::on_actionAbout_triggered()
236{
237 //Show preferences
238 About *aboutWindow = new About(this);
239 aboutWindow->show(); //it destroys itself when finished.
240}
241
242void MainWindow::on_actionAE_Package_Creator_triggered()
243{
244 // it deletes itself once closed
245 WizardFactory<PackageWizard>::startInstance(UtilVago::getAppPath(), this->workspaceWizardsLocation, this->vagoSettings, this->myLogger);
246}
247
248void MainWindow::on_actionSound_Wizard_triggered()
249{
250 // it deletes itself once closed
251 WizardFactory<SoundWizard>::startInstance(UtilVago::getAppPath(), this->workspaceWizardsLocation, this->vagoSettings, this->myLogger, &this->commandMap);
252}
253
254void MainWindow::on_actionBackground_Image_Wizard_triggered()
255{
256 // it deletes itself once closed
257 WizardFactory<BGImageWizard>::startInstance(UtilVago::getAppPath(), this->workspaceWizardsLocation, this->vagoSettings, this->myLogger);
258}
259
260void MainWindow::on_actionWindow_Messages_Wizard_triggered()
261{
262 // it deletes itself once closed
263 WizardFactory<WmWizard>::startInstance(UtilVago::getAppPath(), this->workspaceWizardsLocation, this->vagoSettings, this->myLogger);
264}
265
266void MainWindow::on_tbOni_clicked()
267{
268 QStringList arguments;
269
270 if(this->vagoSettings->value("OniWindow").toBool()){ // Run in a window?
271 arguments << "-noswitch";
272 }
273#ifdef Q_OS_WIN
274 else{
275 arguments << "-switch"; // only supported on windows. Was added by daodan dll.
276 }
277#endif
278
279 arguments << "-debugfiles";
280
281 if(!QProcess::startDetached(this->AeLocation+"/"+GlobalVars::OniExe,arguments,this->AeLocation)){
282 showErrStatusMessage("Oni could not be started!");
283 }
284}
285
286void MainWindow::on_tbAE_clicked()
287{
288 // If the app turn out someday to a native app use QProcess::startDetached instead...
289
290 if(!QDesktopServices::openUrl("file:///"+this->AeLocation+"/AEInstaller/bin/AEInstaller2.jar")){
291 showErrStatusMessage("Could not start AE Installer!");
292 }
293}
294
295void MainWindow::on_tbOpenFolder_clicked()
296{
297 QDesktopServices::openUrl(QUrl("file:///"+this->outputFolder));
298}
299
300
301void MainWindow::on_tbXmlToolsInterface_clicked()
302{
303 //We pass no parent because we want to have an independent window for XmlToolsInterface,
304 //so we can minimize it or maximize indepently from the MainWindow
305 XmlToolsInterface *xmlToolsWindow = new XmlToolsInterface(this->myLogger);
306 xmlToolsWindow->show(); //it destroys itself when finished.
307}
308
309void MainWindow::on_tbAbortConversion_clicked()
310{
311 if(Util::showQuestionPopUp(this,"Are you sure you want to abort the current conversion?")){
312 emit terminateCurrProcess();
313 }
314}
315
316void MainWindow::on_cbEnvMap_toggled(bool checked)
317{
318 ui->leEnvMapTexture->setEnabled(checked);
319}
320
321void MainWindow::on_cbTexture_toggled(bool checked)
322{
323 ui->leTextureName->setEnabled(checked);
324}
325
326void MainWindow::on_cbWithAnimation_toggled(bool checked)
327{
328 ui->leAnimationName->setEnabled(checked);
329}
330
331void MainWindow::on_cbSpecificFilesLevels_toggled(bool checked)
332{
333 ui->leSpecificFilesLevels->setEnabled(checked);
334}
335
336void MainWindow::on_actionCheck_For_Updates_triggered()
337{
338
339 //let's check in the web if this version is the latest
340 QNetworkAccessManager *manager = new QNetworkAccessManager(this);
341 connect(manager, SIGNAL(finished(QNetworkReply*)),
342 this, SLOT(checkVagoLastVersion(QNetworkReply*)));
343
344 manager->get(QNetworkRequest(QUrl(GlobalVars::VagoCheckUpdatesUrl)));
345
346}
347
348void MainWindow::checkVagoLastVersion(QNetworkReply *result){
349
350 if(result->error()==QNetworkReply::NoError){
351 QScriptEngine engine;
352 QScriptValue sc = engine.evaluate("(" + QString(result->readAll()) + ")");
353
354 // "field_version":{"und":[{"value":"0.6a","format":null,"safe_value":"0.6a"}]} //Note the use of [{}] which means it's a array of 1 element with one object inside (so the use of [0] bellow
355
356 QString newVersion = sc.property("field_version").toObject().property("und").toObject().property("0").toObject().property("value").toString();
357
358 if(newVersion!=GlobalVars::AppVersion){
359 Util::showRichPopUp("There's a new version of Vago! (v"+newVersion+")<br/><br/>"+
360 "You can download it <a href='"+GlobalVars::VagoWebUrl+"'>here</a>.");
361 }
362 else{
363 Util::showPopUp("You are using last version.");
364 }
365 }
366 else{
367 UtilVago::showAndLogErrorPopUp(this->myLogger, "An error occurred checking last version:\n\n"+result->errorString());
368 }
369 result->deleteLater();
370}
371
372void MainWindow::on_pbAddSourceXML_clicked()
373{
374 addFilesSource( ui->twSourcesXML,QFileDialog::getOpenFileNames(this,"Choose the files...","./" , "All Files (*.*)"));
375}
376
377void MainWindow::on_pbAddSourceTextures_clicked()
378{
379 addFilesSource( ui->twSourcesTextures, QFileDialog::getOpenFileNames(this,"Choose the files...","./" , "All Files (*.*)"));
380}
381
382void MainWindow::on_pbAddSourceObjects_clicked()
383{
384 addFilesSource( ui->twSourcesObjects,QFileDialog::getOpenFileNames(this,"Choose the files...","./" , "All Files (*.*)"));
385}
386
387void MainWindow::on_pbAddSourceCharacters_clicked()
388{
389 addFilesSource( ui->twSourcesCharacters,QFileDialog::getOpenFileNames(this,"Choose the files...","./" , "All Files (*.*)"));
390}
391
392void MainWindow::on_pbAddSourceLevels_clicked()
393{
394 if(QString::compare(ui->cbFromLevels->currentText(),"ONI FILES",Qt::CaseSensitive)==0 && QString::compare(ui->cbToLevels->currentText(),"DAT",Qt::CaseSensitive)==0){ //CaseSensitive is faster)
395 addFilesSource(ui->twSourcesLevels,Util::multipleDirDialog("Choose folders with ONIs..."));
396 }
397 else{
398 addFilesSource(ui->twSourcesLevels,QFileDialog::getOpenFileNames(this,"Choose the files...","./" , "All Files (*.*)"));
399 }
400}
401
402void MainWindow::on_pbAddSourceMisc_clicked()
403{
404 addFilesSource( ui->twSourcesMisc,QFileDialog::getOpenFileNames(this,"Choose the files...","./" , "All Files (*.*)"));
405}
406
407QString MainWindow::getFileOutputFolder(QString fromTo, QString myOutputFolder){
408
409 if(myOutputFolder==""){ //We may want to change to a non standart location with context menu
410 myOutputFolder=this->outputFolder;
411 }
412
413 if(this->vagoSettings->value("SeparateInWorkspace").toBool() && myOutputFolder==this->workspaceLocation){
414 myOutputFolder+="/"+ui->tabWidget->tabText(ui->tabWidget->currentIndex());
415 myOutputFolder+="/"+QString(fromTo).replace(" / ","_").replace(" > "," - ");
416 }
417 return Util::insertQuotes(myOutputFolder+"/");
418}
419
420void MainWindow::addFilesSource(DropTableWidget *myTable, QStringList files){
421
422 //Get Conversion pretended
423 QString from,to;
424
425 QString fromTo = getTypeConversion(myTable);
426
427 from = QString(fromTo).remove(fromTo.indexOf(" >"),fromTo.size()-1); //parse the string to get the from, only 1 time parsed by each group of files = very fast
428 to = QString(fromTo).remove(0,fromTo.lastIndexOf("> ")+2); //+2 to start after "> "
429
430 //Pre-processing (check if the files/folders received are valid), e.g. check for ONI->DAT if are only given folders and not files
431 if(from=="ONI FILES" && to=="DAT"){
432 //check if it's a folder
433 foreach(QString myFile, files){
434 if(!QDir(myFile).exists()){
435 showErrStatusMessage("Only folders are allowed for this operation.");
436 return;
437 }
438 }
439
440 }
441 else{
442 foreach(QString myFile, files){
443 //check if it's a file
444 if(QDir(myFile).exists()){
445 showErrStatusMessage("Only files are allowed for this operation.");
446 return;
447 }
448 }
449 }
450
451 //Build command
452 QString command, lastFileName;
453
454 QString myOutputFolder=getFileOutputFolder(fromTo);
455
456 //if folder doesn't exist onisplit will create it for us :)
457 foreach(QString currentFile, files){
458
459 currentFile=Util::normalizeAndQuote(currentFile); //insert quotes ("") in file
460
461 if(lastFileName.isEmpty()){ //Optimization: all commands are the same for each file, just replace the filename
462
463 command=getCommand(myTable,myOutputFolder,from,to,currentFile);
464
465 if(command.isEmpty()){ //something wrong was happening (not inputted a texture name?)
466 return; //stop adding files
467 }
468 currentFile=Util::cutName(currentFile);
469 }else{ //one parsing was already made just replace the filename by the old one in the command
470
471 currentFile=Util::cutName(currentFile);
472
473 command.replace(lastFileName,currentFile,Qt::CaseSensitive); //case sentive is faster
474 }
475
476 lastFileName=currentFile;
477
478 addRowTable(myTable,lastFileName,fromTo,command);
479 }
480 updateItemsLoaded(myTable);
481 rowsWereChangedInDropTableWidget();
482}
483
484QString MainWindow::fileParsingXML(QString tabTitle, QString myOutputFolder, QString from, QString to , QString file){
485
486 QString command;
487
488 if(from=="ONI" && to=="XML"){
489 return command=this->commandMap.value(tabTitle+"->"+from+"->"+to)+" "+myOutputFolder+" "+file;
490 }
491 else if(from=="XML" && to=="ONI"){
492 return command=this->commandMap.value(tabTitle+"->"+from+"->"+to)+" "+myOutputFolder+" "+file;
493 }
494
495 return "";
496
497}
498
499QString MainWindow::fileParsingTextures(QString tabTitle, QString myOutputFolder, QString from, QString to , QString file){
500
501 QString command=this->commandMap.value(tabTitle+"->"+from+"->"+to)+" "+myOutputFolder;
502
503 if(ui->gbTextures->isEnabled()){ //faster than compare strings (if is DAT/ONI)
504
505 if(ui->cbMipMapsTextures->isChecked()){
506 command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbMipMapsTextures->text());
507 }
508
509 if(ui->cbNoUwrap->isChecked()){
510 command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbNoUwrap->text());
511 }
512
513 if(ui->cbNoVwrap->isChecked()){
514 command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbNoVwrap->text());
515 }
516
517 if(ui->cbLarge->isChecked()){
518 command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbLarge->text());
519 }
520
521 command+=" "+this->commandMap.value(tabTitle+"->"+getTextureRBCheckedTypeTexture()->text());
522
523 if(ui->cbEnvMap->isChecked()){
524 if(ui->leEnvMapTexture->text().isEmpty()){
525 showErrStatusMessage("Checkbox '"+ui->cbEnvMap->text()+"' is selected. The name texture name cannot be empty.");
526 return "";
527 }
528 command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbEnvMap->text()) + ui->leEnvMapTexture->text().remove(".oni",Qt::CaseInsensitive);
529 }
530 }
531
532 return command+=" "+file; //add source
533}
534
535QString MainWindow::fileParsingCharacters(QString tabTitle, QString myOutputFolder, QString from, QString to , QString file){
536
537 QString command=this->commandMap.value(tabTitle+"->"+from+"->"+to)+" "+myOutputFolder + " " + file ;
538
539
540 if(ui->cbCellShading->isChecked()){
541 command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbCellShading->text());
542 }
543
544 if(ui->cbNormals->isChecked()){
545 command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbNormals->text());
546 }
547
548 if(ui->cbWithTRBS_ONCC->isChecked()){
549 if(ui->leTRBS_ONCC->text().isEmpty()){
550 showErrStatusMessage("Checkbox '"+ui->cbWithTRBS_ONCC->text()+"' is selected. The name cannot be empty.");
551 return "";
552 }
553
554 command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbWithTRBS_ONCC->text())+Util::normalizeAndQuote(ui->leTRBS_ONCC->text());
555 }
556
557 return command;
558}
559
560
561QString MainWindow::fileParsingObjects(QString tabTitle, QString myOutputFolder, QString from, QString to , QString file){
562
563 QString command=this->commandMap.value(tabTitle+"->"+from+"->"+to)+" "+myOutputFolder;
564
565 if(ui->cbTexture->isChecked()){
566 if(ui->leTextureName->text().isEmpty()){
567 showErrStatusMessage("Checkbox '"+ui->cbTexture->text()+"' is selected. The file source cannot be empty.");
568 return "";
569 }
570 command+=" "+this->commandMap.value(tabTitle+"->"+ui->cbTexture->text()) + ui->leTextureName->text();
571 }
572 else if(ui->cbWithAnimation->isChecked()){
573 if(ui->leAnimationName->text().isEmpty()){
574 showErrStatusMessage("Checkbox '"+ui->cbWithAnimation->text()+"' is selected. The file source cannot be empty.");
575 return "";
576 }
577 command+=" "+Util::normalizeAndQuote(ui->leAnimationName->text()) + " " + this->commandMap.value(tabTitle+"->"+ui->cbWithAnimation->text()) + file;
578 return command;
579 }
580
581 if(from=="OBAN ONI (cam)"){
582 command+=" -geom:camera";
583 }
584
585 return command+=" "+file; //add source
586}
587
588QString MainWindow::fileParsingLevels(QString tabTitle, QString myOutputFolder, QString from, QString to , QString file){
589
590 QString datName, command;
591
592 if(!(from=="ONI FILES" && to=="DAT")){ // to all except this one
593
594 command=this->commandMap.value(tabTitle+"->"+from+"->"+to);
595
596 if(ui->cbSpecificFilesLevels->isChecked()){
597
598 if(ui->leSpecificFilesLevels->text().isEmpty()){
599 showErrStatusMessage("Checkbox '"+ui->cbSpecificFilesLevels->text()+"' is selected. The files pattern cannot be empty.");
600 return "";
601 }
602
603 command+=":"+ui->leSpecificFilesLevels->text();
604 }
605
606 if(from=="DAT" && to=="ONI FILES"){ // extract files to a subdir with the files name ex: level0_Final
607 command += " " + myOutputFolder.insert(myOutputFolder.size()-2,QString(Util::cutName(file)).replace(".dat","")) + " " + file;
608 }
609 else{
610 command+=" "+myOutputFolder+" "+file;
611 }
612
613 }
614
615 if((from=="ONI FILES" || from=="MASTER XML") && to=="DAT"){ // almost the same command for both
616 QString datName;
617
618 if(from=="MASTER XML"){
619 command+=GlobalVars::OniSplitProcSeparator; //insert mark so we know this action will take 2 commands
620 }
621
622 if(ui->cbDatLevels->isChecked()){
623 if(ui->leTargetDatLevels->text().isEmpty()){
624 showErrStatusMessage("Checkbox '"+ui->cbDatLevels->text()+"' is selected. The name cannot be empty.");
625 return "";
626 }
627 datName+=QString(myOutputFolder).insert(myOutputFolder.size()-1,ui->leTargetDatLevels->text()); //set name inputted by user
628 if(!ui->leTargetDatLevels->text().toUpper().endsWith(".DAT")){
629 datName.insert(datName.size()-1,".dat"); //append extension if necessary (-1 to maintain final quote)
630 }
631 }
632 else{
633 if(from=="ONI FILES"){
634 datName=QString(myOutputFolder).insert(myOutputFolder.size()-1,Util::cutName(file).remove("/")+".dat"); //if none iputted set the same name of input file
635 }
636 else if(from=="MASTER XML"){
637 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
638 }
639 }
640 if(from=="ONI FILES"){
641 if(ui->actionWindows->isChecked()){ //is target plataform select windows?
642 return command=this->commandMap.value(tabTitle+"->"+from+"->"+to+"(PC)")+" "+ file + " "+datName;
643 }
644 else{
645 return command=this->commandMap.value(tabTitle+"->"+from+"->"+to+"(demoPCMAC)")+" "+ file + " "+datName;
646 }
647 }
648 else if(from=="MASTER XML"){
649 if(ui->actionWindows->isChecked()){ //is target plataform select windows?
650 command+=this->commandMap.value(tabTitle+"->ONI FILES->"+to+"(PC)")+" "+myOutputFolder+" "+datName; //add second command
651 }
652 else{
653 command+=this->commandMap.value(tabTitle+"->ONI FILES->"+to+"(demoPCMAC)")+" "+myOutputFolder+" "+datName; //add second command
654 }
655 }
656 }
657
658 if(ui->cbBnvLevels->isChecked()){
659
660 if(ui->leBnvLevels->text().isEmpty()){
661 showErrStatusMessage("Checkbox '"+ui->cbBnvLevels->text()+"' is selected. The BNV file cannot be empty.");
662 return "";
663 }
664 command+=" "+Util::normalizeAndQuote(ui->leBnvLevels->text());
665 }
666
667 if(ui->cbAdditionalSourcesLevels->isChecked()){
668
669 if(ui->leAdditSourcesLevels->text().isEmpty()){
670 showErrStatusMessage("Checkbox '"+ui->cbAdditionalSourcesLevels->text()+"' is selected. The source files cannot be empty.");
671 return "";
672 }
673
674 QString additionalFiles=ui->leAdditSourcesLevels->text();
675
676 int currentIndex=0, nextIndex=0;
677
678 //parse all files (separated by spaces)
679 while(true){
680 nextIndex=additionalFiles.indexOf(";",currentIndex+1);
681
682 command += " "+Util::normalizeAndQuote(additionalFiles.mid(currentIndex,(nextIndex-currentIndex)));
683
684 if(nextIndex==-1){ //we got to the end, stop parsing
685 break;
686 }
687 currentIndex=nextIndex+1; //update currentIndex +1 for start after the separator
688 }
689 }
690
691 if(ui->cbGridsLevels->isChecked()){
692 command+=GlobalVars::OniSplitProcSeparator+this->commandMap.value(tabTitle+"->"+ui->cbGridsLevels->text())+" "+Util::normalizeAndQuote(ui->leBnvLevels->text())+" "+file+" -out:"+myOutputFolder;
693 }
694
695 return command;
696}
697
698QString MainWindow::fileParsingMisc(QString myOutputFolder, QString from, QString to , QString file){
699 return this->commandMap.value("misc->"+from+"->"+to)+" "+myOutputFolder+" "+file;
700}
701
702void MainWindow::addRowTable(DropTableWidget *myTable, QString fileName, QString fromTo, QString command, bool isToDisabled){
703 //Get actual number rows
704 int twSize=myTable->rowCount();
705
706 //increase the rows for the new item
707 myTable->setRowCount(twSize+1);
708
709 //Add to table and list to
710 QTableWidgetItem *newFile = new QTableWidgetItem(fileName);
711 QTableWidgetItem *newConversion = new QTableWidgetItem(fromTo);
712 QTableWidgetItem *newCommand = new QTableWidgetItem(command);
713
714 if(isToDisabled){
715 myTable->setDisableStyleWidgetItem(newFile);
716 myTable->setDisableStyleWidgetItem(newConversion);
717 myTable->setDisableStyleWidgetItem(newCommand);
718 }
719
720 myTable->setItem(twSize,0,newFile);
721 myTable->setItem(twSize,1,newConversion);
722 myTable->setItem(twSize,2,newCommand);
723
724 myTable->updateTableToolTips(twSize); //Update tool tips
725}
726
727void MainWindow::on_pbConvert_clicked()
728{
729 startConversion();
730}
731
732void MainWindow::startConversion(){
733
734 DropTableWidget* currTable = getCurrentTableWidget();
735
736 bool ready=false;
737 for(int i=0; i<currTable->rowCount(); i++){ //There are items to process?
738 if(currTable->item(i,2)->background()!=currTable->disabledBackStyle){
739 ready=true;
740 break;
741 }
742 }
743
744 if(!ready){
745 showErrStatusMessage("Please add sources to convert first.");
746 return;
747 }
748
749 if(this->myBar->isVisible()){
750 Util::showErrorPopUp("Another conversion is progress. Please wait until it finishes.");
751 return;
752 }
753
754 for(int i=0; i<currTable->rowCount(); i++){
755 //Only process enabled items
756 if(currTable->item(i,2)->background()!=currTable->disabledBackStyle){
757 this->listToProccess.append(currTable->item(i,2)->text());
758 }
759 }
760
761 this->myConverter->start();
762}
763
764void MainWindow::TsetupProgressBar(int max){
765 this->myBar->setValue(0);
766 this->myBar->show();
767 this->myBar->setMaximum(max);
768 ui->tbAbortConversion->show();
769}
770
771void MainWindow::TupdateProgressBar(){
772 this->myBar->setValue(this->myBar->value()+1); //more one task done
773}
774
775void MainWindow::TresultConversion(QString result, int numErrors){
776 QApplication::alert(this); //Show a notification if window is not active
777 this->myBar->hide();
778 ui->tbAbortConversion->hide();
779
780 if(numErrors!=0){
781 QString sNumErrors=QString::number(numErrors);
782 if(numErrors>1){
783 UtilVago::showErrorPopUpLogButton(result+"\n This is the last of "+sNumErrors+" errors.");
784 showErrStatusMessage("Something gone wrong. Check log file ("+sNumErrors+" errors).");
785 }
786 else{
787 UtilVago::showErrorPopUpLogButton(result);
788 showErrStatusMessage("Something gone wrong. Check log file.");
789 }
790 }
791 else{
792 showSuccessStatusMessage("Everything went well!");
793 }
794}
795
796void MainWindow::TconversionAborted(){
797 this->myBar->hide();
798 ui->tbAbortConversion->hide();
799
800 showErrStatusMessage("Conversion was aborted.");
801}
802
803void MainWindow::showErrStatusMessage(QString message){
804
805 QPalette myPalete = QPalette();
806 myPalete.setColor( QPalette::WindowText, QColor(255,0,0));
807 statusBar()->setPalette( myPalete );
808 ui->statusBar->showMessage(message,10000); //display by 10 seconds
809
810}
811
812void MainWindow::showSuccessStatusMessage(QString message){
813
814 QPalette myPalete = QPalette();
815 myPalete.setColor( QPalette::WindowText, QColor(0,150,0));
816 statusBar()->setPalette( myPalete );
817 ui->statusBar->showMessage(message,10000); //display by 10 seconds
818
819}
820
821void MainWindow::mapCommands(){
822 ////////////////////////////////////////////////////////////////////////XML Commands
823 this->commandMap.insert("xml->ONI->XML","-extract:xml");
824 this->commandMap.insert("xml->XML->ONI","-create");
825 //######################General Options
826
827 //Possible Combinations
828 this->commandMap.insertMulti("xml->ONI","XML");
829 this->commandMap.insertMulti("xml->XML","ONI");
830
831 ////////////////////////////////////////////////////////////////////////Textures Commands
832 this->commandMap.insert("textures->DAT / TXMP ONI->DDS","-extract:dds");
833 this->commandMap.insert("textures->DAT / TXMP ONI->TGA","-extract:tga");
834 this->commandMap.insert("textures->DAT / TXMP ONI->PNG","-extract:png");
835 this->commandMap.insert("textures->DAT / TXMP ONI->JPG","-extract:jpg");
836 this->commandMap.insert("textures->TGA / DDS / PNG / JPG->TXMP ONI","-create:txmp");
837 //######################Textures Options
838 this->commandMap.insert("textures->"+ui->rbBGR32->text(),"-format:bgr32");
839 this->commandMap.insert("textures->"+ui->rbBGRA32->text(),"-format:bgra32");
840 this->commandMap.insert("textures->"+ui->rbBGR555->text(),"-format:bgr555");
841 this->commandMap.insert("textures->"+ui->rbBGRA5551->text(),"-format:bgra5551");
842 this->commandMap.insert("textures->"+ui->rbBGRA444->text(),"-format:bgra4444");
843 this->commandMap.insert("textures->"+ui->rbDxt1->text(),"-format:dxt1");
844 this->commandMap.insert("textures->"+ui->cbMipMapsTextures->text(),"-genmipmaps");
845 this->commandMap.insert("textures->"+ui->cbNoUwrap->text(),"-nouwrap");
846 this->commandMap.insert("textures->"+ui->cbNoVwrap->text(),"-novwrap");
847 this->commandMap.insert("textures->"+ui->cbLarge->text(),"-large");
848 this->commandMap.insert("textures->"+ui->cbEnvMap->text(),"-envmap:");
849 //Possible Combinations
850 this->commandMap.insertMulti("textures->DAT / TXMP ONI","TGA");
851 this->commandMap.insertMulti("textures->DAT / TXMP ONI","DDS");
852 this->commandMap.insertMulti("textures->DAT / TXMP ONI","PNG");
853 this->commandMap.insertMulti("textures->DAT / TXMP ONI","JPG");
854 this->commandMap.insertMulti("textures->TGA / DDS / PNG / JPG","TXMP ONI");
855
856 ////////////////////////////////////////////////////////////////////////Characters Commands
857 this->commandMap.insert("characters->TRAM ONI->XML / XML & DAE","-extract:xml");
858 this->commandMap.insert("characters->TRBS / ONCC ONI->DAE","-extract:dae");
859 this->commandMap.insert("characters->TRBS XML->TRBS ONI","-create");
860 this->commandMap.insert("characters->TRBS DAE->TRBS ONI","-create:trbs");
861 this->commandMap.insert("characters->FILM DAT->XML","film2xml");
862
863 //######################Characters Options
864 this->commandMap.insert("characters->"+ui->cbWithTRBS_ONCC->text(),"-anim-body:");
865 this->commandMap.insert("characters->"+ui->cbCellShading->text(),"-cel");
866 this->commandMap.insert("characters->"+ui->cbNormals->text(),"-normals");
867 //Possible Combinations
868 this->commandMap.insertMulti("characters->TRAM ONI","XML / XML & DAE");
869 this->commandMap.insertMulti("characters->TRBS / ONCC ONI","DAE");
870 this->commandMap.insertMulti("characters->DAE","TRBS ONI");
871 this->commandMap.insertMulti("characters->TRBS DAE","TRBS ONI");
872 this->commandMap.insertMulti("characters->TRBS XML","TRBS ONI");
873 this->commandMap.insertMulti("characters->FILM DAT","XML");
874
875 ////////////////////////////////////////////////////////////////////////Objects Commands
876 this->commandMap.insert("objects->M3GM ONI->OBJ","-extract:obj");
877 this->commandMap.insert("objects->M3GM ONI->DAE","-extract:dae");
878 this->commandMap.insert("objects->ONWC ONI->OBJ","-extract:obj");
879 this->commandMap.insert("objects->ONWC ONI->DAE","-extract:dae");
880 this->commandMap.insert("objects->OBAN ONI (cam)->DAE","-extract:dae");
881 this->commandMap.insert("objects->OBJ->M3GM ONI","-create:m3gm");
882 //######################Characters Options
883 this->commandMap.insert("objects->"+ui->cbTexture->text(),"-tex:");
884 this->commandMap.insert("objects->"+ui->cbWithAnimation->text(),"-geom:");
885 //Possible Combinations
886 this->commandMap.insertMulti("objects->M3GM ONI","OBJ");
887 this->commandMap.insertMulti("objects->M3GM ONI","DAE");
888 this->commandMap.insertMulti("objects->ONWC ONI","OBJ");
889 this->commandMap.insertMulti("objects->ONWC ONI","DAE");
890 this->commandMap.insertMulti("objects->OBAN ONI (cam)","DAE");
891 this->commandMap.insertMulti("objects->OBJ","M3GM ONI");
892
893
894 ////////////////////////////////////////////////////////////////////////Levels Commands
895 this->commandMap.insert("levels->DAT->ONI FILES","-export");
896 //this->commandMap.insert("levels->ONI FILES->DAT","-import"); //Not used.
897 this->commandMap.insert("levels->ONI FILES->DAT(PC)","-import:nosep");
898 this->commandMap.insert("levels->ONI FILES->DAT(demoPCMAC)","-import:sep");
899 this->commandMap.insert("levels->AKEV ONI->DAE","-extract:dae");
900 this->commandMap.insert("levels->DAE->AKEV ONI","-create:akev");
901 this->commandMap.insert("levels->MASTER XML->DAT","-create:level");
902 this->commandMap.insert("levels->MASTER XML->ONI FILES","-create:level");
903 //######################Levels Options
904 this->commandMap.insert("levels->"+ui->cbGridsLevels->text(),"-grid:create");
905 //Possible Combinations
906 this->commandMap.insertMulti("levels->DAT","ONI FILES");
907 this->commandMap.insertMulti("levels->ONI FILES","DAT");
908 this->commandMap.insertMulti("levels->AKEV ONI","DAE");
909 this->commandMap.insertMulti("levels->DAE","AKEV ONI");
910 this->commandMap.insertMulti("levels->MASTER XML","DAT");
911 this->commandMap.insertMulti("levels->MASTER XML","ONI FILES");
912
913 ////////////////////////////////////////////////////////////////////////Misc Commands
914 this->commandMap.insert("misc->DAT / SNDD ONI->WAV","-extract:wav");
915 this->commandMap.insert("misc->DAT / SNDD ONI->AIF","-extract:aif");
916 this->commandMap.insert("misc->DAT / SUBT ONI->TXT","-extract:txt");
917 this->commandMap.insert("misc->WAV / AIF->SNDD ONI","-create");
918 this->commandMap.insert("misc->TXT->SUBT ONI","-create:subt");
919 //Possible Combinations
920 this->commandMap.insertMulti("misc->DAT / SNDD ONI","WAV");
921 this->commandMap.insertMulti("misc->DAT / SNDD ONI","AIF");
922 this->commandMap.insertMulti("misc->DAT / SUBT ONI","TXT");
923 this->commandMap.insertMulti("misc->WAV / AIF","SNDD ONI");
924 this->commandMap.insertMulti("misc->TXT","SUBT ONI");
925
926}
927
928void MainWindow::on_cbFromXML_currentIndexChanged(const QString &arg1)
929{
930 updateComboBox(arg1, ui->cbToXML);
931}
932
933
934void MainWindow::on_cbFromTextures_currentIndexChanged(const QString &arg1)
935{
936 updateComboBox(arg1, ui->cbToTextures);
937}
938
939void MainWindow::on_cbFromObjects_currentIndexChanged(const QString &arg1)
940{
941 updateComboBox(arg1, ui->cbToObjects);
942}
943
944void MainWindow::on_cbFromCharacters_currentIndexChanged(const QString &arg1)
945{
946 updateComboBox(arg1, ui->cbToCharacters);
947}
948
949void MainWindow::on_cbFromLevels_currentIndexChanged(const QString &arg1)
950{
951 updateComboBox(arg1, ui->cbToLevels);
952}
953
954void MainWindow::on_cbFromMisc_currentIndexChanged(const QString &arg1)
955{
956 updateComboBox(arg1, ui->cbToMisc);
957}
958
959void MainWindow::updateComboBox(const QString &arg1, QComboBox *comboBox){
960
961 QString identifier;
962
963 if(comboBox == ui->cbToXML){
964 identifier = ui->tabWidget->tabText(XMLTabIndex);
965 }
966 else if(comboBox == ui->cbToTextures){
967 identifier = ui->tabWidget->tabText(TexturesTabIndex);
968
969 //Options are only used for DAT/ONI -> Image
970 if(QString::compare(arg1,"DAT / ONI",Qt::CaseSensitive)==0){ //case sensitive is faster
971 ui->gbTextures->setEnabled(false);
972 }
973 else{
974 ui->gbTextures->setEnabled(true);
975 }
976 }
977 else if(comboBox == ui->cbToCharacters){
978 identifier = ui->tabWidget->tabText(CharactersTabIndex);
979
980 ui->cbWithTRBS_ONCC->setEnabled(false);
981 ui->cbWithTRBS_ONCC->setChecked(false);
982 ui->cbCellShading->setEnabled(false);
983 ui->cbCellShading->setChecked(false);
984 ui->cbNormals->setEnabled(false);
985 ui->cbNormals->setChecked(false);
986//#error add drag and drop to Extract TRAM with TRBS/ONCC
987 if(QString::compare(arg1,"TRAM ONI",Qt::CaseSensitive)==0){ //case sensitive is faster
988 ui->cbWithTRBS_ONCC->setEnabled(true);
989 }
990 else if(QString::compare(arg1,"TRBS DAE",Qt::CaseSensitive)==0){
991 ui->cbNormals->setEnabled(true);
992 ui->cbCellShading->setEnabled(true);
993 }
994
995 }
996 else if(comboBox == ui->cbToObjects){
997 identifier = ui->tabWidget->tabText(ObjectsTabIndex);
998
999 ui->cbTexture->setEnabled(false);
1000 ui->cbTexture->setChecked(false);
1001 ui->cbWithAnimation->setEnabled(false);
1002 ui->cbWithAnimation->setChecked(false);
1003
1004 if(QString::compare(arg1,"M3GM ONI",Qt::CaseSensitive)==0){ //case sensitive is faster
1005 ui->cbWithAnimation->setEnabled(true);
1006 }
1007 else if(QString::compare(arg1,"OBJ",Qt::CaseSensitive)==0){
1008 ui->cbTexture->setEnabled(true);
1009 }
1010 }
1011 else if(comboBox == ui->cbToLevels){
1012 identifier = ui->tabWidget->tabText(LevelsTabIndex);
1013
1014 ui->cbSpecificFilesLevels->setEnabled(false);
1015 ui->cbSpecificFilesLevels->setChecked(false);
1016 ui->cbDatLevels->setEnabled(false);
1017 ui->cbDatLevels->setChecked(false);
1018 ui->cbBnvLevels->setEnabled(false);
1019 ui->cbBnvLevels->setChecked(false);
1020 ui->cbAdditionalSourcesLevels->setEnabled(false);
1021 ui->cbAdditionalSourcesLevels->setChecked(false);
1022 ui->cbGridsLevels->setEnabled(false);
1023 ui->cbGridsLevels->setChecked(false);
1024
1025 if(arg1=="DAT"){ //case sensitive is faster
1026 ui->cbSpecificFilesLevels->setEnabled(true);
1027 }
1028 else if(arg1=="ONI FILES"){ //case sensitive is faster
1029 ui->cbDatLevels->setEnabled(true);
1030 }
1031 else if(arg1=="DAE"){
1032 ui->cbBnvLevels->setEnabled(true);
1033 ui->cbAdditionalSourcesLevels->setEnabled(true);
1034 }
1035 }
1036 else{ // Misc
1037 identifier = ui->tabWidget->tabText(MiscTabIndex);
1038 }
1039
1040 identifier = identifier.toLower(); // get current tab title text (lower case)
1041
1042 comboBox->clear();
1043
1044 QStringList toUpdate=QStringList();
1045
1046 QStringList values=commandMap.values(identifier+"->"+arg1);
1047
1048 for (int i = values.size()-1; i >= 0; i--){ //By defaut MultiItems have the inversed order (http://qt-project.org/doc/qt-4.8/qhash.html#insertMulti)
1049 toUpdate << values.at(i);
1050 }
1051
1052 comboBox->addItems(toUpdate);
1053}
1054
1055
1056void MainWindow::on_actionWindows_triggered()
1057{
1058 ui->actionWindows->setChecked(true);
1059 ui->actionMac_Windows_demo->setChecked(false);
1060}
1061
1062void MainWindow::on_actionMac_Windows_demo_triggered()
1063{
1064 ui->actionMac_Windows_demo->setChecked(true);
1065 ui->actionWindows->setChecked(false);
1066}
1067
1068void MainWindow::on_pbRemoveSourceXML_clicked()
1069{
1070 removeTableContents( ui->twSourcesXML);
1071}
1072
1073void MainWindow::on_pbRemoveSourceTextures_clicked()
1074{
1075 removeTableContents(ui->twSourcesTextures);
1076}
1077
1078void MainWindow::on_pbRemoveSourceObjects_clicked()
1079{
1080 removeTableContents(ui->twSourcesObjects);
1081}
1082
1083void MainWindow::on_pbRemoveSourceCharacters_clicked()
1084{
1085 removeTableContents(ui->twSourcesCharacters);
1086}
1087
1088void MainWindow::on_pbRemoveSourceLevels_clicked()
1089{
1090 removeTableContents(ui->twSourcesLevels);
1091}
1092
1093void MainWindow::on_pbRemoveSourceMisc_clicked()
1094{
1095 removeTableContents(ui->twSourcesMisc);
1096}
1097
1098void MainWindow::on_pbClearSourcesXML_clicked()
1099{
1100 clearTableContents(ui->twSourcesXML);
1101}
1102
1103void MainWindow::on_pbClearSourcesTextures_clicked()
1104{
1105 clearTableContents(ui->twSourcesTextures);
1106}
1107
1108void MainWindow::on_pbClearSourcesObjects_clicked()
1109{
1110 clearTableContents(ui->twSourcesObjects);
1111}
1112
1113void MainWindow::on_pbClearSourcesCharacters_clicked()
1114{
1115 clearTableContents(ui->twSourcesCharacters);
1116}
1117
1118void MainWindow::on_pbClearSourcesLevels_clicked()
1119{
1120 clearTableContents(ui->twSourcesLevels);
1121}
1122
1123void MainWindow::on_pbClearSourcesMisc_clicked()
1124{
1125 clearTableContents(ui->twSourcesMisc);
1126}
1127
1128void MainWindow::removeTableContents(DropTableWidget *myTable){
1129 int size = myTable->selectionModel()->selectedRows().size();
1130
1131 QMessageBox::StandardButton defaultButton = QMessageBox::NoButton; // default button for clear asking question, only customizable in mac os
1132
1133 if(size==0){
1134 Util::showPopUp("Select a row first.");
1135 return;
1136 }
1137
1138#ifdef Q_OS_MAC
1139 if(this->useYesAsDefaultWhenRemovingItems){
1140 defaultButton = QMessageBox::Yes;
1141 }
1142 else{
1143 defaultButton = QMessageBox::No;
1144 }
1145#endif
1146
1147
1148 if(Util::showQuestionPopUp(this,"Are you sure you want to delete the selected rows?",defaultButton)){
1149 for(int i=0; i<size; i++){
1150 //myTable->removeRow(myTable->selectedItems().at(size-i-1)->row());
1151 myTable->removeRow(myTable->selectionModel()->selectedRows().at(size-i-1).row());
1152 }
1153 updateItemsLoaded(myTable);
1154 rowsWereChangedInDropTableWidget();
1155 }
1156}
1157
1158void MainWindow::clearTableContents(DropTableWidget *myTable){
1159
1160 QMessageBox::StandardButton defaultButton = QMessageBox::NoButton; // default button for clear asking question, only customizable in mac os
1161
1162 if(myTable->rowCount()==0){
1163 Util::showPopUp("Nothing to clear.");
1164 return;
1165 }
1166
1167#ifdef Q_OS_MAC
1168 if(this->useYesAsDefaultWhenRemovingItems){
1169 defaultButton = QMessageBox::Yes;
1170 }
1171 else{
1172 defaultButton = QMessageBox::No;
1173 }
1174#endif
1175
1176 if(Util::showQuestionPopUp(this,"Are you sure you want to clear the content?",defaultButton)){
1177 clearTableNoPrompt(myTable);
1178 updateItemsLoaded(myTable);
1179 rowsWereChangedInDropTableWidget();
1180 }
1181
1182}
1183
1184void MainWindow::clearTableNoPrompt(DropTableWidget *myTable){
1185 myTable->clearContents();
1186 myTable->setRowCount(0);
1187}
1188
1189void MainWindow::on_actionPreferences_triggered()
1190{
1191 //Show preferences
1192 Preferences *preferencesWindow = new Preferences(this,this->vagoSettings);
1193 preferencesWindow->exec(); //it destroys itself when finished.
1194}
1195
1196
1197void MainWindow::closeEvent(QCloseEvent *event){
1198 if(this->vagoSettings->value("AskSaveProject").toBool() && this->unsavedChangesExist){
1199 QMessageBox::StandardButton result = askToSaveCurrentProject();
1200 if(result == QMessageBox::StandardButton::Cancel){
1201 event->ignore();
1202 return;
1203 }
1204 }
1205
1206 // Exit application (this will also close all other windows which don't have parent, for instance ManualCommands)
1207 QApplication::quit();
1208}
1209
1210QMessageBox::StandardButton MainWindow::askToSaveCurrentProject(){
1211 QMessageBox::StandardButton result =
1212 Util::showQuestionPopUpWithCancel(this,"There are unsaved changes. Do you want to save the current project?", QMessageBox::StandardButton::Yes);
1213
1214 if(result == QMessageBox::StandardButton::Yes){
1215 on_actionSave_triggered();
1216 }
1217
1218 return result;
1219}
1220
1221void MainWindow::on_cbToLevels_currentIndexChanged(const QString &arg1)
1222{
1223
1224 if(ui->cbFromLevels->currentText()=="MASTER XML" && arg1=="DAT"){
1225 ui->cbDatLevels->setEnabled(true);
1226 }
1227 else if(ui->cbFromLevels->currentText()=="MASTER XML" && arg1=="ONI FILES"){
1228 ui->cbDatLevels->setEnabled(false);
1229 ui->cbDatLevels->setChecked(false);
1230 }
1231
1232}
1233
1234void MainWindow::on_cbDatLevels_toggled(bool checked)
1235{
1236 ui->leTargetDatLevels->setEnabled(checked);
1237}
1238
1239void MainWindow::on_cbBnvLevels_toggled(bool checked)
1240{
1241 ui->leBnvLevels->setEnabled(checked);
1242 ui->cbGridsLevels->setEnabled(checked);
1243 ui->cbGridsLevels->setChecked(checked);
1244 if(checked && !projectIsLoading){
1245 QString file=QFileDialog::getOpenFileName(this,"Choose the BNV.dae file...","./" , "All Files (*.*)");
1246 if(!file.isEmpty()){
1247 ui->leBnvLevels->setText(file);
1248 }
1249 }
1250}
1251
1252void MainWindow::on_cbAdditionalSourcesLevels_toggled(bool checked)
1253{
1254 ui->leAdditSourcesLevels->setEnabled(checked);
1255
1256 if(checked && !projectIsLoading){
1257 QStringList filesSelected=QFileDialog::getOpenFileNames(this,"Choose the additional .dae files...","./" , "All Files (*.*)");
1258 QString filesJoined;
1259 int size=filesSelected.size();
1260
1261 if(!filesSelected.isEmpty()){
1262 for(int i=0; i<size-1; i++){
1263 filesJoined+=filesSelected.at(i)+" ";
1264 }
1265 filesJoined+=filesSelected.at(size-1); //last doesn't have space after
1266 ui->leAdditSourcesLevels->setText(filesJoined);
1267 }
1268
1269 }
1270}
1271
1272void MainWindow::on_cbWithTRBS_ONCC_toggled(bool checked)
1273{
1274 ui->leTRBS_ONCC->setEnabled(checked);
1275}
1276
1277void MainWindow::on_actionCheck_OniSplit_version_triggered()
1278{
1279 QProcess myProcess;
1280 myProcess.setWorkingDirectory(UtilVago::getAppPath());
1281 myProcess.start(UtilVago::getOniSplitExecutable()+" -version");
1282 myProcess.waitForFinished();
1283
1284 QString result=myProcess.readAllStandardOutput();
1285
1286 Util::showPopUp("This Vago version was built with base in OniSplit version "+GlobalVars::BuiltOniSplitVersion+"\n\nCurrent version is:\n"+result.trimmed());
1287}
1288
1289void MainWindow::on_actionCheck_xmlTools_version_triggered()
1290{
1291 QProcess myProcess;
1292 myProcess.setWorkingDirectory(UtilVago::getAppPath());
1293 myProcess.start(UtilVago::getXmlToolsExecutable()+" --version");
1294 myProcess.waitForFinished();
1295 QString result=myProcess.readLine();
1296
1297 Util::showPopUp("This Vago version was built with base in XmlTools version "+GlobalVars::BuiltXmlToolsVersion+"\n\nCurrent version is:\n"+result.trimmed());
1298}
1299
1300/**
1301 Update items loaded
1302**/
1303void MainWindow::on_tabWidget_currentChanged(int)
1304{
1305 updateItemsLoaded(getCurrentTableWidget());
1306}
1307
1308void MainWindow::updateItemsLoaded(DropTableWidget *currentTable){
1309
1310 int numItems=currentTable->rowCount();
1311
1312 this->itemsLoaded->setText(QString().setNum(numItems)+ (numItems==1?" item ":" items ") +"loaded");
1313}
1314
1315void MainWindow::rowsWereChangedInDropTableWidget(){
1316 // We have changed rows, we have now unsaved changes.
1317 if(!this->unsavedChangesExist){
1318 this->unsavedChangesExist = true;
1319 setVagoWindowTitle();
1320 }
1321}
1322
1323void MainWindow::on_tbCommand_clicked()
1324{
1325 //We pass no parent because we want to have an independent window for ManualCommands,
1326 //so we can minimize it or maximize indepently from the MainWindow
1327 ManualCommands *commandsWindow = new ManualCommands();
1328 commandsWindow->show(); //it destroys itself when finished.
1329}
1330
1331void MainWindow::on_actionWorkspace_triggered()
1332{
1333 ui->actionWorkspace->setChecked(true);
1334 ui->actionOther->setChecked(false);
1335 this->outputFolder=this->workspaceLocation;
1336 ui->tbOpenFolder->setToolTip("Open Vago workspace");
1337 showSuccessStatusMessage("Vago is now outputting the NEW items for Vago workspace.");
1338}
1339
1340void MainWindow::on_actionOther_triggered()
1341{
1342 QString newDir=QFileDialog::getExistingDirectory(this,"Choose the folder for output NEW files directly...",this->AeLocation+"/GameDataFolder");
1343 newDir=Util::normalizePath(newDir);
1344
1345 if(newDir.isEmpty()){
1346 ui->actionOther->setChecked(false);
1347 return; //do nothing
1348 }
1349
1350 if(newDir==this->workspaceLocation){
1351 on_actionWorkspace_triggered(); //set it to vago workspace
1352 return;
1353 }
1354
1355 ui->actionOther->setChecked(true);
1356 ui->actionWorkspace->setChecked(false);
1357
1358 this->outputFolder=newDir;
1359
1360 QString newDirName=Util::cutName(newDir);
1361 ui->tbOpenFolder->setToolTip("Open "+newDirName+" output folder");
1362 showSuccessStatusMessage("Vago is now outputting the NEW items for "+newDirName+".");
1363}
1364
1365void MainWindow::on_actionView_log_triggered()
1366{
1367 UtilVago::openLogFile();
1368}
1369
1370void MainWindow::on_actionOpen_AE_folder_triggered()
1371{
1372 QDesktopServices::openUrl(QUrl("file:///"+this->AeLocation));
1373}
1374
1375void MainWindow::on_actionSave_Project_triggered()
1376{
1377
1378 QString filePath = QFileDialog::getSaveFileName(this, tr("Save File"),
1379 this->vagoSettings->value("LastProjectPath").toString(),
1380 tr("Vago project files (*.vgp)"));
1381
1382 if(!filePath.isEmpty()){
1383 saveProjectState(filePath);
1384 }
1385
1386}
1387
1388// New Project
1389void MainWindow::on_actionNew_Project_triggered()
1390{
1391 if(this->vagoSettings->value("AskSaveProject").toBool() && this->unsavedChangesExist){
1392 QMessageBox::StandardButton result = askToSaveCurrentProject();
1393 if(result == QMessageBox::StandardButton::Cancel){
1394 return;
1395 }
1396 }
1397
1398 QList<DropTableWidget*> myTables = getAllTableWidgets();
1399
1400 for(DropTableWidget* const currTable : myTables){
1401 clearTableNoPrompt(currTable);
1402 }
1403
1404 this->lastProjectFilePath=""; // clear last project file path
1405 this->unsavedChangesExist = false;
1406
1407 setVagoWindowTitle(); // update vago title
1408}
1409
1410void MainWindow::on_actionSave_triggered()
1411{
1412 if(this->lastProjectFilePath.isEmpty()){
1413 on_actionSave_Project_triggered();
1414 return;
1415 }
1416
1417 saveProjectState(this->lastProjectFilePath);
1418}
1419
1420void MainWindow::on_actionLoad_Project_triggered()
1421{
1422
1423 QString filePath = QFileDialog::getOpenFileName(this, tr("Load File"),
1424 this->vagoSettings->value("LastProjectPath").toString(),
1425 tr("Vago project files (*.vgp)"));
1426 if(!filePath.isEmpty()){
1427 loadProjectState(filePath);
1428 }
1429}
1430
1431void MainWindow::on_actionProject1_triggered()
1432{
1433 loadProjectState(this->ui->actionProject1->text());
1434}
1435
1436void MainWindow::on_actionProject2_triggered()
1437{
1438 loadProjectState(this->ui->actionProject2->text());
1439}
1440
1441void MainWindow::on_actionProject3_triggered()
1442{
1443 loadProjectState(this->ui->actionProject3->text());
1444}
1445
1446void MainWindow::on_actionProject4_triggered()
1447{
1448 loadProjectState(this->ui->actionProject4->text());
1449}
1450
1451void MainWindow::on_actionProject5_triggered()
1452{
1453 loadProjectState(this->ui->actionProject5->text());
1454}
1455
1456QString MainWindow::getTypeConversion(DropTableWidget *myTable){
1457 QString from,to;
1458
1459 if(myTable==ui->twSourcesXML){
1460 from=ui->cbFromXML->currentText();
1461 to=ui->cbToXML->currentText();
1462 }
1463 else if(myTable==ui->twSourcesTextures){
1464 from=ui->cbFromTextures->currentText();
1465 to=ui->cbToTextures->currentText();
1466 }
1467 else if(myTable==ui->twSourcesObjects){
1468 from=ui->cbFromObjects->currentText();
1469 to=ui->cbToObjects->currentText();
1470 }
1471 else if(myTable==ui->twSourcesCharacters){
1472 from=ui->cbFromCharacters->currentText();
1473 to=ui->cbToCharacters->currentText();
1474 }
1475 else if(myTable==ui->twSourcesLevels){
1476 from=ui->cbFromLevels->currentText();
1477 to=ui->cbToLevels->currentText();
1478 }
1479 else{
1480 from=ui->cbFromMisc->currentText();
1481 to=ui->cbToMisc->currentText();
1482 }
1483
1484 return from + " > " + to;
1485}
1486
1487//Drop table widget context menu
1488void MainWindow::dtContextMenu(DropTableWidget* myTable, QContextMenuEvent *event){
1489 QModelIndex index = myTable->indexAt(event->pos());
1490
1491 //item exists?
1492 if(!index.isValid())
1493 return;
1494
1495 if(myTable->selectionModel()->selectedRows().size()==0){ //No multiple rows selected
1496 myTable->selectRow(myTable->itemAt(event->pos())->row()); //select all the row of the item clicked
1497 }
1498
1499 QList<int> selectedRows = QList<int>();
1500
1501 foreach(QModelIndex rowItem, myTable->selectionModel()->selectedRows()){
1502 selectedRows << rowItem.row();
1503 }
1504
1505 std::unique_ptr<QMenu> menu = std::make_unique<QMenu>();
1506 std::unique_ptr<QAction> copy = std::make_unique<QAction>("Copy",myTable);
1507 std::unique_ptr<QAction> moveUp = std::make_unique<QAction>("Move Up",myTable);
1508 std::unique_ptr<QAction> moveDown = std::make_unique<QAction>("Move Down",myTable);
1509 std::unique_ptr<QAction> changeOptions = std::make_unique<QAction>("Change To Current Options",myTable);
1510 std::unique_ptr<QMenu> changeOutput = std::make_unique<QMenu>("Change Output for:");
1511 std::unique_ptr<QAction> outWorkspace = std::make_unique<QAction>("Workspace",myTable);
1512 std::unique_ptr<QAction> outCurrOutput = std::make_unique<QAction>("Current Output Folder",myTable);
1513 std::unique_ptr<QAction> outOther = std::make_unique<QAction>("Other...",myTable);
1514 std::unique_ptr<QAction> edisable = std::make_unique<QAction>("Enable/Disable",myTable);
1515
1516 menu->addAction(copy.get());
1517 menu->addSeparator();
1518 menu->addAction(moveUp.get());
1519 menu->addAction(moveDown.get());
1520 menu->addSeparator();
1521 menu->addAction(changeOptions.get());
1522 menu->addMenu(changeOutput.get());
1523 changeOutput->addActions(QList<QAction*>() << outWorkspace.get() << outCurrOutput.get() << outOther.get());
1524 menu->addAction(edisable.get());
1525
1526
1527 //if it's in the first row it can't be setted up
1528 if(selectedRows.at(0)==0){
1529 moveUp->setEnabled(false);
1530 }
1531
1532 //if we are at bottom we can't go down
1533 if(selectedRows.at(selectedRows.size()-1)==myTable->rowCount()-1){
1534 moveDown->setEnabled(false);
1535 }
1536
1537 //Can we change the settings? (the conversion must be the same)
1538 QString currentSettings = (getTypeConversion(myTable)); //call function at the mainWindow with a signal (different threads?)
1539 foreach(int row, selectedRows){
1540 if( myTable->item(row,1)->text() != currentSettings){ //If we find out any of the selected items can't be convert disable operation
1541 changeOptions->setEnabled(false);
1542 break;
1543 }
1544 }
1545
1546 QAction* selectedOption = menu->exec(event->globalPos());
1547
1548 if(selectedOption==copy.get()){
1549 //Let's copy the contents to the clipboard
1550
1551 QString toCopy;
1552
1553 int size=selectedRows.size();
1554
1555 //Let's format it a bit...
1556 for(int i=0; i<size; i++){
1557 for(int j=0; j<myTable->columnCount(); j++){
1558 toCopy+=myTable->item(selectedRows.at(i),j)->text();
1559 if(j!=myTable->columnCount()-1){
1560 toCopy+="\t";
1561 }
1562 }
1563 if(i!=size-1){
1564 toCopy+="\n";
1565 }
1566 }
1567
1568 QApplication::clipboard()->setText(toCopy);
1569 showSuccessStatusMessage(QString::number(size) + (size==1?" item ":" items ")+ "copied to the clipboard");
1570 }
1571 else if(selectedOption==moveUp.get()){
1572 qSort(selectedRows); //let's order the selections by the row number, so we know exactly how to swap it
1573 myTable->swapPositions(selectedRows,-1);
1574 rowsWereChangedInDropTableWidget();
1575 }
1576 else if(selectedOption==moveDown.get()){
1577 qSort(selectedRows);
1578 myTable->swapPositions(selectedRows,+1);
1579 rowsWereChangedInDropTableWidget();
1580 }
1581 else if(selectedOption==changeOptions.get()){
1582 changeToCurrentSettings(selectedRows,myTable);
1583 }
1584 else if(selectedOption==outWorkspace.get()){
1585 changeItemsOutput(myTable,selectedRows,this->workspaceLocation);
1586 }
1587 else if(selectedOption==outCurrOutput.get()){
1588 changeItemsOutput(myTable,selectedRows,this->outputFolder);
1589 }
1590 else if(selectedOption==outOther.get()){
1591
1592 QString newDir=QFileDialog::getExistingDirectory(this,"Choose the folder for the output of the files selected...",this->AeLocation+"/GameDataFolder");
1593 newDir=Util::normalizePath(newDir);
1594
1595 if(newDir.isEmpty()){
1596 return; //do nothing
1597 }
1598
1599 changeItemsOutput(myTable,selectedRows,newDir);
1600
1601 }
1602 else if(selectedOption==edisable.get()){
1603
1604 int enabledCount=0, disabledCount=0;
1605
1606 for(int i=0; i<selectedRows.size(); i++){
1607
1608 for(int j=0; j<myTable->columnCount(); j++){
1609 QTableWidgetItem *currentItem=myTable->item(selectedRows.at(i),j);
1610
1611 if(currentItem->background()!=myTable->disabledBackStyle){
1612 myTable->setDisableStyleWidgetItem(currentItem);
1613 if(j==0){ //Only count the row, not the columns
1614 disabledCount++;
1615 }
1616 }
1617 else{ //reset to initial state (enable)
1618 myTable->resetStyleWidgetItem(currentItem);
1619 if(j==0){
1620 enabledCount++;
1621 }
1622 }
1623 }
1624 }
1625
1626 QString result;
1627
1628 if(enabledCount!=0){
1629 result+=QString::number(enabledCount) + (enabledCount==1?" item ":" items ") + "Enabled";
1630 }
1631 if(enabledCount!=0 && disabledCount!=0){
1632 result+=" and ";
1633 }
1634 if(disabledCount!=0){
1635 result+=QString::number(disabledCount) + (disabledCount==1?" item ":" items ") + "Disabled";
1636 }
1637
1638 rowsWereChangedInDropTableWidget();
1639 showSuccessStatusMessage(result);
1640 }
1641}
1642
1643void MainWindow::changeToCurrentSettings(QList<int> rows, DropTableWidget* myTable){
1644 //construct a command for each one
1645 //Output a status message saying the number of changed files
1646 QString fromTo=getTypeConversion(myTable);
1647 QString from = QString(fromTo).remove(fromTo.indexOf(" >"),fromTo.size()-1); //parse the string to get the from, only 1 time parsed by each group of files = very fast
1648 QString to = QString(fromTo).remove(0,fromTo.lastIndexOf("> ")+2); //+2 to start after "> "
1649
1650 QString command;
1651
1652 foreach(int row, rows){
1653
1654 command=getCommand(myTable,getFileOutputFolder(fromTo,myTable->getOutputAbsolute(row)),from,to,myTable->getFileAbsolute(row));
1655
1656 if(command.isEmpty()){ //something wrong was happening (not inputted a texture name?)
1657 return; //stop changing settings
1658 }
1659
1660 myTable->item(row,2)->setText(command); //update settings to the current row
1661 myTable->updateTableToolTips(row);
1662 }
1663
1664 rowsWereChangedInDropTableWidget();
1665 showSuccessStatusMessage(QString::number(rows.size()) + (rows.size()==1?" item ":" items ")+ "changed to the current settings");
1666}
1667
1668void MainWindow::changeItemsOutput(DropTableWidget* myTable, QList<int> rows, QString newOutput){
1669
1670 QString command, currentAbsoluteFile, fromTo, from, to;
1671
1672 foreach(int row, rows){ //No optimization possible here, commands may be different
1673 fromTo=myTable->item(row,1)->text();
1674 from = QString(fromTo).remove(fromTo.indexOf(" >"),fromTo.size()-1); //parse the string to get the from
1675 to = QString(fromTo).remove(0,fromTo.lastIndexOf("> ")+2); //+2 to start after "> "
1676
1677 currentAbsoluteFile=myTable->getFileAbsolute(row);
1678 command=getCommand(myTable,getFileOutputFolder(fromTo,newOutput),from,to,currentAbsoluteFile);
1679
1680 if(command.isEmpty()){ //something wrong was happening (not inputted a texture name?)
1681 return; //stop changing output
1682 }
1683
1684 myTable->item(row,2)->setText(command); //update command to the current row
1685 myTable->updateTableToolTips(row);
1686 }
1687
1688 rowsWereChangedInDropTableWidget();
1689 showSuccessStatusMessage(QString::number(rows.size()) + (rows.size()==1?" item ":" items ")+ "changed the output to "+(newOutput!=this->workspaceLocation?Util::cutName(newOutput):"Vago workspace"));
1690}
1691
1692QString MainWindow::getCommand(DropTableWidget* myTable, QString myOutputFolder, QString from, QString to , QString file){
1693
1694 QString tabTitle=ui->tabWidget->tabText(ui->tabWidget->currentIndex()).toLower(); // get current tab title
1695
1696 if(myTable==ui->twSourcesXML){ //So we only need to parse one command.
1697 return fileParsingXML(tabTitle, myOutputFolder,from,to,file);
1698 }
1699 else if(myTable==ui->twSourcesTextures){
1700 return fileParsingTextures(tabTitle, myOutputFolder,from,to,file);
1701 }
1702 else if(myTable==ui->twSourcesObjects){
1703 return fileParsingObjects(tabTitle, myOutputFolder,from,to,file);
1704 }
1705 else if(myTable==ui->twSourcesCharacters){
1706 return fileParsingCharacters(tabTitle, myOutputFolder,from,to,file);
1707 }
1708 else if(myTable==ui->twSourcesLevels){
1709 return fileParsingLevels(tabTitle, myOutputFolder,from,to,file);
1710 }
1711 else{
1712 return fileParsingMisc(myOutputFolder,from,to,file);
1713 }
1714
1715}
1716
1717void MainWindow::connectSlots(){
1718
1719 //This signal is for thread that is working setup the progress bar (make it visible and set it's min-max)
1720 connect(myConverter, SIGNAL(setupPB(int)), this, SLOT(TsetupProgressBar(int)), Qt::BlockingQueuedConnection);
1721
1722 //This signal is for thread that is working can update the progress bar of the gui
1723 connect(myConverter, SIGNAL(taskDone()), this, SLOT(TupdateProgressBar()),Qt::BlockingQueuedConnection);
1724
1725 //This signal is for thread that is working can show the result of a conversion
1726 connect(myConverter, SIGNAL(resultConversion(QString,int)), this, SLOT(TresultConversion(QString,int)));
1727
1728 //This signal is for thread that is working notify the gui thread that the conversion was aborted with sucess
1729 connect(myConverter, SIGNAL(conversionAborted()), this, SLOT(TconversionAborted()));
1730
1731 // This signal is to the user be able to terminate a conversion (OniSplit process in class myConverter will be terminated)
1732 connect(this, SIGNAL(terminateCurrProcess()), myConverter, SLOT(terminateCurrProcess()));
1733
1734 //Drop signal for General table
1735 connect(ui->twSourcesXML, SIGNAL(dropped(DropTableWidget*,QStringList)), this, SLOT(addFilesSource(DropTableWidget*,QStringList)));
1736
1737 //Drop signal for Textures table
1738 connect(ui->twSourcesTextures, SIGNAL(dropped(DropTableWidget*,QStringList)), this, SLOT(addFilesSource(DropTableWidget*,QStringList)));
1739
1740 //Drop signal for Objects table
1741 connect(ui->twSourcesObjects, SIGNAL(dropped(DropTableWidget*,QStringList)), this, SLOT(addFilesSource(DropTableWidget*,QStringList)));
1742
1743 //Drop signal for Characters table
1744 connect(ui->twSourcesCharacters, SIGNAL(dropped(DropTableWidget*,QStringList)), this, SLOT(addFilesSource(DropTableWidget*,QStringList)));
1745
1746 //Drop signal for Levels table
1747 connect(ui->twSourcesLevels, SIGNAL(dropped(DropTableWidget*,QStringList)), this, SLOT(addFilesSource(DropTableWidget*,QStringList)));
1748
1749 //Drop signal for Misc table
1750 connect(ui->twSourcesMisc, SIGNAL(dropped(DropTableWidget*,QStringList)), this, SLOT(addFilesSource(DropTableWidget*,QStringList)));
1751
1752 //Context menu for General table
1753 connect(ui->twSourcesXML, SIGNAL(dtContextMenu(DropTableWidget*,QContextMenuEvent*)), this, SLOT(dtContextMenu(DropTableWidget*,QContextMenuEvent*)));
1754
1755 //Context menu for Textures table
1756 connect(ui->twSourcesTextures, SIGNAL(dtContextMenu(DropTableWidget*,QContextMenuEvent*)), this, SLOT(dtContextMenu(DropTableWidget*,QContextMenuEvent*)));
1757
1758 //Context menu for Objects table
1759 connect(ui->twSourcesObjects, SIGNAL(dtContextMenu(DropTableWidget*,QContextMenuEvent*)), this, SLOT(dtContextMenu(DropTableWidget*,QContextMenuEvent*)));
1760
1761 //Context menu for Characters table
1762 connect(ui->twSourcesCharacters, SIGNAL(dtContextMenu(DropTableWidget*,QContextMenuEvent*)), this, SLOT(dtContextMenu(DropTableWidget*,QContextMenuEvent*)));
1763
1764 //Context menu for Levels table
1765 connect(ui->twSourcesLevels, SIGNAL(dtContextMenu(DropTableWidget*,QContextMenuEvent*)), this, SLOT(dtContextMenu(DropTableWidget*,QContextMenuEvent*)));
1766
1767 //Context menu for Misc table
1768 connect(ui->twSourcesMisc, SIGNAL(dtContextMenu(DropTableWidget*,QContextMenuEvent*)), this, SLOT(dtContextMenu(DropTableWidget*,QContextMenuEvent*)));
1769}
1770
1771void MainWindow::saveProjectState(const QString &filePath)
1772{
1773
1774 QList<DropTableWidget*> tableWidgets = getAllTableWidgets();
1775
1776 pugi::xml_document doc;
1777
1778 pugi::xml_node rootNode = doc.append_child("VagoProject");
1779 rootNode.append_attribute("vagoVersion").set_value(GlobalVars::LastCompatibleVersion.toUtf8().constData());
1780
1781 foreach(DropTableWidget* const &myTable, tableWidgets){
1782 saveProjectWidget(rootNode, myTable);
1783 }
1784
1785 if(!doc.save_file(filePath.toUtf8().constData(), PUGIXML_TEXT("\t"), pugi::format_default | pugi::format_write_bom, pugi::xml_encoding::encoding_utf8)){
1786 UtilVago::showAndLogErrorPopUpLogButton(this->myLogger, "An error ocurred while trying to save the project file. Please try another path.");
1787 return;
1788 }
1789
1790 this->vagoSettings->setValue("LastProjectPath",QFileInfo(filePath).absoluteDir().path());
1791
1792 this->lastProjectFilePath = filePath;
1793 this->unsavedChangesExist = false;
1794
1795 addNewRecentProject(filePath);
1796
1797 setVagoWindowTitle();
1798
1799 showSuccessStatusMessage("Project saved sucessfully.");
1800}
1801
1802void MainWindow::saveProjectWidget(pugi::xml_node &rootNode, DropTableWidget* table)
1803{
1804 QString from;
1805 QString to;
1806 QString tabName = getTabNameByTableWidget(table);
1807
1808 pugi::xml_node currentNodeTable = rootNode.append_child("tempName");
1809 pugi::xml_node options;
1810
1811 if(table==ui->twSourcesXML){ //So we only need to parse one command.
1812 from = ui->cbFromXML->currentText().toUtf8().constData();
1813 to = ui->cbToXML->currentText().toUtf8().constData();
1814 }
1815 else if(table==ui->twSourcesTextures){
1816 from = ui->cbFromTextures->currentText().toUtf8().constData();
1817 to = ui->cbToTextures->currentText().toUtf8().constData();
1818 options = currentNodeTable.append_child("Options");
1819 options.append_attribute("type").set_value(Util::qStrToCstr(getTextureRBCheckedTypeTexture()->text()));
1820 options.append_attribute("genMipMaps").set_value(Util::boolToCstr(ui->cbMipMapsTextures->isChecked()));
1821 options.append_attribute("noUwrap").set_value(Util::boolToCstr(ui->cbNoUwrap->isChecked()));
1822 options.append_attribute("noVwrap").set_value(Util::boolToCstr(ui->cbNoVwrap->isChecked()));
1823 options.append_attribute("large").set_value(Util::boolToCstr(ui->cbLarge->isChecked()));
1824 options.append_attribute("envMap").set_value(Util::boolToCstr(ui->cbEnvMap->isChecked()));
1825 options.append_attribute("envMapValue").set_value(Util::qStrToCstr(ui->leEnvMapTexture->text()));
1826 }
1827 else if(table==ui->twSourcesCharacters){
1828 from = ui->cbFromCharacters->currentText().toUtf8().constData();
1829 to = ui->cbToCharacters->currentText().toUtf8().constData();
1830 options = currentNodeTable.append_child("Options");
1831 options.append_attribute("cellShading").set_value(Util::boolToCstr(ui->cbCellShading->isChecked()));
1832 options.append_attribute("normals").set_value(Util::boolToCstr(ui->cbNormals->isChecked()));
1833 options.append_attribute("extractTRBSONCC").set_value(Util::boolToCstr(ui->cbWithTRBS_ONCC->isChecked()));
1834 options.append_attribute("extractTRBSONCCValue").set_value(Util::qStrToCstr(ui->leTRBS_ONCC->text()));
1835 }
1836 else if(table==ui->twSourcesObjects){
1837 from = ui->cbFromObjects->currentText().toUtf8().constData();
1838 to = ui->cbToObjects->currentText().toUtf8().constData();
1839 options = currentNodeTable.append_child("Options");
1840 options.append_attribute("texture").set_value(Util::boolToCstr(ui->cbTexture->isChecked()));
1841 options.append_attribute("textureValue").set_value(Util::qStrToCstr(ui->leTextureName->text()));
1842 options.append_attribute("withAnimation").set_value(Util::boolToCstr(ui->cbWithAnimation->isChecked()));
1843 options.append_attribute("withAnimationValue").set_value(Util::qStrToCstr(ui->leAnimationName->text()));
1844 }
1845 else if(table==ui->twSourcesLevels){
1846 from = ui->cbFromLevels->currentText().toUtf8().constData();
1847 to = ui->cbToLevels->currentText().toUtf8().constData();
1848 options = currentNodeTable.append_child("Options");
1849 options.append_attribute("extractWithFiles").set_value(Util::boolToCstr(ui->cbSpecificFilesLevels->isChecked()));
1850 options.append_attribute("extractWithFilesValue").set_value(Util::qStrToCstr(ui->leSpecificFilesLevels->text()));
1851 options.append_attribute("datFilename").set_value(Util::boolToCstr(ui->cbDatLevels->isChecked()));
1852 options.append_attribute("datFilenameValue").set_value(Util::qStrToCstr(ui->leTargetDatLevels->text()));
1853 options.append_attribute("bnvSource").set_value(Util::boolToCstr(ui->cbBnvLevels->isChecked()));
1854 options.append_attribute("bnvSourceValue").set_value(Util::qStrToCstr(ui->leBnvLevels->text()));
1855 options.append_attribute("generateGrids").set_value(Util::boolToCstr(ui->cbGridsLevels->isChecked()));
1856 options.append_attribute("additionalSources").set_value(Util::boolToCstr(ui->cbAdditionalSourcesLevels->isChecked()));
1857 options.append_attribute("additionalSourcesValue").set_value(Util::qStrToCstr(ui->leAdditSourcesLevels->text()));
1858 }
1859 else{
1860 from = ui->cbFromMisc->currentText().toUtf8().constData();
1861 to = ui->cbToMisc->currentText().toUtf8().constData();
1862 }
1863
1864 currentNodeTable.set_name(tabName.toUtf8().constData());
1865
1866 currentNodeTable.append_attribute("from").set_value(from.toUtf8().constData());
1867 currentNodeTable.append_attribute("to").set_value(to.toUtf8().constData());
1868
1869
1870 for(int i=0; i<table->rowCount(); i++){
1871
1872 QString currFileFolder = table->item(i,0)->text();
1873 QString currFromTo = table->item(i,1)->text();
1874 QString currCommand = table->item(i,2)->text();
1875
1876 pugi::xml_node currentRow = currentNodeTable.append_child("Row");
1877
1878
1879 currentRow.append_attribute("fileFolder").set_value(Util::qStrToCstr(currFileFolder));
1880 currentRow.append_attribute("fromTo").set_value(Util::qStrToCstr(currFromTo));
1881 currentRow.append_attribute("command").set_value(Util::qStrToCstr(currCommand));
1882
1883 if(table->item(i,2)->background()==table->disabledBackStyle){
1884 currentRow.append_attribute("disabled").set_value(true);
1885 }
1886
1887 }
1888}
1889
1890QRadioButton* MainWindow::getTextureRBCheckedTypeTexture()
1891{
1892 if(ui->rbBGR32->isChecked()){
1893 return ui->rbBGR32;
1894 }
1895 else if(ui->rbBGRA32->isChecked()){
1896 return ui->rbBGRA32;
1897 }
1898 else if(ui->rbBGR555->isChecked()){
1899 return ui->rbBGR555;
1900 }
1901 else if(ui->rbBGRA5551->isChecked()){
1902 return ui->rbBGRA5551;
1903 }
1904 else if(ui->rbBGRA444->isChecked()){
1905 return ui->rbBGRA444;
1906 }
1907 else{ //dxt1 checked
1908 return ui->rbDxt1;
1909 }
1910}
1911
1912QRadioButton* MainWindow::getTextureRBTypeTextureByName(const QString &texType)
1913{
1914 if(QString::compare(texType,ui->rbBGR32->text(),Qt::CaseSensitive)==0){
1915 return ui->rbBGR32;
1916 }
1917 else if(QString::compare(texType,ui->rbBGRA32->text(),Qt::CaseSensitive)==0){
1918 return ui->rbBGRA32;
1919 }
1920 else if(QString::compare(texType, ui->rbBGR555->text(),Qt::CaseSensitive)==0){
1921 return ui->rbBGR555;
1922 }
1923 else if(QString::compare(texType,ui->rbBGRA5551->text(),Qt::CaseSensitive)==0){
1924 return ui->rbBGRA5551;
1925 }
1926 else if(QString::compare(texType,ui->rbBGRA444->text(),Qt::CaseSensitive)==0){
1927 return ui->rbBGRA444;
1928 }
1929 else{ //dxt1
1930 return ui->rbDxt1;
1931 }
1932
1933}
1934
1935void MainWindow::setVagoWindowTitle(){
1936
1937 QString vagoTitle = "Vago v"+GlobalVars::AppVersion + " - ";
1938
1939 if(this->lastProjectFilePath.isEmpty()){
1940 vagoTitle += "Untitled";
1941 }
1942 else{
1943 vagoTitle += Util::cutNameWithoutBackSlash(this->lastProjectFilePath);
1944 }
1945
1946 if(this->unsavedChangesExist){
1947 vagoTitle += "*";
1948 }
1949
1950 setWindowTitle(vagoTitle);
1951}
1952
1953DropTableWidget* MainWindow::getCurrentTableWidget(){
1954
1955 return getTableWidgetByTabName(ui->tabWidget->tabText(ui->tabWidget->currentIndex()));
1956
1957}
1958
1959DropTableWidget* MainWindow::getTableWidgetByTabName(const QString &tabName){
1960
1961 if(tabName.compare("XML",Qt::CaseSensitive)==0){ //case sentive is faster
1962 return ui->twSourcesXML;
1963 }
1964 else if(tabName.compare("Textures",Qt::CaseSensitive)==0){
1965 return ui->twSourcesTextures;
1966 }
1967 else if(tabName.compare("Characters",Qt::CaseSensitive)==0){
1968 return ui->twSourcesCharacters;
1969 }
1970 else if(tabName.compare("Objects",Qt::CaseSensitive)==0){
1971 return ui->twSourcesObjects;
1972 }
1973 else if(tabName.compare("Levels",Qt::CaseSensitive)==0){
1974 return ui->twSourcesLevels;
1975 }
1976 else{
1977 return ui->twSourcesMisc;
1978 }
1979
1980}
1981
1982QString MainWindow::getCurrentTabName(){
1983 return ui->tabWidget->tabText(ui->tabWidget->currentIndex());
1984}
1985
1986QString MainWindow::getTabNameByTableWidget(DropTableWidget* table){
1987
1988 if(table == ui->twSourcesXML){
1989 return ui->tabWidget->tabText(XMLTabIndex);
1990 }
1991 else if(table == ui->twSourcesTextures){
1992 return ui->tabWidget->tabText(TexturesTabIndex);
1993 }
1994 else if(table == ui->twSourcesCharacters){
1995 return ui->tabWidget->tabText(CharactersTabIndex);
1996 }
1997 else if(table == ui->twSourcesObjects){
1998 return ui->tabWidget->tabText(ObjectsTabIndex);
1999 }
2000 else if(table == ui->twSourcesLevels){
2001 return ui->tabWidget->tabText(LevelsTabIndex);
2002 }
2003 else{
2004 return ui->tabWidget->tabText(MiscTabIndex);
2005 }
2006
2007}
2008
2009QList<DropTableWidget*> MainWindow::getAllTableWidgets()
2010{
2011 QList<DropTableWidget*> tableWidgets;
2012
2013 tableWidgets << ui->twSourcesXML << ui->twSourcesTextures << ui->twSourcesCharacters
2014 << ui->twSourcesObjects << ui->twSourcesLevels << ui->twSourcesMisc;
2015
2016 return tableWidgets;
2017}
2018
2019void MainWindow::loadProjectState(const QString &filePath)
2020{
2021
2022 this->projectIsLoading = true;
2023
2024 if(this->vagoSettings->value("AskSaveProject").toBool() && this->unsavedChangesExist){
2025 QMessageBox::StandardButton result = askToSaveCurrentProject();
2026 if(result == QMessageBox::StandardButton::Cancel){
2027 this->projectIsLoading = false;
2028 return;
2029 }
2030 }
2031
2032 QString statusError = "Couldn't load project.";
2033
2034 pugi::xml_document doc;
2035
2036 pugi::xml_parse_result result = doc.load_file(Util::qStrToCstr(filePath));
2037
2038 if(result.status!=pugi::status_ok){
2039 UtilVago::showAndLogErrorPopUpLogButton(this->myLogger, "An error ocurred while loading project file.\n" + QString(result.description()));
2040 showErrStatusMessage(statusError);
2041 this->projectIsLoading = false;
2042 return;
2043 }
2044
2045
2046 if(QString(doc.root().first_child().name()) != "VagoProject"){
2047 UtilVago::showAndLogErrorPopUpLogButton(this->myLogger, QString(doc.root().name()) + "The file opened is not a valid VagoProject file. Load aborted.");
2048 showErrStatusMessage(statusError);
2049 this->projectIsLoading = false;
2050 return;
2051 }
2052
2053 QString projVagoVersion;
2054
2055 try{
2056 projVagoVersion = QString(doc.select_node("/VagoProject/@vagoVersion").attribute().value());
2057 }
2058 catch (const pugi::xpath_exception& e)
2059 {
2060 UtilVago::showAndLogErrorPopUpLogButton(this->myLogger, "Couldn't find the vagoVersion of the current project. Load aborted.\n" + QString(e.what()));
2061 showErrStatusMessage(statusError);
2062 this->projectIsLoading = false;
2063 return;
2064 }
2065
2066 if(!projVagoVersion.startsWith(GlobalVars::LastCompatibleVersion)){
2067 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.");
2068 showErrStatusMessage(statusError);
2069 this->projectIsLoading = false;
2070 return;
2071 }
2072
2073 // After the initial validations begin loading the project data
2074
2075 QList<DropTableWidget*> tableWidgets = getAllTableWidgets();
2076
2077 try{
2078 foreach(DropTableWidget* const &myTable, tableWidgets){
2079 loadProjectWidget(doc, myTable);
2080 }
2081 }
2082 catch(const std::exception& e){
2083 UtilVago::showAndLogErrorPopUpLogButton(this->myLogger, "Couldn't load the vago project. Error: " + QString(e.what()));
2084 showErrStatusMessage(statusError);
2085 this->projectIsLoading = false;
2086 return;
2087 }
2088
2089 this->vagoSettings->setValue("LastProjectPath",QFileInfo(filePath).absoluteDir().path());
2090
2091 this->lastProjectFilePath = filePath;
2092 this->unsavedChangesExist = false;
2093
2094 addNewRecentProject(filePath);
2095
2096 setVagoWindowTitle();
2097
2098 this->projectIsLoading = false;
2099
2100 showSuccessStatusMessage("Project loaded sucessfully.");
2101}
2102
2103
2104void MainWindow::loadProjectWidget(pugi::xml_document &doc, DropTableWidget* table)
2105{
2106 QString tabName = getTabNameByTableWidget(table);
2107 QString from (doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/@from")).attribute().value());
2108 QString to (doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/@to")).attribute().value());
2109
2110 if(table==ui->twSourcesXML){
2111 ui->cbFromXML->setCurrentText(from);
2112 on_cbFromXML_currentIndexChanged(from);
2113 ui->cbToXML->setCurrentText(to);
2114 }
2115 else if(table==ui->twSourcesTextures){
2116 //ui->cbFromTextures->setCurrentText(from);
2117 on_cbFromTextures_currentIndexChanged(from);
2118 ui->cbToTextures->setCurrentText(to);
2119
2120 getTextureRBTypeTextureByName((doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@type")).attribute().value()))->setChecked(true);
2121 ui->cbMipMapsTextures->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@genMipMaps")).attribute().as_bool());
2122 ui->cbNoUwrap->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@noUwrap")).attribute().as_bool());
2123 ui->cbNoVwrap->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@noVwrap")).attribute().as_bool());
2124 ui->cbLarge->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@large")).attribute().as_bool());
2125 ui->cbEnvMap->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@envMap")).attribute().as_bool());
2126 ui->leEnvMapTexture->setText(QString(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@envMapValue")).attribute().value()));
2127 }
2128 else if(table==ui->twSourcesCharacters){
2129 ui->cbFromCharacters->setCurrentText(from);
2130 on_cbFromCharacters_currentIndexChanged(from);
2131 ui->cbToCharacters->setCurrentText(to);
2132
2133
2134 ui->cbCellShading->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@cellShading")).attribute().as_bool());
2135 ui->cbNormals->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@normals")).attribute().as_bool());
2136 ui->cbWithTRBS_ONCC->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@extractTRBSONCC")).attribute().as_bool());
2137 ui->leTRBS_ONCC->setText(QString(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@extractTRBSONCCValue")).attribute().value()));
2138 }
2139 else if(table==ui->twSourcesObjects){
2140 ui->cbFromObjects->setCurrentText(from);
2141 on_cbFromObjects_currentIndexChanged(from);
2142 ui->cbToObjects->setCurrentText(to);
2143
2144 ui->cbTexture->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@texture")).attribute().as_bool());
2145 ui->leTextureName->setText(QString(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@textureValue")).attribute().value()));
2146 ui->cbWithAnimation->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@withAnimation")).attribute().as_bool());
2147 ui->leAnimationName->setText(QString(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@withAnimationValue")).attribute().value()));
2148 }
2149 else if(table==ui->twSourcesLevels){
2150 ui->cbFromLevels->setCurrentText(from);
2151 on_cbFromLevels_currentIndexChanged(from);
2152 ui->cbToLevels->setCurrentText(to);
2153
2154 ui->cbSpecificFilesLevels->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@extractWithFiles")).attribute().as_bool());
2155 ui->leSpecificFilesLevels->setText(QString(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@extractWithFilesValue")).attribute().value()));
2156 ui->cbDatLevels->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@datFilename")).attribute().as_bool());
2157 ui->leTargetDatLevels->setText(QString(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@datFilenameValue")).attribute().value()));
2158 ui->cbBnvLevels->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@bnvSource")).attribute().as_bool());
2159 ui->leBnvLevels->setText(QString(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@bnvSourceValue")).attribute().value()));
2160 ui->cbGridsLevels->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@generateGrids")).attribute().as_bool());
2161 ui->cbAdditionalSourcesLevels->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@additionalSources")).attribute().as_bool());
2162 ui->leAdditSourcesLevels->setText(QString(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@additionalSourcesValue")).attribute().value()));
2163 }
2164 else{
2165 ui->cbFromMisc->setCurrentText(from);
2166 on_cbFromMisc_currentIndexChanged(from);
2167 ui->cbToMisc->setCurrentText(to);
2168 }
2169
2170 // Clean previous rows
2171 clearTableNoPrompt(table);
2172
2173 for(const pugi::xpath_node &xPathNode : doc.select_nodes(Util::qStrToCstr("/VagoProject/"+tabName+"/Row"))){
2174 pugi::xml_node currNode = xPathNode.node();
2175
2176 QString currFileFolder = currNode.attribute("fileFolder").value();
2177 QString currFromTo = currNode.attribute("fromTo").value();
2178 QString currCommand = currNode.attribute("command").value();
2179
2180 bool isToDisable = false;
2181 pugi::xml_attribute disabledAttr = currNode.attribute("disabled");
2182 isToDisable = disabledAttr.empty() ? false : disabledAttr.as_bool();
2183
2184 addRowTable(table,currFileFolder,currFromTo,currCommand, isToDisable);
2185 }
2186}
2187
2188void MainWindow::saveRecentProjects(){
2189 for(int i=0; i<this->recentProjectsList.size(); i++){
2190 this->vagoSettings->setValue("RecentProject" + QString::number(i+1), recentProjectsList[i]);
2191 }
2192}
2193
2194void MainWindow::loadRecentProjects(){
2195 for(int i=0; i<this->recentProjectsMaxSize; i++){
2196
2197 QString currProj = this->vagoSettings->value("RecentProject" + QString::number(i+1)).toString();
2198
2199 if(!currProj.isEmpty()){
2200 recentProjectsList.append(currProj);
2201 }
2202 else{
2203 break;
2204 }
2205 }
2206
2207 reloadRecentProjectsMenu();
2208
2209}
2210
2211void MainWindow::addNewRecentProject(const QString &filePath){
2212
2213 // If the new project is equal to the last one simply ignore
2214 if(filePath == this->vagoSettings->value("RecentProject1").toString()){
2215 return;
2216 }
2217
2218 // If the item already exists in our list remove it, so it can go to the top again
2219 for(auto it = this->recentProjectsList.begin(); it != this->recentProjectsList.end();){
2220 if(*it == filePath){
2221 it = this->recentProjectsList.erase(it);
2222 }
2223 else{
2224 it++;
2225 }
2226 }
2227
2228 // if we gonna overflow our list, remove the older item to reserve space to the new one
2229 if(this->recentProjectsList.size()==this->recentProjectsMaxSize){
2230 this->recentProjectsList.removeLast();
2231 }
2232
2233 this->vagoSettings->setValue("LastProjectPath",QFileInfo(filePath).absoluteDir().path());
2234
2235 // add new recent file
2236 this->recentProjectsList.prepend(filePath);
2237
2238 reloadRecentProjectsMenu();
2239
2240 saveRecentProjects();
2241}
2242
2243void MainWindow::reloadRecentProjectsMenu(){
2244
2245 ui->menuRecent_Projects->setEnabled(false);
2246 ui->actionProject1->setVisible(false);
2247 ui->actionProject2->setVisible(false);
2248 ui->actionProject3->setVisible(false);
2249 ui->actionProject4->setVisible(false);
2250 ui->actionProject5->setVisible(false);
2251
2252 {
2253 QList<QString>::const_iterator it;
2254 int i;
2255 for(it = recentProjectsList.cbegin(), i=0; it != recentProjectsList.cend(); it++, i++){
2256
2257 QAction* currAction = nullptr;
2258
2259 switch (i){
2260 case 0:
2261 currAction = ui->actionProject1;
2262 break;
2263 case 1:
2264 currAction = ui->actionProject2;
2265 break;
2266 case 2:
2267 currAction = ui->actionProject3;
2268 break;
2269 case 3:
2270 currAction = ui->actionProject4;
2271 break;
2272 case 4:
2273 currAction = ui->actionProject5;
2274 break;
2275 }
2276
2277 if(currAction){
2278 ui->menuRecent_Projects->setEnabled(true);
2279 currAction->setText(*it);
2280 currAction->setVisible(true);
2281 }
2282 }
2283 }
2284
2285}
Note: See TracBrowser for help on using the repository browser.