ViewVC Help
View File | Revision Log | View Changeset | Root Listing
root/Oni2/s10k/Vago/mainwindow.cpp
Revision: 1035
Committed: Thu Mar 24 22:28:41 2016 UTC (9 years, 6 months ago) by s10k
Content type: text/x-c++src
Original Path: Vago/trunk/Vago/mainwindow.cpp
File size: 61957 byte(s)
Log Message:
Vago 9.0b

File Contents

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