mainwindow.cc

Go to the documentation of this file.
00001 /*
00002  * lozsrame - Legend of Zelda SRAM Editor
00003  * Copyright (C) 2007-2008 emuWorks
00004  * http://games.technoplaza.net/
00005  *
00006  * This file is part of lozsrame.
00007  *
00008  * lozsrame is free software; you can redistribute it and/or modify it under the
00009  * terms of the GNU General Public License as published by the Free Software
00010  * Foundation; either version 2 of the License, or (at your option) any later
00011  * version.
00012  *
00013  * lozsrame is distributed in the hope that it will be useful, but WITHOUT ANY
00014  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00015  * A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License along with
00018  * lozsrame; if not, write to the Free Software Foundation, Inc.,
00019  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020  */
00021 
00022 // $Id: mainwindow.cc,v 1.13 2008/12/18 05:01:40 jdratlif Exp $
00023 
00024 #include <QActionGroup>
00025 #include <QButtonGroup>
00026 #include <QDesktopWidget>
00027 #include <QFileDialog>
00028 #include <QMessageBox>
00029 #include <QRegExpValidator>
00030 #include <QSignalMapper>
00031 #include <QUrl>
00032 
00033 #include "view/mainwindow.hh"
00034 
00035 using namespace lozsrame;
00036 
00037 MainWindow::MainWindow() : QMainWindow(), ignoreSignals(false), open(false) {
00038     // create widgets
00039     ui.setupUi(this);
00040     
00041     // setup button groups
00042     QActionGroup *gameActionGroup = new QActionGroup(this);
00043     gameActionGroup->addAction(ui.gameGame1);
00044     gameActionGroup->addAction(ui.gameGame2);
00045     gameActionGroup->addAction(ui.gameGame3);
00046     gameActionGroup->setExclusive(true);
00047     
00048     QButtonGroup *questButtonGroup = new QButtonGroup(this);
00049     questButtonGroup->addButton(ui.radioQuestFirst);
00050     questButtonGroup->addButton(ui.radioQuestSecond);
00051     questButtonGroup->setExclusive(true);
00052     
00053     QButtonGroup *swordButtonGroup = new QButtonGroup(this);
00054     swordButtonGroup->addButton(ui.radioSwordNone);
00055     swordButtonGroup->addButton(ui.radioSwordWooden);
00056     swordButtonGroup->addButton(ui.radioSwordWhite);
00057     swordButtonGroup->addButton(ui.radioSwordMaster);
00058     swordButtonGroup->setExclusive(true);
00059     
00060     QButtonGroup *arrowsButtonGroup = new QButtonGroup(this);
00061     arrowsButtonGroup->addButton(ui.radioArrowsNone);
00062     arrowsButtonGroup->addButton(ui.radioArrowsWooden);
00063     arrowsButtonGroup->addButton(ui.radioArrowsSilver);
00064     arrowsButtonGroup->setExclusive(true);
00065     
00066     QButtonGroup *candleButtonGroup = new QButtonGroup(this);
00067     candleButtonGroup->addButton(ui.radioCandleNone);
00068     candleButtonGroup->addButton(ui.radioCandleBlue);
00069     candleButtonGroup->addButton(ui.radioCandleRed);
00070     candleButtonGroup->setExclusive(true);
00071     
00072     QButtonGroup *potionButtonGroup = new QButtonGroup(this);
00073     potionButtonGroup->addButton(ui.radioPotionNone);
00074     potionButtonGroup->addButton(ui.radioPotionBlue);
00075     potionButtonGroup->addButton(ui.radioPotionRed);
00076     potionButtonGroup->setExclusive(true);
00077     
00078     QButtonGroup *ringButtonGroup = new QButtonGroup(this);
00079     ringButtonGroup->addButton(ui.radioRingNone);
00080     ringButtonGroup->addButton(ui.radioRingBlue);
00081     ringButtonGroup->addButton(ui.radioRingRed);
00082     ringButtonGroup->setExclusive(true);
00083     
00084     QButtonGroup *noteButtonGroup = new QButtonGroup(this);
00085     noteButtonGroup->addButton(ui.radioNoteOldMan);
00086     noteButtonGroup->addButton(ui.radioNoteLink);
00087     noteButtonGroup->addButton(ui.radioNoteOldWoman);
00088     noteButtonGroup->setExclusive(true);
00089     
00090     // create button group arrays
00091     compassChecks[0] = ui.checkCompass1;
00092     compassChecks[1] = ui.checkCompass2;
00093     compassChecks[2] = ui.checkCompass3;
00094     compassChecks[3] = ui.checkCompass4;
00095     compassChecks[4] = ui.checkCompass5;
00096     compassChecks[5] = ui.checkCompass6;
00097     compassChecks[6] = ui.checkCompass7;
00098     compassChecks[7] = ui.checkCompass8;
00099     compassChecks[8] = ui.checkCompass9;
00100     
00101     mapChecks[0] = ui.checkMap1;
00102     mapChecks[1] = ui.checkMap2;
00103     mapChecks[2] = ui.checkMap3;
00104     mapChecks[3] = ui.checkMap4;
00105     mapChecks[4] = ui.checkMap5;
00106     mapChecks[5] = ui.checkMap6;
00107     mapChecks[6] = ui.checkMap7;
00108     mapChecks[7] = ui.checkMap8;
00109     mapChecks[8] = ui.checkMap9;
00110     
00111     triforceChecks[0] = ui.checkTriforce1;
00112     triforceChecks[1] = ui.checkTriforce2;
00113     triforceChecks[2] = ui.checkTriforce3;
00114     triforceChecks[3] = ui.checkTriforce4;
00115     triforceChecks[4] = ui.checkTriforce5;
00116     triforceChecks[5] = ui.checkTriforce6;
00117     triforceChecks[6] = ui.checkTriforce7;
00118     triforceChecks[7] = ui.checkTriforce8;
00119     
00120     // setup name validator
00121     QRegExpValidator *nameValidator =
00122         new QRegExpValidator(QRegExp("[A-Z0-9 ,!'&\\.\"\\?_]{0,8}"), this);
00123     ui.lineHerosName->setValidator(nameValidator);
00124     
00125     // setup connections for the game menu
00126     QSignalMapper *gameMapper = new QSignalMapper(this);
00127     
00128     gameMapper->setMapping(ui.gameGame1, 0);
00129     gameMapper->setMapping(ui.gameGame2, 1);
00130     gameMapper->setMapping(ui.gameGame3, 2);
00131     
00132     connect(gameMapper, SIGNAL(mapped(int)), this, SLOT(selectGame(int)));
00133     
00134     connect(ui.gameGame1, SIGNAL(triggered(bool)), gameMapper, SLOT(map()));
00135     connect(ui.gameGame2, SIGNAL(triggered(bool)), gameMapper, SLOT(map()));
00136     connect(ui.gameGame3, SIGNAL(triggered(bool)), gameMapper, SLOT(map()));
00137     
00138     updateUI();
00139 }
00140 
00141 bool MainWindow::closeSRAM() {
00142     Q_ASSERT(open);
00143     
00144     if (sram->isModified()) {
00145         int choice = QMessageBox::question(this,
00146             tr("Warning: Unsaved Changes"), tr("Save changes?"),
00147             QMessageBox::Yes, QMessageBox::No, QMessageBox::Cancel);
00148         
00149         if (choice == QMessageBox::Yes) {
00150             ui.fileSave->trigger();
00151             
00152             // if the save failed, abort
00153             if (sram->isModified()) {
00154                 return false;
00155             }
00156         } else if (choice == QMessageBox::Cancel) {
00157             return false;
00158         }
00159     }
00160     
00161     delete sram;
00162     open = false;
00163     
00164     return true;
00165 }
00166 
00167 void MainWindow::loadSRAMData() {
00168     Q_ASSERT(open);
00169     
00170     ignoreSignals = true;
00171     
00172     // load the hero's name
00173     ui.lineHerosName->setText(sram->getName());
00174     
00175     // load the play count
00176     ui.spinPlayCount->setValue(sram->getPlayCount());
00177     
00178     // load the quest number
00179     switch (sram->getQuest()) {
00180         case QUEST_FIRST: ui.radioQuestFirst->setChecked(true); break;
00181         case QUEST_SECOND: ui.radioQuestSecond->setChecked(true); break;
00182     }
00183     
00184     // load the sword type
00185     switch (sram->getSword()) {
00186         case SWORD_NONE: ui.radioSwordNone->setChecked(true); break;
00187         case SWORD_WOODEN: ui.radioSwordWooden->setChecked(true); break;
00188         case SWORD_WHITE: ui.radioSwordWhite->setChecked(true); break;
00189         case SWORD_MASTER: ui.radioSwordMaster->setChecked(true); break;
00190     }
00191     
00192     // load the arrow type
00193     switch (sram->getArrows()) {
00194         case ARROW_NONE: ui.radioArrowsNone->setChecked(true); break;
00195         case ARROW_WOODEN: ui.radioArrowsWooden->setChecked(true); break;
00196         case ARROW_SILVER: ui.radioArrowsSilver->setChecked(true); break;
00197     }
00198     
00199     // load the candle type
00200     switch (sram->getCandle()) {
00201         case CANDLE_NONE: ui.radioCandleNone->setChecked(true); break;
00202         case CANDLE_BLUE: ui.radioCandleBlue->setChecked(true); break;
00203         case CANDLE_RED: ui.radioCandleRed->setChecked(true); break;
00204     }
00205     
00206     // load the potion type
00207     switch (sram->getPotion()) {
00208         case POTION_NONE: ui.radioPotionNone->setChecked(true); break;
00209         case POTION_BLUE: ui.radioPotionBlue->setChecked(true); break;
00210         case POTION_RED: ui.radioPotionRed->setChecked(true); break;
00211     }
00212     
00213     // load the ring type
00214     switch (sram->getRing()) {
00215         case RING_NONE: ui.radioRingNone->setChecked(true); break;
00216         case RING_BLUE: ui.radioRingBlue->setChecked(true); break;
00217         case RING_RED: ui.radioRingRed->setChecked(true); break;
00218     }
00219     
00220     // load inventory data
00221     ui.checkBoomerang->setChecked(sram->hasItem(ITEM_BOOMERANG));
00222     ui.checkBow->setChecked(sram->hasItem(ITEM_BOW));
00223     ui.checkMagicBoomerang->setChecked(sram->hasItem(ITEM_MAGICBOOMERANG));
00224     ui.checkRaft->setChecked(sram->hasItem(ITEM_RAFT));
00225     ui.checkLadder->setChecked(sram->hasItem(ITEM_LADDER));
00226     ui.checkWhistle->setChecked(sram->hasItem(ITEM_WHISTLE));
00227     ui.checkWand->setChecked(sram->hasItem(ITEM_WAND));
00228     ui.checkBook->setChecked(sram->hasItem(ITEM_BOOK));
00229     ui.checkMagicKey->setChecked(sram->hasItem(ITEM_MAGICKEY));
00230     ui.checkMagicShield->setChecked(sram->hasItem(ITEM_MAGICSHIELD));
00231     ui.checkPowerBracelet->setChecked(sram->hasItem(ITEM_POWERBRACELET));
00232     ui.checkBait->setChecked(sram->hasItem(ITEM_BAIT));
00233     
00234     // load dungeon data
00235     for (int i = 1; i < 10; ++i) {
00236         compassChecks[i - 1]->setChecked(sram->hasCompass(i));
00237         mapChecks[i - 1]->setChecked(sram->hasMap(i));
00238         
00239         if (i < 9) {
00240             triforceChecks[i - 1]->setChecked(sram->hasTriforce(i));
00241         }
00242     }
00243     
00244     // load potion note data
00245     switch (sram->getNote()) {
00246         case NOTE_OLDMAN: ui.radioNoteOldMan->setChecked(true); break;
00247         case NOTE_LINK: ui.radioNoteLink->setChecked(true); break;
00248         case NOTE_OLDWOMAN: ui.radioNoteOldWoman->setChecked(true); break;
00249     }
00250     
00251     // load treasure and bomb data
00252     ui.spinRupees->setValue(sram->getRupees());
00253     ui.spinKeys->setValue(sram->getKeys());
00254     ui.spinHeartContainers->setValue(sram->getHeartContainers());
00255     ui.spinBombsCarrying->setValue(sram->getBombs());
00256     ui.spinBombsCapacity->setValue(sram->getBombCapacity());
00257     
00258     ignoreSignals = false;
00259 }
00260 
00261 void MainWindow::openSRAM(const QString &filename) {
00262     Q_ASSERT(!open);
00263     
00264     try {
00265         sram = new SRAMFile(filename);
00266         sramFile = filename;
00267         open = true;
00268         
00269         loadSRAMData();
00270         updateUI();
00271     } catch (InvalidSRAMFileException &e) {
00272         QString temp;
00273         
00274         if (e.getError() == ISFE_INVALIDSIZE) {
00275             temp = tr("Invalid SRAM File Size");
00276         } else if (e.getError() == ISFE_NOVALIDGAMES) {
00277             temp = tr("No Save Games Found");
00278         }
00279         
00280         QMessageBox::warning(this, tr("Unable to Open SRAM File"), temp,
00281                              QMessageBox::Ok,  QMessageBox::NoButton);
00282     }
00283 }
00284 
00285 void MainWindow::selectArrows(enum sf_arrow arrows) {
00286     Q_ASSERT(open);
00287     
00288     sram->setArrows(arrows);
00289     updateUI();
00290 }
00291 
00292 void MainWindow::selectCandle(enum sf_candle candle) {
00293     Q_ASSERT(open);
00294     
00295     sram->setCandle(candle);
00296     updateUI();
00297 }
00298 
00299 void MainWindow::selectCompass(int level, bool give) {
00300     Q_ASSERT(open);
00301     Q_ASSERT((level >= 1) && (level <= 9));
00302     
00303     sram->setCompass(level, give);
00304     updateUI();
00305 }
00306 
00307 void MainWindow::selectItem(enum sf_item item, bool give) {
00308     Q_ASSERT(open);
00309     
00310     sram->setItem(item, give);
00311     updateUI();
00312 }
00313 
00314 void MainWindow::selectMap(int level, bool give) {
00315     Q_ASSERT(open);
00316     Q_ASSERT((level >= 1) && (level <= 9));
00317     
00318     sram->setMap(level, give);
00319     updateUI();
00320 }
00321 
00322 void MainWindow::selectNote(enum sf_note note) {
00323     Q_ASSERT(open);
00324     
00325     sram->setNote(note);
00326     updateUI();
00327 }
00328 
00329 void MainWindow::selectQuest(enum sf_quest quest) {
00330     Q_ASSERT(open);
00331     
00332     sram->setQuest(quest);
00333     updateUI();
00334 }
00335 
00336 void MainWindow::selectPotion(enum sf_potion potion) {
00337     Q_ASSERT(open);
00338     
00339     sram->setPotion(potion);
00340     updateUI();
00341 }
00342 
00343 void MainWindow::selectRing(enum sf_ring ring) {
00344     Q_ASSERT(open);
00345     
00346     sram->setRing(ring);
00347     updateUI();
00348 }
00349 
00350 void MainWindow::selectSword(enum sf_sword sword) {
00351     Q_ASSERT(open);
00352     
00353     sram->setSword(sword);
00354     updateUI();
00355 }
00356 
00357 void MainWindow::selectTriforce(int level, bool give) {
00358     Q_ASSERT(open);
00359     Q_ASSERT((level >= 1) && (level <= 8));
00360     
00361     sram->setTriforce(level, give);
00362     updateUI();
00363 }
00364 
00365 void MainWindow::updateUI() {
00366     ui.fileClose->setEnabled(open);
00367     ui.fileSave->setEnabled(open && sram->isModified());
00368     ui.fileSaveAs->setEnabled(open);
00369     
00370     ui.gameGame1->setEnabled(open && sram->isValid(0));
00371     ui.gameGame2->setEnabled(open && sram->isValid(1));
00372     ui.gameGame3->setEnabled(open && sram->isValid(2));
00373     
00374     ui.centralwidget->setVisible(open);
00375     
00376     if (open) {
00377         switch (sram->getGame()) {
00378             case 0: ui.gameGame1->setChecked(true); break;
00379             case 1: ui.gameGame2->setChecked(true); break;
00380             case 2: ui.gameGame3->setChecked(true); break;
00381                 
00382             default:
00383                 // we must never get here!
00384                 Q_ASSERT(false);
00385         }
00386     }
00387 }
00388 
00389 void MainWindow::closeEvent(QCloseEvent *event) {
00390     if (open) {
00391         event->setAccepted(closeSRAM());
00392     } else {
00393         event->accept();
00394     }
00395 }
00396 
00397 void MainWindow::dragEnterEvent(QDragEnterEvent *event) {
00398     if (event->mimeData()->hasFormat("text/uri-list")) {
00399         event->acceptProposedAction();
00400     }
00401 }
00402 
00403 void MainWindow::dropEvent(QDropEvent *event) {
00404     QList<QUrl> urls = event->mimeData()->urls();
00405     QString filename = urls.first().toLocalFile();
00406     
00407     // uri could be something else
00408     if (filename.isEmpty()) {
00409         return;
00410     }
00411     
00412     if (open && !closeSRAM()) {
00413         return;
00414     }
00415     
00416     openSRAM(filename);
00417 }
00418 
00419 void MainWindow::on_fileClose_triggered(bool) {
00420     Q_ASSERT(open);
00421     
00422     if (closeSRAM()) {
00423         updateUI();
00424     }
00425 }
00426 
00427 void MainWindow::on_fileOpen_triggered(bool) {
00428     if (open && !closeSRAM()) {
00429         return;
00430     }
00431     
00432     QString filename = QFileDialog::getOpenFileName(this,
00433         tr("Open Legend of Zelda SRAM File"), "", tr("SRAM Files (*.sav)"));
00434         
00435     if (filename.isNull()) {
00436         return;
00437     }
00438     
00439     openSRAM(filename);
00440 }
00441 
00442 void MainWindow::on_fileSave_triggered(bool) {
00443     Q_ASSERT(open);
00444     
00445     if (!sram->save(sramFile)) {
00446         QMessageBox::warning(this, tr("Unable to Save SRAM File"),
00447                              tr("An I/O error occurred while trying to save."),
00448                              QMessageBox::Ok, QMessageBox::NoButton);
00449     }
00450     
00451     updateUI();
00452 }
00453 
00454 void MainWindow::on_fileSaveAs_triggered(bool) {
00455     Q_ASSERT(open);
00456     
00457     QString temp = QFileDialog::getSaveFileName(this, tr("Save SRAM File As"),
00458         "", tr("SRAM Files (*.sav)"));
00459                                      
00460     if (temp.isNull()) {
00461         return;
00462     }
00463     
00464     sramFile = temp;
00465     
00466     ui.fileSave->trigger();
00467 }
00468 
00469 void MainWindow::on_helpAbout_triggered(bool) {
00470     QMessageBox::about(this, tr("About lozsrame"), 
00471         tr("Legend of Zelda SRAM Editor Version 0.90a\n"
00472            "Copyright (C) 2007-2008 emuWorks\n"
00473            "http://games.technoplaza.net/"));
00474 }
00475 
00476 void MainWindow::on_lineHerosName_textEdited(const QString &text) {
00477     Q_ASSERT(open);
00478     
00479     sram->setName(text);
00480     updateUI();
00481 }
00482 
00483 void MainWindow::on_spinBombsCarrying_valueChanged(int value) {
00484     Q_ASSERT(open);
00485     
00486     if (!ignoreSignals) {
00487         sram->setBombs(value);
00488         updateUI();
00489     }
00490 }
00491 
00492 void MainWindow::on_spinBombsCapacity_valueChanged(int value) {
00493     Q_ASSERT(open);
00494     
00495     if (!ignoreSignals) {
00496         sram->setBombCapacity(value);
00497         updateUI();
00498     }
00499 }
00500 
00501 void MainWindow::on_spinHeartContainers_valueChanged(int value) {
00502     Q_ASSERT(open);
00503     
00504     if (!ignoreSignals) {
00505         sram->setHeartContainers(value);
00506         updateUI();
00507     }
00508 }
00509 
00510 void MainWindow::on_spinKeys_valueChanged(int value) {
00511     Q_ASSERT(open);
00512     
00513     if (!ignoreSignals) {
00514         sram->setKeys(value);
00515         updateUI();
00516     }
00517 }
00518 
00519 void MainWindow::on_spinPlayCount_valueChanged(int value) {
00520     Q_ASSERT(open);
00521     
00522     if (!ignoreSignals) {
00523         sram->setPlayCount(value);
00524         updateUI();
00525     }
00526 }
00527 
00528 void MainWindow::on_spinRupees_valueChanged(int value) {
00529     Q_ASSERT(open);
00530     
00531     if (!ignoreSignals) {
00532         sram->setRupees(value);
00533         updateUI();
00534     }
00535 }
00536 
00537 void MainWindow::selectGame(int game) {
00538     Q_ASSERT(open);
00539     
00540     sram->setGame(game);
00541     loadSRAMData();
00542     updateUI();
00543 }
00544 
00545 void MainWindow::showEvent(QShowEvent *) {
00546     static bool centered = false;
00547     
00548     // center on screen the first time we're displayed
00549     if (!centered) {
00550         QRect screenRect = QApplication::desktop()->availableGeometry();
00551         QRect windowRect = frameGeometry();
00552         
00553         move(screenRect.width() / 2 - windowRect.width() / 2,
00554              screenRect.height() / 2 - windowRect.height() / 2);
00555         
00556         centered = true;
00557     }
00558 }
00559 

Generated on Mon Dec 29 00:56:07 2008 for Legend of Zelda SRAM Editor by  doxygen 1.5.4