source: s10k/Vago/mainwindow.cpp@ 1098

Last change on this file since 1098 was 1093, checked in by s10k, 7 years ago

Vago 1.4

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