ViewVC Help
View File | Revision Log | View Changeset | Root Listing
root/Oni2/s10k/Vago/mainwindow.cpp
Revision: 801
Committed: Sun Apr 7 15:36:17 2013 UTC (12 years, 6 months ago) by s10k
Content type: text/x-c++src
Original Path: Vago/trunk/Vago/mainwindow.cpp
File size: 59319 byte(s)
Log Message:
Vago: tried to fix the main directory in mac. I don't want to get the
bundle one.

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