--- Vago/trunk/Vago/mainwindow.cpp 2016/09/16 22:51:26 1047 +++ Vago/trunk/Vago/mainwindow.cpp 2016/10/30 14:42:39 1058 @@ -16,12 +16,12 @@ MainWindow::MainWindow(QWidget *parent) setVagoWindowTitle(); - if(!QFile::exists(UtilVago::getOniSplitExeAbsolutePath())){ + if(!QFile::exists(UtilVago::getOniSplitExecutableAbsolutePath())){ 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."); exit(1); } - if(!QFile::exists(UtilVago::getXmlToolsExeAbsolutePath())){ + if(!QFile::exists(UtilVago::getXmlToolsExecutableAbsolutePath())){ 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."); exit(1); } @@ -71,8 +71,12 @@ MainWindow::MainWindow(QWidget *parent) this->vagoSettings->setValue("SeparateInWorkspace",true); iniChanged=true; } - if(!this->vagoSettings->contains("ConfirmExit")){ - this->vagoSettings->setValue("ConfirmExit", false); + if(!this->vagoSettings->contains("AskSaveProject")){ + this->vagoSettings->setValue("AskSaveProject", true); + iniChanged=true; + } + if(!this->vagoSettings->contains("AskToOpenLastProject")){ + this->vagoSettings->setValue("AskToOpenLastProject", false); iniChanged=true; } if(!this->vagoSettings->contains("LastProjectPath")){ @@ -124,9 +128,6 @@ MainWindow::MainWindow(QWidget *parent) ui->statusBar->addPermanentWidget(this->myBar); //this adds automatically in right ui->statusBar->addPermanentWidget(ui->tbAbortConversion); - //Initialize list pointers - this->listToProccess = new QStringList; - // User interface ui->mainToolBar->addWidget(ui->tbAE); //add ae installer launch button ui->mainToolBar->addWidget(ui->emptySpacerLabel); //trick, we can't add directly a space so we add an empty @@ -134,6 +135,8 @@ MainWindow::MainWindow(QWidget *parent) ui->mainToolBar->addWidget(ui->emptySpacerLabel2); //same as before ui->mainToolBar->addWidget(ui->tbCommand); //add option to manual onisplit commands ui->mainToolBar->addWidget(ui->emptySpacerLabel3); //same as before + ui->mainToolBar->addWidget(ui->tbXmlToolsInterface); //add option to manual onisplit commands + ui->mainToolBar->addWidget(ui->emptySpacerLabel4); //same as before ui->mainToolBar->addWidget(ui->tbOpenFolder); //add option to open folder with files converted etc ui->mainToolBar->setLayoutDirection(Qt::RightToLeft); @@ -179,7 +182,20 @@ MainWindow::~MainWindow() void MainWindow::showEvent(QShowEvent *e) { - #ifdef Q_OS_WIN + // If we don't have a converter yet, application wasn't started. + if(!this->applicationIsFullyLoaded) + { + // Apparently Qt doesn't contains a slot to when the application was fully load (mainwindow). So we do our own implementation instead. + connect(this, SIGNAL(signalAppIsLoaded()), this, SLOT(applicationWasLoaded()), Qt::ConnectionType::QueuedConnection); + emit signalAppIsLoaded(); + } + + e->accept(); +} + +// Called only when the MainWindow was fully loaded and painted on the screen. This slot is only called once. +void MainWindow::applicationWasLoaded(){ +#ifdef Q_OS_WIN // QProgressBar only works after the windows was shown // http://stackoverflow.com/questions/24840941/qwintaskbarprogress-wont-show (Kervala answer) @@ -190,16 +206,24 @@ void MainWindow::showEvent(QShowEvent *e this->win7TaskBarProgress = this->win7TaskBarButton->progress(); //Create a thread for do the conversion in background - this->myConverter = new Converter(UtilVago::getAppPath(), this->myLogger, this->listToProccess, this->win7TaskBarProgress); - #else - this->myConverter = new Converter(UtilVago::getAppPath(), this->myLogger, this->listToProccess); - #endif + this->myConverter = new Converter(UtilVago::getAppPath(), this->myLogger, &this->listToProccess, this->win7TaskBarProgress); +#else + this->myConverter = new Converter(UtilVago::getAppPath(), this->myLogger, &this->listToProccess); +#endif connectSlots(); this->myLogger->writeString("Application started."); - e->accept(); + this->applicationIsFullyLoaded = true; + + QString lastSavedProject = this->vagoSettings->value("RecentProject1").toString(); + + if(!lastSavedProject.isEmpty() && this->vagoSettings->value("AskToOpenLastProject").toBool()){ + if(Util::showQuestionPopUp(this,"Do you want to load latest project?\n\nLatest project was '" + Util::cutNameWithoutBackSlash(lastSavedProject) + "'.")){ + loadProjectState(lastSavedProject); + } + } } @@ -227,6 +251,12 @@ void MainWindow::on_actionSound_Wizard_t myWizard.exec(); } +void MainWindow::on_actionBackground_Image_Wizard_triggered() +{ + BGImageWizard myWizard (UtilVago::getAppPath(), this->workspaceWizardsLocation, this->vagoSettings, this->myLogger); + myWizard.exec(); +} + void MainWindow::on_tbOni_clicked() { QStringList arguments; @@ -261,6 +291,15 @@ void MainWindow::on_tbOpenFolder_clicked QDesktopServices::openUrl(QUrl("file:///"+this->outputFolder)); } + +void MainWindow::on_tbXmlToolsInterface_clicked() +{ + //We pass no parent because we want to have an independent window for XmlToolsInterface, + //so we can minimize it or maximize indepently from the MainWindow + XmlToolsInterface *xmlToolsWindow = new XmlToolsInterface(this->myLogger); + xmlToolsWindow->show(); //it destroys itself when finished. +} + void MainWindow::on_tbAbortConversion_clicked() { if(Util::showQuestionPopUp(this,"Are you sure you want to abort the current conversion?")){ @@ -433,6 +472,7 @@ void MainWindow::addFilesSource(DropTabl addRowTable(myTable,lastFileName,fromTo,command); } updateItemsLoaded(myTable); + rowsWereChangedInDropTableWidget(); } QString MainWindow::fileParsingXML(QString tabTitle, QString myOutputFolder, QString from, QString to , QString file){ @@ -709,7 +749,7 @@ void MainWindow::startConversion(){ for(int i=0; irowCount(); i++){ //Only process enabled items if(currTable->item(i,2)->background()!=currTable->disabledBackStyle){ - this->listToProccess->append(currTable->item(i,2)->text()); + this->listToProccess.append(currTable->item(i,2)->text()); } } @@ -735,14 +775,13 @@ void MainWindow::TresultConversion(QStri if(numErrors!=0){ QString sNumErrors=QString::number(numErrors); if(numErrors>1){ - UtilVago::showErrorPopUpLogButton(result+"\n This is the last of "+sNumErrors+" Errors."); - showErrStatusMessage("Something gone wrong. Check log file ("+sNumErrors+" Errors)."); + UtilVago::showErrorPopUpLogButton(result+"\n This is the last of "+sNumErrors+" errors."); + showErrStatusMessage("Something gone wrong. Check log file ("+sNumErrors+" errors)."); } else{ UtilVago::showErrorPopUpLogButton(result); showErrStatusMessage("Something gone wrong. Check log file."); } - } else{ showSuccessStatusMessage("Everything went well!"); @@ -1107,6 +1146,7 @@ void MainWindow::removeTableContents(Dro myTable->removeRow(myTable->selectionModel()->selectedRows().at(size-i-1).row()); } updateItemsLoaded(myTable); + rowsWereChangedInDropTableWidget(); } } @@ -1130,8 +1170,10 @@ void MainWindow::clearTableContents(Drop if(Util::showQuestionPopUp(this,"Are you sure you want to clear the content?",defaultButton)){ clearTableNoPrompt(myTable); + updateItemsLoaded(myTable); + rowsWereChangedInDropTableWidget(); } - updateItemsLoaded(myTable); + } void MainWindow::clearTableNoPrompt(DropTableWidget *myTable){ @@ -1148,11 +1190,27 @@ void MainWindow::on_actionPreferences_tr void MainWindow::closeEvent(QCloseEvent *event){ - if(this->vagoSettings->value("ConfirmExit").toBool()){ - if(!Util::showQuestionPopUp(this,"Exit Vago?")){ + if(this->vagoSettings->value("AskSaveProject").toBool() && this->unsavedChangesExist){ + QMessageBox::StandardButton result = askToSaveCurrentProject(); + if(result == QMessageBox::StandardButton::Cancel){ event->ignore(); + return; } } + + // Exit application (this will also close all other windows which don't have parent, for instance ManualCommands) + QApplication::quit(); +} + +QMessageBox::StandardButton MainWindow::askToSaveCurrentProject(){ + QMessageBox::StandardButton result = + Util::showQuestionPopUpWithCancel(this,"There are unsaved changes. Do you want to save the current project?", QMessageBox::StandardButton::Yes); + + if(result == QMessageBox::StandardButton::Yes){ + on_actionSave_triggered(); + } + + return result; } void MainWindow::on_cbToLevels_currentIndexChanged(const QString &arg1) @@ -1178,7 +1236,7 @@ void MainWindow::on_cbBnvLevels_toggled( ui->leBnvLevels->setEnabled(checked); ui->cbGridsLevels->setEnabled(checked); ui->cbGridsLevels->setChecked(checked); - if(checked){ + if(checked && !projectIsLoading){ QString file=QFileDialog::getOpenFileName(this,"Choose the BNV.dae file...","./" , "All Files (*.*)"); if(!file.isEmpty()){ ui->leBnvLevels->setText(file); @@ -1190,7 +1248,7 @@ void MainWindow::on_cbAdditionalSourcesL { ui->leAdditSourcesLevels->setEnabled(checked); - if(checked){ + if(checked && !projectIsLoading){ QStringList filesSelected=QFileDialog::getOpenFileNames(this,"Choose the additional .dae files...","./" , "All Files (*.*)"); QString filesJoined; int size=filesSelected.size(); @@ -1215,7 +1273,7 @@ void MainWindow::on_actionCheck_OniSplit { QProcess myProcess; myProcess.setWorkingDirectory(UtilVago::getAppPath()); - myProcess.start(UtilVago::getOniSplitExeAbsolutePath()+" -version"); + myProcess.start(UtilVago::getOniSplitExecutable()+" -version"); myProcess.waitForFinished(); QString result=myProcess.readAllStandardOutput(); @@ -1227,7 +1285,7 @@ void MainWindow::on_actionCheck_xmlTools { QProcess myProcess; myProcess.setWorkingDirectory(UtilVago::getAppPath()); - myProcess.start(UtilVago::getXmlToolsExeAbsolutePath()+" --version"); + myProcess.start(UtilVago::getXmlToolsExecutable()+" --version"); myProcess.waitForFinished(); QString result=myProcess.readLine(); @@ -1249,10 +1307,19 @@ void MainWindow::updateItemsLoaded(DropT this->itemsLoaded->setText(QString().setNum(numItems)+ (numItems==1?" item ":" items ") +"loaded"); } +void MainWindow::rowsWereChangedInDropTableWidget(){ + // We have changed rows, we have now unsaved changes. + if(!this->unsavedChangesExist){ + this->unsavedChangesExist = true; + setVagoWindowTitle(); + } +} + void MainWindow::on_tbCommand_clicked() { - //Show preferences - ManualCommands *commandsWindow = new ManualCommands(this); + //We pass no parent because we want to have an independent window for ManualCommands, + //so we can minimize it or maximize indepently from the MainWindow + ManualCommands *commandsWindow = new ManualCommands(); commandsWindow->show(); //it destroys itself when finished. } @@ -1313,6 +1380,28 @@ void MainWindow::on_actionSave_Project_t } +// New Project +void MainWindow::on_actionNew_Project_triggered() +{ + if(this->vagoSettings->value("AskSaveProject").toBool() && this->unsavedChangesExist){ + QMessageBox::StandardButton result = askToSaveCurrentProject(); + if(result == QMessageBox::StandardButton::Cancel){ + return; + } + } + + QList myTables = getAllTableWidgets(); + + for(DropTableWidget* const currTable : myTables){ + clearTableNoPrompt(currTable); + } + + this->lastProjectFilePath=""; // clear last project file path + this->unsavedChangesExist = false; + + setVagoWindowTitle(); // update vago title +} + void MainWindow::on_actionSave_triggered() { if(this->lastProjectFilePath.isEmpty()){ @@ -1477,10 +1566,12 @@ void MainWindow::dtContextMenu(DropTable else if(selectedOption==moveUp.get()){ qSort(selectedRows); //let's order the selections by the row number, so we know exactly how to swap it myTable->swapPositions(selectedRows,-1); + rowsWereChangedInDropTableWidget(); } else if(selectedOption==moveDown.get()){ qSort(selectedRows); myTable->swapPositions(selectedRows,+1); + rowsWereChangedInDropTableWidget(); } else if(selectedOption==changeOptions.get()){ changeToCurrentSettings(selectedRows,myTable); @@ -1539,6 +1630,7 @@ void MainWindow::dtContextMenu(DropTable result+=QString::number(disabledCount) + (disabledCount==1?" item ":" items ") + "Disabled"; } + rowsWereChangedInDropTableWidget(); showSuccessStatusMessage(result); } } @@ -1564,6 +1656,7 @@ void MainWindow::changeToCurrentSettings myTable->updateTableToolTips(row); } + rowsWereChangedInDropTableWidget(); showSuccessStatusMessage(QString::number(rows.size()) + (rows.size()==1?" item ":" items ")+ "changed to the current settings"); } @@ -1587,6 +1680,7 @@ void MainWindow::changeItemsOutput(DropT myTable->updateTableToolTips(row); } + rowsWereChangedInDropTableWidget(); showSuccessStatusMessage(QString::number(rows.size()) + (rows.size()==1?" item ":" items ")+ "changed the output to "+(newOutput!=this->workspaceLocation?Util::cutName(newOutput):"Vago workspace")); } @@ -1677,7 +1771,7 @@ void MainWindow::saveProjectState(const pugi::xml_document doc; pugi::xml_node rootNode = doc.append_child("VagoProject"); - rootNode.append_attribute("vagoVersion").set_value(GlobalVars::AppVersion.toUtf8().constData()); + rootNode.append_attribute("vagoVersion").set_value(GlobalVars::LastCompatibleVersion.toUtf8().constData()); foreach(DropTableWidget* const &myTable, tableWidgets){ saveProjectWidget(rootNode, myTable); @@ -1691,10 +1785,13 @@ void MainWindow::saveProjectState(const this->vagoSettings->setValue("LastProjectPath",QFileInfo(filePath).absoluteDir().path()); this->lastProjectFilePath = filePath; + this->unsavedChangesExist = false; addNewRecentProject(filePath); setVagoWindowTitle(); + + showSuccessStatusMessage("Project saved sucessfully."); } void MainWindow::saveProjectWidget(pugi::xml_node &rootNode, DropTableWidget* table) @@ -1841,6 +1938,10 @@ void MainWindow::setVagoWindowTitle(){ vagoTitle += Util::cutNameWithoutBackSlash(this->lastProjectFilePath); } + if(this->unsavedChangesExist){ + vagoTitle += "*"; + } + setWindowTitle(vagoTitle); } @@ -1913,6 +2014,16 @@ QList MainWindow::getA void MainWindow::loadProjectState(const QString &filePath) { + this->projectIsLoading = true; + + if(this->vagoSettings->value("AskSaveProject").toBool() && this->unsavedChangesExist){ + QMessageBox::StandardButton result = askToSaveCurrentProject(); + if(result == QMessageBox::StandardButton::Cancel){ + this->projectIsLoading = false; + return; + } + } + QString statusError = "Couldn't load project."; pugi::xml_document doc; @@ -1922,6 +2033,7 @@ void MainWindow::loadProjectState(const if(result.status!=pugi::status_ok){ UtilVago::showAndLogErrorPopUpLogButton(this->myLogger, "An error ocurred while loading project file.\n" + QString(result.description())); showErrStatusMessage(statusError); + this->projectIsLoading = false; return; } @@ -1929,6 +2041,7 @@ void MainWindow::loadProjectState(const if(QString(doc.root().first_child().name()) != "VagoProject"){ UtilVago::showAndLogErrorPopUpLogButton(this->myLogger, QString(doc.root().name()) + "The file opened is not a valid VagoProject file. Load aborted."); showErrStatusMessage(statusError); + this->projectIsLoading = false; return; } @@ -1941,12 +2054,14 @@ void MainWindow::loadProjectState(const { UtilVago::showAndLogErrorPopUpLogButton(this->myLogger, "Couldn't find the vagoVersion of the current project. Load aborted.\n" + QString(e.what())); showErrStatusMessage(statusError); + this->projectIsLoading = false; return; } if(!projVagoVersion.startsWith(GlobalVars::LastCompatibleVersion)){ 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."); showErrStatusMessage(statusError); + this->projectIsLoading = false; return; } @@ -1962,17 +2077,21 @@ void MainWindow::loadProjectState(const catch(const std::exception& e){ UtilVago::showAndLogErrorPopUpLogButton(this->myLogger, "Couldn't load the vago project. Error: " + QString(e.what())); showErrStatusMessage(statusError); + this->projectIsLoading = false; return; } this->vagoSettings->setValue("LastProjectPath",QFileInfo(filePath).absoluteDir().path()); this->lastProjectFilePath = filePath; + this->unsavedChangesExist = false; addNewRecentProject(filePath); setVagoWindowTitle(); + this->projectIsLoading = false; + showSuccessStatusMessage("Project loaded sucessfully."); } @@ -2035,7 +2154,7 @@ void MainWindow::loadProjectWidget(pugi: ui->leBnvLevels->setText(QString(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@bnvSourceValue")).attribute().value())); ui->cbGridsLevels->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@generateGrids")).attribute().as_bool()); ui->cbAdditionalSourcesLevels->setChecked(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@additionalSources")).attribute().as_bool()); - ui->leAdditSourcesLevels->setText(QString(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@bnvSource")).attribute().value())); + ui->leAdditSourcesLevels->setText(QString(doc.select_node(Util::qStrToCstr("/VagoProject/"+tabName+"/Options/@additionalSourcesValue")).attribute().value())); } else{ ui->cbFromMisc->setCurrentText(from);