diff options
Diffstat (limited to 'qt-ui/mainwindow.cpp')
-rw-r--r-- | qt-ui/mainwindow.cpp | 387 |
1 files changed, 242 insertions, 145 deletions
diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp index 82eaaac57..648ead174 100644 --- a/qt-ui/mainwindow.cpp +++ b/qt-ui/mainwindow.cpp @@ -11,7 +11,8 @@ #include <QSettings> #include <QShortcut> #include <QToolBar> -#include "ssrf-version.h" +#include "version.h" +#include "divelistview.h" #include "downloadfromdivecomputer.h" #include "preferences.h" #include "subsurfacewebservices.h" @@ -20,6 +21,10 @@ #include "updatemanager.h" #include "planner.h" #include "filtermodels.h" +#include "profile/profilewidget2.h" +#include "globe.h" +#include "maintab.h" +#include "diveplanner.h" #ifndef NO_PRINTING #include <QPrintDialog> #include "printdialog.h" @@ -31,6 +36,7 @@ #include "usermanual.h" #endif #include <QNetworkProxy> +#include <QUndoStack> MainWindow *MainWindow::m_Instance = NULL; @@ -44,7 +50,25 @@ MainWindow::MainWindow() : QMainWindow(), Q_ASSERT_X(m_Instance == NULL, "MainWindow", "MainWindow recreated!"); m_Instance = this; ui.setupUi(this); - ui.multiFilter->hide(); + // Define the States of the Application Here, Currently the states are situations where the different + // widgets will change on the mainwindow. + + // for the "default" mode + MainTab *mainTab = new MainTab(); + DiveListView *diveListView = new DiveListView(); + ProfileWidget2 *profileWidget = new ProfileWidget2(); + +#ifndef NO_MARBLE + GlobeGPS *globeGps = new GlobeGPS(); +#else + QWidget *globeGps = NULL; +#endif + + PlannerSettingsWidget *plannerSettings = new PlannerSettingsWidget(); + DivePlannerWidget *plannerWidget = new DivePlannerWidget(); + PlannerDetails *plannerDetails = new PlannerDetails(); + LocationInformationWidget *locationInformation = new LocationInformationWidget(); + // what is a sane order for those icons? we should have the ones the user is // most likely to want towards the top so they are always visible // and the ones that someone likely sets and then never touches again towards the bottom @@ -57,69 +81,83 @@ MainWindow::MainWindow() : QMainWindow(), ui.profEad << ui.profSAC << ui.profHR << // very few dive computers support this ui.profTissues; // maybe less frequently used + + QToolBar *toolBar = new QToolBar(); + Q_FOREACH (QAction *a, profileToolbarActions) + toolBar->addAction(a); + toolBar->setOrientation(Qt::Vertical); + toolBar->setIconSize(QSize(24,24)); + + QWidget *profileContainer = new QWidget(); + QHBoxLayout *profLayout = new QHBoxLayout(); + profLayout->addWidget(toolBar); + profLayout->addWidget(profileWidget); + profileContainer->setLayout(profLayout); + + registerApplicationState("Default", mainTab, profileContainer, diveListView, globeGps ); + registerApplicationState("AddDive", mainTab, profileContainer, diveListView, globeGps ); + registerApplicationState("EditDive", mainTab, profileContainer, diveListView, globeGps ); + registerApplicationState("PlanDive", plannerWidget, profileContainer, plannerSettings, plannerDetails ); + registerApplicationState("EditPlannedDive", plannerWidget, profileContainer, diveListView, globeGps ); + registerApplicationState("EditDiveSite",locationInformation, profileContainer, diveListView, globeGps ); + + setApplicationState("Default"); + + ui.multiFilter->hide(); + setWindowIcon(QIcon(":subsurface-icon")); if (!QIcon::hasThemeIcon("window-close")) { QIcon::setThemeName("subsurface"); } - connect(ui.ListWidget, SIGNAL(currentDiveChanged(int)), this, SLOT(current_dive_changed(int))); + connect(dive_list(), SIGNAL(currentDiveChanged(int)), this, SLOT(current_dive_changed(int))); connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), this, SLOT(readSettings())); - connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), ui.ListWidget, SLOT(update())); - connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), ui.ListWidget, SLOT(reloadHeaderActions())); - connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), ui.InfoWidget, SLOT(updateDiveInfo())); - connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), ui.divePlannerWidget, SLOT(settingsChanged())); - connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), ui.plannerSettingsWidget, SLOT(settingsChanged())); + connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), diveListView, SLOT(update())); + connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), diveListView, SLOT(reloadHeaderActions())); + connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), information(), SLOT(updateDiveInfo())); + connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), divePlannerWidget(), SLOT(settingsChanged())); + connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), divePlannerSettingsWidget(), SLOT(settingsChanged())); connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), TankInfoModel::instance(), SLOT(update())); connect(ui.actionRecent1, SIGNAL(triggered(bool)), this, SLOT(recentFileTriggered(bool))); connect(ui.actionRecent2, SIGNAL(triggered(bool)), this, SLOT(recentFileTriggered(bool))); connect(ui.actionRecent3, SIGNAL(triggered(bool)), this, SLOT(recentFileTriggered(bool))); connect(ui.actionRecent4, SIGNAL(triggered(bool)), this, SLOT(recentFileTriggered(bool))); - connect(information(), SIGNAL(addDiveFinished()), ui.newProfile, SLOT(setProfileState())); + connect(information(), SIGNAL(addDiveFinished()), graphics(), SLOT(setProfileState())); connect(DivePlannerPointsModel::instance(), SIGNAL(planCreated()), this, SLOT(planCreated())); connect(DivePlannerPointsModel::instance(), SIGNAL(planCanceled()), this, SLOT(planCanceled())); - connect(ui.printPlan, SIGNAL(pressed()), ui.divePlannerWidget, SLOT(printDecoPlan())); + connect(plannerDetails->printPlan(), SIGNAL(pressed()), divePlannerWidget(), SLOT(printDecoPlan())); + connect(mainTab, SIGNAL(requestDiveSiteEdit(uint32_t)), this, SLOT(enableDiveSiteEdit(uint32_t))); + connect(locationInformation, SIGNAL(informationManagementEnded()), this, SLOT(setDefaultState())); + connect(locationInformation, SIGNAL(informationManagementEnded()), this, SLOT(refreshDisplay())); + connect(locationInformation, SIGNAL(informationManagementEnded()), information(), SLOT(showLocation())); + #ifdef NO_PRINTING ui.printPlan->hide(); + ui.menuFile->removeAction(ui.actionPrint); #endif ui.mainErrorMessage->hide(); - ui.newProfile->setEmptyState(); + graphics()->setEmptyState(); initialUiSetup(); readSettings(); - ui.ListWidget->reload(DiveTripModel::TREE); - ui.ListWidget->reloadHeaderActions(); - ui.ListWidget->setFocus(); - ui.globe->reload(); - ui.ListWidget->expand(ui.ListWidget->model()->index(0, 0)); - ui.ListWidget->scrollTo(ui.ListWidget->model()->index(0, 0), QAbstractItemView::PositionAtCenter); - ui.divePlannerWidget->settingsChanged(); - ui.plannerSettingsWidget->settingsChanged(); + diveListView->reload(DiveTripModel::TREE); + diveListView->reloadHeaderActions(); + diveListView->setFocus(); + globe()->reload(); + diveListView->expand(dive_list()->model()->index(0, 0)); + diveListView->scrollTo(dive_list()->model()->index(0, 0), QAbstractItemView::PositionAtCenter); + divePlannerWidget()->settingsChanged(); + divePlannerSettingsWidget()->settingsChanged(); #ifdef NO_MARBLE - ui.globePane->hide(); ui.menuView->removeAction(ui.actionViewGlobe); #else - connect(ui.globe, SIGNAL(coordinatesChanged()), ui.InfoWidget, SLOT(updateGpsCoordinates())); + connect(globe(), SIGNAL(coordinatesChanged()), locationInformation, SLOT(updateGpsCoordinates())); #endif #ifdef NO_USERMANUAL ui.menuHelp->removeAction(ui.actionUserManual); #endif -#ifdef NO_PRINTING - ui.menuFile->removeAction(ui.actionPrint); -#endif memset(©PasteDive, 0, sizeof(copyPasteDive)); memset(&what, 0, sizeof(what)); - QToolBar *toolBar = new QToolBar(); - Q_FOREACH (QAction *a, profileToolbarActions) - toolBar->addAction(a); - toolBar->setOrientation(Qt::Vertical); - toolBar->setIconSize(QSize(24,24)); - // since I'm adding the toolBar by hand, because designer - // has no concept of "toolbar" for a non-mainwindow widget (...) - // I need to take the current item that's in the toolbar Position - // and reposition it alongside the grid layout. - QLayoutItem *p = ui.profileInnerLayout->takeAt(0); - ui.profileInnerLayout->addWidget(toolBar, 0, 0); - ui.profileInnerLayout->addItem(p, 0, 1); // and now for some layout hackery // this gets us consistent margins everywhere and a much more balanced look @@ -146,12 +184,19 @@ MainWindow::MainWindow() : QMainWindow(), else layout->setContentsMargins(margins); } - margins = QMargins(0, 5, 5, 5); - ui.profileInnerLayout->setContentsMargins(margins); - ui.profileInnerLayout->setSpacing(0); toolBar->setContentsMargins(zeroMargins); updateManager = new UpdateManager(this); + + undoStack = new QUndoStack(this); + QAction *undoAction = undoStack->createUndoAction(this, tr("&Undo")); + QAction *redoAction = undoStack->createRedoAction(this, tr("&Redo")); + undoAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Z)); + redoAction->setShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Z)); + QList<QAction*>undoRedoActions; + undoRedoActions.append(undoAction); + undoRedoActions.append(redoAction); + ui.menu_Edit->addActions(undoRedoActions); } MainWindow::~MainWindow() @@ -159,6 +204,26 @@ MainWindow::~MainWindow() m_Instance = NULL; } +PlannerDetails *MainWindow::plannerDetails() const { + return qobject_cast<PlannerDetails*>(applicationState["PlanDive"].bottomRight); +} + +PlannerSettingsWidget *MainWindow::divePlannerSettingsWidget() { + return qobject_cast<PlannerSettingsWidget*>(applicationState["PlanDive"].bottomLeft); +} + +LocationInformationWidget *MainWindow::locationInformationWidget() { + return qobject_cast<LocationInformationWidget*>(applicationState["EditDiveSite"].topLeft); +} + +void MainWindow::enableDiveSiteEdit(uint32_t id) { + setApplicationState("EditDiveSite"); +} + +void MainWindow::setDefaultState() { + setApplicationState("Default"); +} + void MainWindow::setLoadedWithFiles(bool f) { filesAsArguments = f; @@ -178,18 +243,15 @@ MainWindow *MainWindow::instance() void MainWindow::refreshDisplay(bool doRecreateDiveList) { showError(get_error_string()); - ui.InfoWidget->reload(); + information()->reload(); TankInfoModel::instance()->update(); - ui.globe->reload(); + globe()->reload(); if (doRecreateDiveList) recreateDiveList(); - ui.diveListPane->setCurrentIndex(0); // switch to the dive list -#ifdef NO_MARBLE - ui.globePane->hide(); -#endif - ui.globePane->setCurrentIndex(0); - ui.ListWidget->setEnabled(true); - ui.ListWidget->setFocus(); + + setApplicationState("Default"); + dive_list()->setEnabled(true); + dive_list()->setFocus(); WSInfoModel::instance()->updateInfo(); if (amount_selected == 0) cleanUpEmpty(); @@ -197,7 +259,7 @@ void MainWindow::refreshDisplay(bool doRecreateDiveList) void MainWindow::recreateDiveList() { - ui.ListWidget->reload(DiveTripModel::CURRENT); + dive_list()->reload(DiveTripModel::CURRENT); TagFilterModel::instance()->repopulate(); BuddyFilterModel::instance()->repopulate(); LocationFilterModel::instance()->repopulate(); @@ -208,10 +270,11 @@ void MainWindow::current_dive_changed(int divenr) { if (divenr >= 0) { select_dive(divenr); - ui.globe->centerOnCurrentDive(); + globe()->centerOnCurrentDive(); } - ui.newProfile->plotDive(); - ui.InfoWidget->updateDiveInfo(); + graphics()->plotDive(); + information()->updateDiveInfo(); + locationInformationWidget()->setLocationId(displayed_dive.dive_site_uuid); } void MainWindow::on_actionNew_triggered() @@ -254,18 +317,19 @@ void MainWindow::on_actionSaveAs_triggered() ProfileWidget2 *MainWindow::graphics() const { - return ui.newProfile; + return qobject_cast<ProfileWidget2*>(applicationState["Default"].topRight->layout()->itemAt(1)->widget()); } void MainWindow::cleanUpEmpty() { - ui.InfoWidget->clearStats(); - ui.InfoWidget->clearInfo(); - ui.InfoWidget->clearEquipment(); - ui.InfoWidget->updateDiveInfo(true); - ui.newProfile->setEmptyState(); - ui.ListWidget->reload(DiveTripModel::TREE); - ui.globe->reload(); + information()->clearStats(); + information()->clearInfo(); + information()->clearEquipment(); + information()->updateDiveInfo(true); + graphics()->setEmptyState(); + dive_list()->reload(DiveTripModel::TREE); + locationInformationWidget()->setLocationId(0); + globe()->reload(); if (!existing_filename) setTitle(MWTF_DEFAULT); disableShortcuts(); @@ -274,7 +338,8 @@ void MainWindow::cleanUpEmpty() bool MainWindow::okToClose(QString message) { if (DivePlannerPointsModel::instance()->currentMode() != DivePlannerPointsModel::NOTHING || - ui.InfoWidget->isEditing()) { + information()->isEditing() || + currentApplicationState == "EditDiveSite") { QMessageBox::warning(this, tr("Warning"), message); return false; } @@ -286,11 +351,13 @@ bool MainWindow::okToClose(QString message) void MainWindow::closeCurrentFile() { - ui.newProfile->setEmptyState(); + graphics()->setEmptyState(); /* free the dives and trips */ clear_git_id(); while (dive_table.nr) delete_single_dive(0); + while (dive_site_table.nr) + delete_dive_site(get_dive_site(0)->uuid); free((void *)existing_filename); existing_filename = NULL; @@ -362,8 +429,8 @@ void MainWindow::enableShortcuts() void MainWindow::showProfile() { enableShortcuts(); - ui.newProfile->setProfileState(); - ui.infoPane->setCurrentIndex(MAINTAB); + graphics()->setProfileState(); + setApplicationState("Default"); } void MainWindow::on_actionPreferences_triggered() @@ -373,9 +440,9 @@ void MainWindow::on_actionPreferences_triggered() void MainWindow::on_actionQuit_triggered() { - if (ui.InfoWidget->isEditing()) { - ui.InfoWidget->rejectChanges(); - if (ui.InfoWidget->isEditing()) + if (information()->isEditing()) { + information()->rejectChanges(); + if (information()->isEditing()) // didn't discard the edits return; } @@ -421,7 +488,7 @@ void MainWindow::on_actionEditDeviceNames_triggered() bool MainWindow::plannerStateClean() { if (DivePlannerPointsModel::instance()->currentMode() != DivePlannerPointsModel::NOTHING || - ui.InfoWidget->isEditing()) { + information()->isEditing()) { QMessageBox::warning(this, tr("Warning"), tr("Please save or cancel the current dive edit before trying to add a dive.")); return false; } @@ -433,16 +500,16 @@ void MainWindow::planCanceled() // while planning we might have modified the displayed_dive // let's refresh what's shown on the profile showProfile(); - ui.newProfile->replot(); + graphics()->replot(); refreshDisplay(false); - ui.newProfile->plotDive(get_dive(selected_dive)); + graphics()->plotDive(get_dive(selected_dive)); DivePictureModel::instance()->updateDivePictures(); } void MainWindow::planCreated() { // get the new dive selected and assign a number if reasonable - ui.newProfile->setProfileState(); + graphics()->setProfileState(); if (displayed_dive.id == 0) { // we might have added a new dive (so displayed_dive was cleared out by clone_dive() dive_list()->unselectDives(); @@ -451,20 +518,20 @@ void MainWindow::planCreated() set_dive_nr_for_current_dive(); } // make sure our UI is in a consistent state - ui.InfoWidget->updateDiveInfo(); + information()->updateDiveInfo(); showProfile(); refreshDisplay(); } void MainWindow::setPlanNotes(const char *notes) { - ui.divePlanOutput->setHtml(notes); + plannerDetails()->divePlanOutput()->setHtml(notes); } void MainWindow::printPlan() { #ifndef NO_PRINTING - QString diveplan = ui.divePlanOutput->toHtml(); + QString diveplan = plannerDetails()->divePlanOutput()->toHtml(); QString withDisclaimer = QString("<img height=50 src=\":subsurface-icon\"> ") + diveplan + QString(disclaimer); QPrinter printer; @@ -473,9 +540,9 @@ void MainWindow::printPlan() if (dialog->exec() != QDialog::Accepted) return; - ui.divePlanOutput->setHtml(withDisclaimer); - ui.divePlanOutput->print(&printer); - ui.divePlanOutput->setHtml(diveplan); + plannerDetails()->divePlanOutput()->setHtml(withDisclaimer); + plannerDetails()->divePlanOutput()->print(&printer); + plannerDetails()->divePlanOutput()->setHtml(diveplan); #endif } @@ -489,6 +556,7 @@ void MainWindow::setupForAddAndPlan(const char *model) // setup the dive cylinders DivePlannerPointsModel::instance()->clear(); DivePlannerPointsModel::instance()->setupCylinders(); + locationInformationWidget()->setLocationId(0); } void MainWindow::on_actionReplanDive_triggered() @@ -503,17 +571,12 @@ void MainWindow::on_actionReplanDive_triggered() DivePlannerPointsModel::instance()->clear(); DivePlannerPointsModel::instance()->setPlanMode(DivePlannerPointsModel::PLAN); - ui.newProfile->setPlanState(); - ui.newProfile->clearHandlers(); - ui.infoPane->setCurrentIndex(PLANNERWIDGET); - ui.divePlannerWidget->setReplanButton(true); + graphics()->setPlanState(); + graphics()->clearHandlers(); + setApplicationState("PlanDive"); + divePlannerWidget()->setReplanButton(true); DivePlannerPointsModel::instance()->loadFromDive(current_dive); reset_cylinders(&displayed_dive, true); - ui.diveListPane->setCurrentIndex(1); // switch to the plan output - ui.globePane->setCurrentIndex(1); -#ifdef NO_MARBLE - ui.globePane->show(); -#endif } void MainWindow::on_actionDivePlanner_triggered() @@ -523,22 +586,20 @@ void MainWindow::on_actionDivePlanner_triggered() // put us in PLAN mode DivePlannerPointsModel::instance()->setPlanMode(DivePlannerPointsModel::PLAN); + setApplicationState("PlanDive"); - ui.newProfile->setPlanState(); - ui.infoPane->setCurrentIndex(PLANNERWIDGET); + graphics()->setPlanState(); // create a simple starting dive, using the first gas from the just copied cylidners setupForAddAndPlan("planned dive"); // don't translate, stored in XML file DivePlannerPointsModel::instance()->setupStartTime(); DivePlannerPointsModel::instance()->createSimpleDive(); DivePictureModel::instance()->updateDivePictures(); - ui.divePlannerWidget->setReplanButton(false); + divePlannerWidget()->setReplanButton(false); +} - ui.diveListPane->setCurrentIndex(1); // switch to the plan output - ui.globePane->setCurrentIndex(1); -#ifdef NO_MARBLE - ui.globePane->show(); -#endif +DivePlannerWidget* MainWindow::divePlannerWidget() { + return qobject_cast<DivePlannerWidget*>(applicationState["PlanDive"].topLeft); } void MainWindow::on_actionAddDive_triggered() @@ -551,23 +612,23 @@ void MainWindow::on_actionAddDive_triggered() dive_list()->clearSelection(); } + setApplicationState("AddDive"); DivePlannerPointsModel::instance()->setPlanMode(DivePlannerPointsModel::ADD); // setup things so we can later create our starting dive setupForAddAndPlan("manually added dive"); // don't translate, stored in the XML file // now show the mostly empty main tab - ui.InfoWidget->updateDiveInfo(); + information()->updateDiveInfo(); // show main tab - ui.InfoWidget->setCurrentIndex(0); + information()->setCurrentIndex(0); - ui.InfoWidget->addDiveStarted(); - ui.infoPane->setCurrentIndex(MAINTAB); + information()->addDiveStarted(); - ui.newProfile->setAddState(); + graphics()->setAddState(); DivePlannerPointsModel::instance()->createSimpleDive(); - ui.newProfile->plotDive(); + graphics()->plotDive(); } void MainWindow::on_actionRenumber_triggered() @@ -612,16 +673,16 @@ void MainWindow::on_actionYearlyStatistics_triggered() #define TOGGLE_COLLAPSABLE( X ) \ ui.mainSplitter->setCollapsible(0, X); \ ui.mainSplitter->setCollapsible(1, X); \ - ui.infoProfileSplitter->setCollapsible(0, X); \ - ui.infoProfileSplitter->setCollapsible(1, X); \ - ui.listGlobeSplitter->setCollapsible(0, X); \ - ui.listGlobeSplitter->setCollapsible(1, X); + ui.topSplitter->setCollapsible(0, X); \ + ui.topSplitter->setCollapsible(1, X); \ + ui.bottomSplitter->setCollapsible(0, X); \ + ui.bottomSplitter->setCollapsible(1, X); void MainWindow::on_actionViewList_triggered() { TOGGLE_COLLAPSABLE( true ); beginChangeState(LIST_MAXIMIZED); - ui.listGlobeSplitter->setSizes(BEHAVIOR << EXPANDED << COLLAPSED); + ui.topSplitter->setSizes(BEHAVIOR << EXPANDED << COLLAPSED); ui.mainSplitter->setSizes(BEHAVIOR << COLLAPSED << EXPANDED); } @@ -629,7 +690,7 @@ void MainWindow::on_actionViewProfile_triggered() { TOGGLE_COLLAPSABLE( true ); beginChangeState(PROFILE_MAXIMIZED); - ui.infoProfileSplitter->setSizes(BEHAVIOR << COLLAPSED << EXPANDED); + ui.topSplitter->setSizes(BEHAVIOR << COLLAPSED << EXPANDED); ui.mainSplitter->setSizes(BEHAVIOR << EXPANDED << COLLAPSED); } @@ -637,7 +698,7 @@ void MainWindow::on_actionViewInfo_triggered() { TOGGLE_COLLAPSABLE( true ); beginChangeState(INFO_MAXIMIZED); - ui.infoProfileSplitter->setSizes(BEHAVIOR << EXPANDED << COLLAPSED); + ui.topSplitter->setSizes(BEHAVIOR << EXPANDED << COLLAPSED); ui.mainSplitter->setSizes(BEHAVIOR << EXPANDED << COLLAPSED); } @@ -646,7 +707,7 @@ void MainWindow::on_actionViewGlobe_triggered() TOGGLE_COLLAPSABLE( true ); beginChangeState(GLOBE_MAXIMIZED); ui.mainSplitter->setSizes(BEHAVIOR << COLLAPSED << EXPANDED); - ui.listGlobeSplitter->setSizes(BEHAVIOR << COLLAPSED << EXPANDED); + ui.bottomSplitter->setSizes(BEHAVIOR << COLLAPSED << EXPANDED); } #undef BEHAVIOR @@ -677,26 +738,26 @@ void MainWindow::on_actionViewAll_triggered() settings.beginGroup("MainWindow"); if (settings.value("mainSplitter").isValid()) { ui.mainSplitter->restoreState(settings.value("mainSplitter").toByteArray()); - ui.infoProfileSplitter->restoreState(settings.value("infoProfileSplitter").toByteArray()); - ui.listGlobeSplitter->restoreState(settings.value("listGlobeSplitter").toByteArray()); + ui.topSplitter->restoreState(settings.value("topSplitter").toByteArray()); + ui.bottomSplitter->restoreState(settings.value("bottomSplitter").toByteArray()); if (ui.mainSplitter->sizes().first() == 0 || ui.mainSplitter->sizes().last() == 0) ui.mainSplitter->setSizes(mainSizes); - if (ui.infoProfileSplitter->sizes().first() == 0 || ui.infoProfileSplitter->sizes().last() == 0) - ui.infoProfileSplitter->setSizes(infoProfileSizes); - if (ui.listGlobeSplitter->sizes().first() == 0 || ui.listGlobeSplitter->sizes().last() == 0) - ui.listGlobeSplitter->setSizes(listGlobeSizes); + if (ui.topSplitter->sizes().first() == 0 || ui.topSplitter->sizes().last() == 0) + ui.topSplitter->setSizes(infoProfileSizes); + if (ui.bottomSplitter->sizes().first() == 0 || ui.bottomSplitter->sizes().last() == 0) + ui.bottomSplitter->setSizes(listGlobeSizes); } else { ui.mainSplitter->setSizes(mainSizes); - ui.infoProfileSplitter->setSizes(infoProfileSizes); - ui.listGlobeSplitter->setSizes(listGlobeSizes); + ui.topSplitter->setSizes(infoProfileSizes); + ui.bottomSplitter->setSizes(listGlobeSizes); } ui.mainSplitter->setCollapsible(0, false); ui.mainSplitter->setCollapsible(1, false); - ui.infoProfileSplitter->setCollapsible(0, false); - ui.infoProfileSplitter->setCollapsible(1, false); - ui.listGlobeSplitter->setCollapsible(0,false); - ui.listGlobeSplitter->setCollapsible(1,false); + ui.topSplitter->setCollapsible(0, false); + ui.topSplitter->setCollapsible(1, false); + ui.bottomSplitter->setCollapsible(0,false); + ui.bottomSplitter->setCollapsible(1,false); } #undef TOGGLE_COLLAPSABLE @@ -714,24 +775,24 @@ void MainWindow::saveSplitterSizes() QSettings settings; settings.beginGroup("MainWindow"); settings.setValue("mainSplitter", ui.mainSplitter->saveState()); - settings.setValue("infoProfileSplitter", ui.infoProfileSplitter->saveState()); - settings.setValue("listGlobeSplitter", ui.listGlobeSplitter->saveState()); + settings.setValue("topSplitter", ui.topSplitter->saveState()); + settings.setValue("bottomSplitter", ui.bottomSplitter->saveState()); } void MainWindow::on_actionPreviousDC_triggered() { unsigned nrdc = number_of_computers(current_dive); dc_number = (dc_number + nrdc - 1) % nrdc; - ui.newProfile->plotDive(); - ui.InfoWidget->updateDiveInfo(); + graphics()->plotDive(); + information()->updateDiveInfo(); } void MainWindow::on_actionNextDC_triggered() { unsigned nrdc = number_of_computers(current_dive); dc_number = (dc_number + 1) % nrdc; - ui.newProfile->plotDive(); - ui.InfoWidget->updateDiveInfo(); + graphics()->plotDive(); + information()->updateDiveInfo(); } void MainWindow::on_actionFullScreen_triggered(bool checked) @@ -937,7 +998,7 @@ void MainWindow::checkSurvey(QSettings *s) s->setValue("FirstUse42", value); } // wait a week for production versions, but not at all for non-tagged builds - QString ver(VERSION_STRING); + QString ver(subsurface_version()); int waitTime = 7; QDate firstUse42 = s->value("FirstUse42").toDate(); if (run_survey || (firstUse42.daysTo(QDate().currentDate()) > waitTime && !s->contains("SurveyDone"))) { @@ -965,7 +1026,7 @@ void MainWindow::writeSettings() void MainWindow::closeEvent(QCloseEvent *event) { if (DivePlannerPointsModel::instance()->currentMode() != DivePlannerPointsModel::NOTHING || - ui.InfoWidget->isEditing()) { + information()->isEditing()) { on_actionQuit_triggered(); event->ignore(); return; @@ -994,17 +1055,17 @@ void MainWindow::closeEvent(QCloseEvent *event) DiveListView *MainWindow::dive_list() { - return ui.ListWidget; + return qobject_cast<DiveListView*>(applicationState["Default"].bottomLeft); } GlobeGPS *MainWindow::globe() { - return ui.globe; + return qobject_cast<GlobeGPS*>(applicationState["Default"].bottomRight); } MainTab *MainWindow::information() { - return ui.InfoWidget; + return qobject_cast<MainTab*>(applicationState["Default"].topLeft); } void MainWindow::loadRecentFiles(QSettings *s) @@ -1179,8 +1240,8 @@ int MainWindow::file_save_as(void) if (filename.isNull() || filename.isEmpty()) return report_error("No filename to save into"); - if (ui.InfoWidget->isEditing()) - ui.InfoWidget->acceptChanges(); + if (information()->isEditing()) + information()->acceptChanges(); if (save_dives(filename.toUtf8().data())) { showError(get_error_string()); @@ -1202,8 +1263,8 @@ int MainWindow::file_save(void) if (!existing_filename) return file_save_as(); - if (ui.InfoWidget->isEditing()) - ui.InfoWidget->acceptChanges(); + if (information()->isEditing()) + information()->acceptChanges(); current_default = prefs.default_filename; if (strcmp(existing_filename, current_default) == 0) { @@ -1368,20 +1429,16 @@ void MainWindow::editCurrentDive() if (defaultDC == "manually added dive") { disableShortcuts(); DivePlannerPointsModel::instance()->setPlanMode(DivePlannerPointsModel::ADD); - ui.newProfile->setAddState(); - ui.infoPane->setCurrentIndex(MAINTAB); + graphics()->setAddState(); + setApplicationState("EditDive"); DivePlannerPointsModel::instance()->loadFromDive(d); - ui.InfoWidget->enableEdition(MainTab::MANUALLY_ADDED_DIVE); + information()->enableEdition(MainTab::MANUALLY_ADDED_DIVE); } else if (defaultDC == "planned dive") { disableShortcuts(); DivePlannerPointsModel::instance()->setPlanMode(DivePlannerPointsModel::PLAN); - //TODO: I BROKE THIS BY COMMENTING THE LINE BELOW - // and I'm sleepy now, so I think I should not try to fix right away. - // we don't setCurrentIndex anymore, we ->setPlanState() or ->setAddState() on the ProfileView. - //ui.stackedWidget->setCurrentIndex(PLANNERPROFILE); // Planner. - ui.infoPane->setCurrentIndex(PLANNERWIDGET); + setApplicationState("EditPlannedDive"); DivePlannerPointsModel::instance()->loadFromDive(d); - ui.InfoWidget->enableEdition(MainTab::MANUALLY_ADDED_DIVE); + information()->enableEdition(MainTab::MANUALLY_ADDED_DIVE); } } @@ -1456,7 +1513,7 @@ void MainWindow::on_paste_triggered() { // take the data in our copyPasteDive and apply it to selected dives selective_copy_dive(©PasteDive, &displayed_dive, what, false); - ui.InfoWidget->showAndTriggerEditSelective(what); + information()->showAndTriggerEditSelective(what); } void MainWindow::on_actionFilterTags_triggered() @@ -1466,3 +1523,43 @@ void MainWindow::on_actionFilterTags_triggered() else ui.multiFilter->setVisible(true); } + +void MainWindow::registerApplicationState(const QByteArray& state, QWidget *topLeft, QWidget *topRight, QWidget *bottomLeft, QWidget *bottomRight) +{ + applicationState[state] = WidgetForQuadrant(topLeft, topRight, bottomLeft, bottomRight); + if (ui.topLeft->indexOf(topLeft) == -1 && topLeft) { + ui.topLeft->addWidget(topLeft); + } + if (ui.topRight->indexOf(topRight) == -1 && topRight) { + ui.topRight->addWidget(topRight); + } + if (ui.bottomLeft->indexOf(bottomLeft) == -1 && bottomLeft) { + ui.bottomLeft->addWidget(bottomLeft); + } + if(ui.bottomRight->indexOf(bottomRight) == -1 && bottomRight) { + ui.bottomRight->addWidget(bottomRight); + } +} + +void MainWindow::setApplicationState(const QByteArray& state) { + if (!applicationState.keys().contains(state)) + return; + + if (currentApplicationState == state) + return; + + currentApplicationState = state; +#define SET_CURRENT_INDEX( X ) \ + if (applicationState[state].X) { \ + ui.X->setCurrentWidget( applicationState[state].X); \ + ui.X->show(); \ + } else { \ + ui.X->hide(); \ + } + + SET_CURRENT_INDEX( topLeft ) + SET_CURRENT_INDEX( topRight ) + SET_CURRENT_INDEX( bottomLeft ) + SET_CURRENT_INDEX( bottomRight ) +#undef SET_CURRENT_INDEX +} |