00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
00039 ui.setupUi(this);
00040
00041
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
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
00121 QRegExpValidator *nameValidator =
00122 new QRegExpValidator(QRegExp("[A-Z0-9 ,!'&\\.\"\\?_]{0,8}"), this);
00123 ui.lineHerosName->setValidator(nameValidator);
00124
00125
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
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
00173 ui.lineHerosName->setText(sram->getName());
00174
00175
00176 ui.spinPlayCount->setValue(sram->getPlayCount());
00177
00178
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
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
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
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
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
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
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
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
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
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
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
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.90\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
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