ViewVC Help
View File | Revision Log | View Changeset | Root Listing
root/Oni2/s10k/Vago/mainwindow.cpp
Revision: 797
Committed: Sun Apr 7 01:02:07 2013 UTC (12 years, 6 months ago) by s10k
Content type: text/x-c++src
Original Path: Vago/trunk/Vago/mainwindow.cpp
File size: 58890 byte(s)
Log Message:
fixed some really small tooltips at mac and also fixed at sound wizard
not recognizing *.aif.aif files (thanks Iritscen!)

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