ViewVC Help
View File | Revision Log | View Changeset | Root Listing
root/Oni2/s10k/Vago/mainwindow.cpp
Revision: 897
Committed: Wed Jan 8 11:32:55 2014 UTC (11 years, 9 months ago) by s10k
Content type: text/x-c++src
Original Path: Vago/trunk/Vago/mainwindow.cpp
File size: 60831 byte(s)
Log Message:
Vago 09

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