ViewVC Help
View File | Revision Log | View Changeset | Root Listing
root/Oni2/s10k/Vago/mainwindow.cpp
Revision: 815
Committed: Sat Apr 13 13:44:29 2013 UTC (12 years, 6 months ago) by s10k
Content type: text/x-c++src
Original Path: Vago/trunk/Vago/mainwindow.cpp
File size: 59609 byte(s)
Log Message:
Vago: Some more app dir mac fixes

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