2013-04-14 03:44:02 +00:00
|
|
|
/*
|
|
|
|
* mainwindow.cpp
|
|
|
|
*
|
|
|
|
* classes for the main UI window in Subsurface
|
|
|
|
*/
|
2013-04-07 22:20:43 +00:00
|
|
|
#include "mainwindow.h"
|
|
|
|
|
|
|
|
#include <QVBoxLayout>
|
2013-04-13 13:17:59 +00:00
|
|
|
#include <QFileDialog>
|
|
|
|
#include <QMessageBox>
|
2013-04-09 08:35:44 +00:00
|
|
|
#include <QtDebug>
|
2013-04-18 07:59:32 +00:00
|
|
|
#include <QDateTime>
|
2013-04-27 09:09:57 +00:00
|
|
|
#include <QSettings>
|
|
|
|
#include <QCloseEvent>
|
2013-05-02 21:05:53 +00:00
|
|
|
#include <QApplication>
|
|
|
|
#include <QFontMetrics>
|
2013-06-17 23:02:30 +00:00
|
|
|
#include <QTableView>
|
2013-10-04 15:28:40 +00:00
|
|
|
#include <QDesktopWidget>
|
2013-12-05 12:02:25 +00:00
|
|
|
#include <QDesktopServices>
|
2014-02-13 21:48:07 +00:00
|
|
|
#include <QStringList>
|
|
|
|
#include <QSettings>
|
2014-04-25 04:37:47 +00:00
|
|
|
#include <QShortcut>
|
2014-06-03 08:06:18 +00:00
|
|
|
#include <QPrintDialog>
|
2014-05-25 18:56:39 +00:00
|
|
|
#include <fcntl.h>
|
2013-04-12 07:24:07 +00:00
|
|
|
#include "divelistview.h"
|
2013-04-22 23:00:27 +00:00
|
|
|
#include "starwidget.h"
|
2014-06-13 17:56:46 +00:00
|
|
|
#include "ssrf-version.h"
|
2014-04-11 08:51:07 +00:00
|
|
|
#include "dive.h"
|
|
|
|
#include "display.h"
|
|
|
|
#include "divelist.h"
|
|
|
|
#include "pref.h"
|
|
|
|
#include "helpers.h"
|
2013-04-27 15:27:27 +00:00
|
|
|
#include "modeldelegates.h"
|
2013-05-02 23:32:57 +00:00
|
|
|
#include "models.h"
|
2013-05-20 19:43:33 +00:00
|
|
|
#include "downloadfromdivecomputer.h"
|
2013-05-24 18:19:48 +00:00
|
|
|
#include "preferences.h"
|
2013-06-06 13:33:15 +00:00
|
|
|
#include "subsurfacewebservices.h"
|
2013-06-07 14:43:45 +00:00
|
|
|
#include "divecomputermanagementdialog.h"
|
2013-06-17 16:41:00 +00:00
|
|
|
#include "simplewidgets.h"
|
2013-06-20 15:33:26 +00:00
|
|
|
#include "diveplanner.h"
|
2013-06-24 11:36:38 +00:00
|
|
|
#include "about.h"
|
2014-03-30 20:14:56 +00:00
|
|
|
#include "worldmap-save.h"
|
2014-04-02 19:41:39 +00:00
|
|
|
#include "updatemanager.h"
|
2014-06-04 21:34:09 +00:00
|
|
|
#include "planner.h"
|
2014-03-26 22:36:06 +00:00
|
|
|
#ifndef NO_PRINTING
|
2013-07-09 12:37:53 +00:00
|
|
|
#include "printdialog.h"
|
2014-03-26 22:36:06 +00:00
|
|
|
#endif
|
2013-12-29 16:11:20 +00:00
|
|
|
#include "divelogimportdialog.h"
|
2014-05-20 16:33:32 +00:00
|
|
|
#include "divelogexportdialog.h"
|
2014-06-13 17:56:46 +00:00
|
|
|
#include "usersurvey.h"
|
2014-03-26 22:35:24 +00:00
|
|
|
#ifndef NO_USERMANUAL
|
|
|
|
#include "usermanual.h"
|
|
|
|
#endif
|
2013-04-13 13:17:59 +00:00
|
|
|
|
2014-02-12 14:22:54 +00:00
|
|
|
MainWindow *MainWindow::m_Instance = NULL;
|
2013-05-19 03:09:36 +00:00
|
|
|
|
2014-02-09 19:04:21 +00:00
|
|
|
MainWindow::MainWindow() : QMainWindow(),
|
|
|
|
actionNextDive(0),
|
|
|
|
actionPreviousDive(0),
|
|
|
|
helpView(0),
|
2014-03-11 16:31:00 +00:00
|
|
|
yearlyStats(0),
|
|
|
|
yearlyStatsModel(0),
|
2014-04-02 19:56:14 +00:00
|
|
|
state(VIEWALL),
|
2014-05-27 22:02:45 +00:00
|
|
|
updateManager(0),
|
2014-06-13 17:56:46 +00:00
|
|
|
fakeDiveId(0),
|
|
|
|
survey(0)
|
2013-04-07 22:20:43 +00:00
|
|
|
{
|
2014-02-19 00:47:21 +00:00
|
|
|
Q_ASSERT_X(m_Instance == NULL, "MainWindow", "MainWindow recreated!");
|
2014-02-12 14:22:54 +00:00
|
|
|
m_Instance = this;
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.setupUi(this);
|
2013-04-25 23:44:06 +00:00
|
|
|
setWindowIcon(QIcon(":subsurface-icon"));
|
2013-10-03 18:54:25 +00:00
|
|
|
connect(ui.ListWidget, SIGNAL(currentDiveChanged(int)), this, SLOT(current_dive_changed(int)));
|
2013-05-26 18:33:45 +00:00
|
|
|
connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), this, SLOT(readSettings()));
|
2013-10-03 18:54:25 +00:00
|
|
|
connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), ui.ListWidget, SLOT(update()));
|
|
|
|
connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), ui.ListWidget, SLOT(reloadHeaderActions()));
|
2013-11-20 07:08:20 +00:00
|
|
|
connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), ui.InfoWidget, SLOT(updateDiveInfo()));
|
2013-12-09 06:43:00 +00:00
|
|
|
connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), ui.divePlannerWidget, SLOT(settingsChanged()));
|
2014-01-11 14:57:06 +00:00
|
|
|
connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), TankInfoModel::instance(), SLOT(update()));
|
2014-02-13 21:48:07 +00:00
|
|
|
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)));
|
2014-05-21 23:34:06 +00:00
|
|
|
connect(information(), SIGNAL(addDiveFinished()), ui.newProfile, SLOT(setProfileState()));
|
2014-05-28 18:54:04 +00:00
|
|
|
connect(DivePlannerPointsModel::instance(), SIGNAL(planCreated()), MainWindow::instance(), SLOT(planCreated()));
|
|
|
|
connect(DivePlannerPointsModel::instance(), SIGNAL(planCanceled()), MainWindow::instance(), SLOT(planCanceled()));
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.mainErrorMessage->hide();
|
2013-06-04 12:40:09 +00:00
|
|
|
initialUiSetup();
|
2013-05-22 01:29:23 +00:00
|
|
|
readSettings();
|
2013-11-08 22:30:17 +00:00
|
|
|
ui.ListWidget->reload(DiveTripModel::TREE);
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.ListWidget->reloadHeaderActions();
|
|
|
|
ui.ListWidget->setFocus();
|
|
|
|
ui.globe->reload();
|
2014-02-14 06:11:05 +00:00
|
|
|
ui.ListWidget->expand(ui.ListWidget->model()->index(0, 0));
|
|
|
|
ui.ListWidget->scrollTo(ui.ListWidget->model()->index(0, 0), QAbstractItemView::PositionAtCenter);
|
2013-12-09 06:43:00 +00:00
|
|
|
ui.divePlannerWidget->settingsChanged();
|
2014-03-26 22:08:56 +00:00
|
|
|
#ifdef NO_MARBLE
|
|
|
|
ui.layoutWidget->hide();
|
|
|
|
ui.menuView->removeAction(ui.actionViewGlobe);
|
|
|
|
#endif
|
2014-03-26 22:35:24 +00:00
|
|
|
#ifdef NO_USERMANUAL
|
|
|
|
ui.menuHelp->removeAction(ui.actionUserManual);
|
|
|
|
#endif
|
2014-03-26 22:36:06 +00:00
|
|
|
#ifdef NO_PRINTING
|
|
|
|
ui.menuFile->removeAction(ui.actionPrint);
|
|
|
|
#endif
|
2013-05-14 11:18:26 +00:00
|
|
|
}
|
|
|
|
|
2014-02-12 14:22:54 +00:00
|
|
|
MainWindow::~MainWindow()
|
|
|
|
{
|
|
|
|
m_Instance = NULL;
|
|
|
|
}
|
|
|
|
|
2014-03-11 21:54:28 +00:00
|
|
|
void MainWindow::setLoadedWithFiles(bool f)
|
|
|
|
{
|
|
|
|
filesAsArguments = f;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MainWindow::filesFromCommandLine() const
|
|
|
|
{
|
|
|
|
return filesAsArguments;
|
|
|
|
}
|
|
|
|
|
2014-02-12 14:22:54 +00:00
|
|
|
MainWindow *MainWindow::instance()
|
|
|
|
{
|
|
|
|
return m_Instance;
|
|
|
|
}
|
|
|
|
|
2013-05-30 08:58:59 +00:00
|
|
|
// this gets called after we download dives from a divecomputer
|
2014-05-18 10:08:58 +00:00
|
|
|
void MainWindow::refreshDisplay(bool doRecreateDiveList)
|
2013-05-30 08:58:59 +00:00
|
|
|
{
|
2014-03-14 18:26:07 +00:00
|
|
|
showError(get_error_string());
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.InfoWidget->reload();
|
2013-12-28 22:56:01 +00:00
|
|
|
TankInfoModel::instance()->update();
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.globe->reload();
|
2014-05-18 10:08:58 +00:00
|
|
|
if (doRecreateDiveList)
|
|
|
|
recreateDiveList();
|
2014-06-01 03:59:36 +00:00
|
|
|
ui.diveListPane->setCurrentIndex(0); // switch to the dive list
|
2014-06-10 15:40:02 +00:00
|
|
|
ui.globePane->setCurrentIndex(0);
|
2014-05-27 22:10:22 +00:00
|
|
|
ui.ListWidget->setEnabled(true);
|
2014-05-27 22:32:45 +00:00
|
|
|
ui.ListWidget->setFocus();
|
2013-11-16 20:58:31 +00:00
|
|
|
WSInfoModel::instance()->updateInfo();
|
2014-03-11 16:31:00 +00:00
|
|
|
// refresh the yearly stats if the window has an instance
|
|
|
|
if (yearlyStats) {
|
|
|
|
if (yearlyStatsModel)
|
|
|
|
delete yearlyStatsModel;
|
|
|
|
yearlyStatsModel = new YearlyStatisticsModel();
|
|
|
|
yearlyStats->setModel(yearlyStatsModel);
|
|
|
|
}
|
2014-05-28 17:14:40 +00:00
|
|
|
if (amount_selected == 0)
|
|
|
|
cleanUpEmpty();
|
2013-05-30 08:58:59 +00:00
|
|
|
}
|
|
|
|
|
2014-05-18 10:08:58 +00:00
|
|
|
void MainWindow::recreateDiveList()
|
|
|
|
{
|
|
|
|
ui.ListWidget->reload(DiveTripModel::CURRENT);
|
|
|
|
}
|
|
|
|
|
2013-05-14 11:18:26 +00:00
|
|
|
void MainWindow::current_dive_changed(int divenr)
|
|
|
|
{
|
2013-06-05 00:51:40 +00:00
|
|
|
if (divenr >= 0) {
|
2013-05-31 12:05:33 +00:00
|
|
|
select_dive(divenr);
|
2014-05-07 20:58:07 +00:00
|
|
|
ui.globe->centerOnCurrentDive();
|
2013-05-31 12:05:33 +00:00
|
|
|
}
|
2013-05-02 23:32:57 +00:00
|
|
|
|
2014-01-15 12:47:08 +00:00
|
|
|
/* It looks like it's a bit too cumberstone to send *one* dive using a QList,
|
|
|
|
* but this is just futureproofness, it's the best way in the future to show more than
|
|
|
|
* a single profile plot on the canvas. I know that we are using only one right now,
|
|
|
|
* but let's keep like this so it's easy to change when we need? :)
|
|
|
|
*/
|
2014-02-14 06:11:05 +00:00
|
|
|
ui.newProfile->plotDives(QList<dive *>() << (current_dive));
|
2014-01-15 20:13:20 +00:00
|
|
|
ui.InfoWidget->updateDiveInfo(divenr);
|
|
|
|
}
|
|
|
|
|
2013-04-09 08:35:44 +00:00
|
|
|
void MainWindow::on_actionNew_triggered()
|
|
|
|
{
|
2013-06-26 12:07:50 +00:00
|
|
|
on_actionClose_triggered();
|
2013-04-09 08:35:44 +00:00
|
|
|
}
|
2013-04-09 16:26:23 +00:00
|
|
|
|
|
|
|
void MainWindow::on_actionOpen_triggered()
|
|
|
|
{
|
2014-06-09 02:46:43 +00:00
|
|
|
if (!okToClose(tr("Please save or cancel the current dive edit before opening a new file.")))
|
2013-11-15 21:42:49 +00:00
|
|
|
return;
|
2014-06-09 02:46:43 +00:00
|
|
|
|
2013-11-14 15:51:05 +00:00
|
|
|
QString filename = QFileDialog::getOpenFileName(this, tr("Open File"), lastUsedDir(), filter());
|
2013-04-28 03:47:47 +00:00
|
|
|
if (filename.isEmpty())
|
2013-04-13 13:17:59 +00:00
|
|
|
return;
|
2013-11-14 15:51:05 +00:00
|
|
|
updateLastUsedDir(QFileInfo(filename).dir().path());
|
2014-06-09 02:46:43 +00:00
|
|
|
closeCurrentFile();
|
2014-02-14 06:11:05 +00:00
|
|
|
loadFiles(QStringList() << filename);
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionSave_triggered()
|
|
|
|
{
|
2013-05-19 22:25:47 +00:00
|
|
|
file_save();
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionSaveAs_triggered()
|
|
|
|
{
|
2013-05-19 22:25:47 +00:00
|
|
|
file_save_as();
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
2013-09-23 05:24:28 +00:00
|
|
|
|
2014-05-22 18:40:22 +00:00
|
|
|
ProfileWidget2 *MainWindow::graphics() const
|
2014-03-07 15:42:13 +00:00
|
|
|
{
|
|
|
|
return ui.newProfile;
|
|
|
|
}
|
|
|
|
|
2013-09-23 05:24:28 +00:00
|
|
|
void MainWindow::cleanUpEmpty()
|
|
|
|
{
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.InfoWidget->clearStats();
|
|
|
|
ui.InfoWidget->clearInfo();
|
|
|
|
ui.InfoWidget->clearEquipment();
|
|
|
|
ui.InfoWidget->updateDiveInfo(-1);
|
2014-03-07 15:42:13 +00:00
|
|
|
ui.newProfile->setEmptyState();
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.ListWidget->reload(DiveTripModel::TREE);
|
|
|
|
ui.globe->reload();
|
2013-12-05 12:38:12 +00:00
|
|
|
if (!existing_filename)
|
|
|
|
setTitle(MWTF_DEFAULT);
|
2013-09-23 05:24:28 +00:00
|
|
|
}
|
|
|
|
|
2014-03-11 16:30:58 +00:00
|
|
|
void MainWindow::setToolButtonsEnabled(bool enabled)
|
|
|
|
{
|
|
|
|
ui.profPO2->setEnabled(enabled);
|
|
|
|
ui.profPn2->setEnabled(enabled);
|
|
|
|
ui.profPhe->setEnabled(enabled);
|
|
|
|
ui.profDcCeiling->setEnabled(enabled);
|
|
|
|
ui.profCalcCeiling->setEnabled(enabled);
|
|
|
|
ui.profCalcAllTissues->setEnabled(enabled);
|
|
|
|
ui.profIncrement3m->setEnabled(enabled);
|
|
|
|
ui.profMod->setEnabled(enabled);
|
|
|
|
ui.profEad->setEnabled(enabled);
|
|
|
|
ui.profNdl_tts->setEnabled(enabled);
|
|
|
|
ui.profSAC->setEnabled(enabled);
|
|
|
|
ui.profRuler->setEnabled(enabled);
|
|
|
|
ui.profScaled->setEnabled(enabled);
|
2014-04-08 04:00:50 +00:00
|
|
|
ui.profHR->setEnabled(enabled);
|
2014-03-11 16:30:58 +00:00
|
|
|
}
|
|
|
|
|
2014-06-09 02:46:43 +00:00
|
|
|
bool MainWindow::okToClose(QString message)
|
2013-04-09 16:26:23 +00:00
|
|
|
{
|
2014-01-16 04:50:56 +00:00
|
|
|
if (DivePlannerPointsModel::instance()->currentMode() != DivePlannerPointsModel::NOTHING ||
|
|
|
|
ui.InfoWidget->isEditing()) {
|
2014-06-09 02:46:43 +00:00
|
|
|
QMessageBox::warning(this, tr("Warning"), message);
|
|
|
|
return false;
|
2013-11-15 21:42:49 +00:00
|
|
|
}
|
2014-06-09 02:46:43 +00:00
|
|
|
if (unsaved_changes() && askSaveChanges() == false)
|
|
|
|
return false;
|
2013-04-13 13:17:59 +00:00
|
|
|
|
2014-06-09 02:46:43 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::closeCurrentFile()
|
|
|
|
{
|
2014-02-11 18:03:08 +00:00
|
|
|
ui.newProfile->setEmptyState();
|
2013-04-13 13:17:59 +00:00
|
|
|
/* free the dives and trips */
|
2014-03-13 22:42:45 +00:00
|
|
|
clear_git_id();
|
2013-04-13 13:17:59 +00:00
|
|
|
while (dive_table.nr)
|
|
|
|
delete_single_dive(0);
|
2013-04-28 03:47:47 +00:00
|
|
|
|
2014-05-28 20:17:20 +00:00
|
|
|
ui.ListWidget->clearSelection();
|
2013-04-13 13:17:59 +00:00
|
|
|
/* clear the selection and the statistics */
|
2013-05-16 18:42:20 +00:00
|
|
|
selected_dive = -1;
|
2013-04-13 13:17:59 +00:00
|
|
|
|
2014-05-12 17:58:15 +00:00
|
|
|
free((void *)existing_filename);
|
|
|
|
existing_filename = NULL;
|
|
|
|
|
2013-09-23 05:24:28 +00:00
|
|
|
cleanUpEmpty();
|
2014-01-15 08:30:42 +00:00
|
|
|
mark_divelist_changed(false);
|
2013-04-13 13:17:59 +00:00
|
|
|
|
|
|
|
clear_events();
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
2014-06-09 02:46:43 +00:00
|
|
|
void MainWindow::on_actionClose_triggered()
|
|
|
|
{
|
|
|
|
if (okToClose(tr("Please save or cancel the current dive edit before closing the file.")))
|
|
|
|
closeCurrentFile();
|
|
|
|
}
|
|
|
|
|
2013-11-14 15:42:26 +00:00
|
|
|
QString MainWindow::lastUsedDir()
|
2013-04-09 16:26:23 +00:00
|
|
|
{
|
2013-06-25 10:35:04 +00:00
|
|
|
QSettings settings;
|
|
|
|
QString lastDir = QDir::homePath();
|
|
|
|
|
|
|
|
settings.beginGroup("FileDialog");
|
|
|
|
if (settings.contains("LastDir"))
|
|
|
|
if (QDir::setCurrent(settings.value("LastDir").toString()))
|
|
|
|
lastDir = settings.value("LastDir").toString();
|
2013-11-14 15:42:26 +00:00
|
|
|
return lastDir;
|
|
|
|
}
|
2013-06-25 10:35:04 +00:00
|
|
|
|
2014-02-14 06:11:05 +00:00
|
|
|
void MainWindow::updateLastUsedDir(const QString &dir)
|
2013-11-14 15:42:26 +00:00
|
|
|
{
|
|
|
|
QSettings s;
|
|
|
|
s.beginGroup("FileDialog");
|
|
|
|
s.setValue("LastDir", dir);
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionPrint_triggered()
|
|
|
|
{
|
2014-03-26 22:36:06 +00:00
|
|
|
#ifndef NO_PRINTING
|
2014-02-08 19:12:13 +00:00
|
|
|
PrintDialog dlg(this);
|
|
|
|
|
|
|
|
dlg.exec();
|
2014-03-26 22:36:06 +00:00
|
|
|
#endif
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
2013-07-04 15:30:05 +00:00
|
|
|
void MainWindow::disableDcShortcuts()
|
|
|
|
{
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.actionPreviousDC->setShortcut(QKeySequence());
|
|
|
|
ui.actionNextDC->setShortcut(QKeySequence());
|
2013-07-04 15:30:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::enableDcShortcuts()
|
|
|
|
{
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.actionPreviousDC->setShortcut(Qt::Key_Left);
|
|
|
|
ui.actionNextDC->setShortcut(Qt::Key_Right);
|
2013-07-04 15:30:05 +00:00
|
|
|
}
|
|
|
|
|
2013-06-27 17:48:03 +00:00
|
|
|
void MainWindow::showProfile()
|
|
|
|
{
|
2013-07-04 15:30:05 +00:00
|
|
|
enableDcShortcuts();
|
2014-05-27 22:44:47 +00:00
|
|
|
ui.newProfile->setProfileState();
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.infoPane->setCurrentIndex(MAINTAB);
|
2013-06-20 21:48:21 +00:00
|
|
|
}
|
|
|
|
|
2013-04-09 16:26:23 +00:00
|
|
|
void MainWindow::on_actionPreferences_triggered()
|
|
|
|
{
|
2013-05-24 18:19:48 +00:00
|
|
|
PreferencesDialog::instance()->show();
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionQuit_triggered()
|
|
|
|
{
|
2014-05-06 13:56:28 +00:00
|
|
|
if (ui.InfoWidget->isEditing()) {
|
2014-06-04 01:17:32 +00:00
|
|
|
ui.InfoWidget->rejectChanges();
|
|
|
|
if (ui.InfoWidget->isEditing())
|
|
|
|
// didn't discard the edits
|
|
|
|
return;
|
2013-11-17 23:46:27 +00:00
|
|
|
}
|
2014-05-06 13:56:28 +00:00
|
|
|
if (DivePlannerPointsModel::instance()->currentMode() != DivePlannerPointsModel::NOTHING) {
|
|
|
|
DivePlannerPointsModel::instance()->cancelPlan();
|
|
|
|
if (DivePlannerPointsModel::instance()->currentMode() != DivePlannerPointsModel::NOTHING)
|
|
|
|
// The planned dive was not discarded
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-01-15 08:30:42 +00:00
|
|
|
if (unsaved_changes() && (askSaveChanges() == false))
|
2013-04-27 09:09:57 +00:00
|
|
|
return;
|
2013-05-03 23:30:36 +00:00
|
|
|
writeSettings();
|
|
|
|
QApplication::quit();
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionDownloadDC_triggered()
|
|
|
|
{
|
2014-02-08 19:22:09 +00:00
|
|
|
DownloadFromDCWidget dlg(this);
|
|
|
|
|
|
|
|
dlg.exec();
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionDownloadWeb_triggered()
|
|
|
|
{
|
2014-02-09 16:51:19 +00:00
|
|
|
SubsurfaceWebServices dlg(this);
|
|
|
|
|
|
|
|
dlg.exec();
|
2013-06-06 13:33:15 +00:00
|
|
|
}
|
2013-04-09 16:26:23 +00:00
|
|
|
|
2013-10-25 01:02:59 +00:00
|
|
|
void MainWindow::on_actionDivelogs_de_triggered()
|
|
|
|
{
|
2013-11-15 02:57:09 +00:00
|
|
|
DivelogsDeWebServices::instance()->downloadDives();
|
2013-10-25 01:02:59 +00:00
|
|
|
}
|
|
|
|
|
2013-04-09 16:26:23 +00:00
|
|
|
void MainWindow::on_actionEditDeviceNames_triggered()
|
|
|
|
{
|
2013-06-17 22:58:26 +00:00
|
|
|
DiveComputerManagementDialog::instance()->init();
|
2013-06-07 14:43:45 +00:00
|
|
|
DiveComputerManagementDialog::instance()->update();
|
|
|
|
DiveComputerManagementDialog::instance()->show();
|
2013-06-10 18:34:57 +00:00
|
|
|
}
|
2013-04-09 16:26:23 +00:00
|
|
|
|
2014-05-25 18:19:36 +00:00
|
|
|
bool MainWindow::plannerStateClean()
|
2014-05-25 18:15:57 +00:00
|
|
|
{
|
|
|
|
if (DivePlannerPointsModel::instance()->currentMode() != DivePlannerPointsModel::NOTHING ||
|
|
|
|
ui.InfoWidget->isEditing()) {
|
2014-05-25 18:19:36 +00:00
|
|
|
QMessageBox::warning(this, tr("Warning"), tr("Please save or cancel the current dive edit before trying to add a dive."));
|
|
|
|
return false;
|
2014-05-25 18:15:57 +00:00
|
|
|
}
|
2014-05-25 18:19:36 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-05-25 18:56:39 +00:00
|
|
|
void MainWindow::createFakeDiveForAddAndPlan()
|
|
|
|
{
|
|
|
|
// now cheat - create one dive that we use to store the info tab data in
|
|
|
|
//TODO: C-function create_temporary_dive ?
|
|
|
|
struct dive *dive = alloc_dive();
|
2014-05-27 22:02:45 +00:00
|
|
|
fakeDiveId = dive->id;
|
2014-05-25 18:56:39 +00:00
|
|
|
dive->when = QDateTime::currentMSecsSinceEpoch() / 1000L + gettimezoneoffset();
|
|
|
|
dive->dc.model = "manually added dive"; // don't translate! this is stored in the XML file
|
|
|
|
|
|
|
|
dive->latitude.udeg = 0;
|
|
|
|
dive->longitude.udeg = 0;
|
|
|
|
record_dive(dive);
|
2014-05-27 18:32:18 +00:00
|
|
|
// select this new dive (but remember the old selection
|
|
|
|
ui.ListWidget->rememberSelection();
|
|
|
|
ui.ListWidget->unselectDives();
|
2014-05-28 12:03:14 +00:00
|
|
|
ui.ListWidget->reload(DiveTripModel::CURRENT);
|
2014-05-27 18:32:18 +00:00
|
|
|
ui.ListWidget->selectDives(QList<int>() << dive_table.nr - 1);
|
2014-05-25 18:56:39 +00:00
|
|
|
ui.InfoWidget->updateDiveInfo(selected_dive);
|
|
|
|
}
|
|
|
|
|
2014-05-27 22:02:45 +00:00
|
|
|
void MainWindow::removeFakeDiveForAddAndPlan()
|
|
|
|
{
|
|
|
|
int idx;
|
|
|
|
|
|
|
|
if (!fakeDiveId ||
|
|
|
|
(idx = get_idx_by_uniq_id(fakeDiveId)) == dive_table.nr)
|
|
|
|
return;
|
|
|
|
delete_single_dive(idx);
|
|
|
|
}
|
|
|
|
|
2014-05-28 18:43:32 +00:00
|
|
|
void MainWindow::planCanceled()
|
|
|
|
{
|
|
|
|
removeFakeDiveForAddAndPlan();
|
|
|
|
showProfile();
|
2014-05-28 20:17:20 +00:00
|
|
|
ui.ListWidget->reload(DiveTripModel::CURRENT);
|
|
|
|
ui.ListWidget->restoreSelection();
|
2014-05-28 18:43:32 +00:00
|
|
|
refreshDisplay();
|
|
|
|
}
|
|
|
|
|
2014-05-28 18:54:04 +00:00
|
|
|
void MainWindow::planCreated()
|
|
|
|
{
|
|
|
|
removeFakeDiveForAddAndPlan();
|
|
|
|
showProfile();
|
|
|
|
refreshDisplay();
|
|
|
|
}
|
|
|
|
|
2014-06-01 04:14:44 +00:00
|
|
|
void MainWindow::setPlanNotes(const char *notes)
|
|
|
|
{
|
2014-06-03 07:35:19 +00:00
|
|
|
ui.divePlanOutput->setHtml(notes);
|
2014-06-01 04:14:44 +00:00
|
|
|
}
|
|
|
|
|
2014-06-03 08:06:18 +00:00
|
|
|
void MainWindow::printPlan()
|
|
|
|
{
|
2014-06-04 21:34:09 +00:00
|
|
|
QString diveplan = ui.divePlanOutput->toHtml();
|
|
|
|
QString withDisclaimer = diveplan + QString(disclaimer);
|
|
|
|
|
2014-06-03 08:06:18 +00:00
|
|
|
QPrinter printer;
|
|
|
|
QPrintDialog *dialog = new QPrintDialog(&printer, this);
|
|
|
|
dialog->setWindowTitle(tr("Print runtime table"));
|
|
|
|
if (dialog->exec() != QDialog::Accepted)
|
|
|
|
return;
|
|
|
|
|
2014-06-04 21:34:09 +00:00
|
|
|
ui.divePlanOutput->setHtml(withDisclaimer);
|
2014-06-03 08:06:18 +00:00
|
|
|
ui.divePlanOutput->print(&printer);
|
2014-06-04 21:34:09 +00:00
|
|
|
ui.divePlanOutput->setHtml(diveplan);
|
2014-06-03 08:06:18 +00:00
|
|
|
}
|
|
|
|
|
2014-05-25 18:19:36 +00:00
|
|
|
void MainWindow::on_actionDivePlanner_triggered()
|
|
|
|
{
|
2014-05-25 20:49:26 +00:00
|
|
|
if(!plannerStateClean())
|
2014-05-25 18:19:36 +00:00
|
|
|
return;
|
|
|
|
|
2014-05-27 18:32:18 +00:00
|
|
|
// put us in PLAN mode
|
2014-05-26 20:43:52 +00:00
|
|
|
DivePlannerPointsModel::instance()->setPlanMode(DivePlannerPointsModel::PLAN);
|
2014-05-25 18:15:57 +00:00
|
|
|
ui.newProfile->setPlanState();
|
|
|
|
ui.infoPane->setCurrentIndex(PLANNERWIDGET);
|
2014-05-27 18:32:18 +00:00
|
|
|
|
|
|
|
// set up the staging dive and clean up the widgets
|
2014-05-25 20:49:26 +00:00
|
|
|
DivePlannerPointsModel::instance()->clear();
|
2014-05-27 18:32:18 +00:00
|
|
|
|
|
|
|
// setup the staging dive cylinders from the selected dive
|
2014-05-29 00:01:18 +00:00
|
|
|
DivePlannerPointsModel::instance()->setupCylinders();
|
2014-05-27 18:32:18 +00:00
|
|
|
|
|
|
|
// create a simple starting dive, using the first gas from the just copied cylidners
|
|
|
|
createFakeDiveForAddAndPlan();
|
2014-05-27 18:28:42 +00:00
|
|
|
DivePlannerPointsModel::instance()->createSimpleDive();
|
2014-05-27 22:10:22 +00:00
|
|
|
|
2014-05-27 22:02:45 +00:00
|
|
|
// reload and then disable the dive list
|
|
|
|
ui.ListWidget->reload(DiveTripModel::CURRENT);
|
2014-05-27 22:10:22 +00:00
|
|
|
ui.ListWidget->setEnabled(false);
|
2014-06-01 03:59:36 +00:00
|
|
|
ui.diveListPane->setCurrentIndex(1); // switch to the plan output
|
2014-06-10 15:40:02 +00:00
|
|
|
ui.globePane->setCurrentIndex(1);
|
2014-05-25 18:15:57 +00:00
|
|
|
}
|
|
|
|
|
2013-04-09 16:26:23 +00:00
|
|
|
void MainWindow::on_actionAddDive_triggered()
|
|
|
|
{
|
2014-05-25 18:19:36 +00:00
|
|
|
if(!plannerStateClean())
|
2013-11-09 00:09:46 +00:00
|
|
|
return;
|
2014-05-25 18:19:36 +00:00
|
|
|
|
2013-11-09 00:09:46 +00:00
|
|
|
DivePlannerPointsModel::instance()->setPlanMode(DivePlannerPointsModel::ADD);
|
2013-11-12 07:33:27 +00:00
|
|
|
|
2014-05-25 18:56:39 +00:00
|
|
|
createFakeDiveForAddAndPlan();
|
2013-12-03 23:25:20 +00:00
|
|
|
|
2013-11-14 03:18:33 +00:00
|
|
|
ui.InfoWidget->setCurrentIndex(0);
|
2013-11-12 07:33:27 +00:00
|
|
|
ui.InfoWidget->addDiveStarted();
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.infoPane->setCurrentIndex(MAINTAB);
|
2014-05-22 02:31:26 +00:00
|
|
|
|
|
|
|
ui.newProfile->setAddState();
|
2013-11-12 07:33:27 +00:00
|
|
|
DivePlannerPointsModel::instance()->clear();
|
2013-09-20 12:36:14 +00:00
|
|
|
DivePlannerPointsModel::instance()->createSimpleDive();
|
2013-12-03 23:25:20 +00:00
|
|
|
ui.ListWidget->reload(DiveTripModel::CURRENT);
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionRenumber_triggered()
|
|
|
|
{
|
2014-05-19 21:11:32 +00:00
|
|
|
RenumberDialog::instance()->renumberOnlySelected(false);
|
2013-06-17 16:41:00 +00:00
|
|
|
RenumberDialog::instance()->show();
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionAutoGroup_triggered()
|
|
|
|
{
|
2013-10-17 23:30:32 +00:00
|
|
|
autogroup = ui.actionAutoGroup->isChecked();
|
|
|
|
if (autogroup)
|
|
|
|
autogroup_dives();
|
|
|
|
else
|
|
|
|
remove_autogen_trips();
|
|
|
|
refreshDisplay();
|
|
|
|
mark_divelist_changed(true);
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionYearlyStatistics_triggered()
|
|
|
|
{
|
2014-03-11 16:31:00 +00:00
|
|
|
// create the widget only once
|
|
|
|
if (!yearlyStats) {
|
|
|
|
yearlyStats = new QTreeView();
|
|
|
|
yearlyStats->setWindowModality(Qt::NonModal);
|
|
|
|
yearlyStats->setMinimumWidth(600);
|
|
|
|
yearlyStats->setWindowTitle(tr("Yearly Statistics"));
|
|
|
|
yearlyStats->setWindowIcon(QIcon(":subsurface-icon"));
|
2014-06-03 22:28:06 +00:00
|
|
|
QShortcut *closeKey = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_W), yearlyStats, 0, 0, Qt::WidgetShortcut);
|
2014-04-25 04:37:47 +00:00
|
|
|
connect(closeKey, SIGNAL(activated()), yearlyStats, SLOT(close()));
|
2014-06-03 22:28:06 +00:00
|
|
|
closeKey = new QShortcut(QKeySequence(Qt::Key_Escape), yearlyStats, 0, 0, Qt::WidgetShortcut);
|
2014-04-25 04:37:47 +00:00
|
|
|
connect(closeKey, SIGNAL(activated()), yearlyStats, SLOT(close()));
|
2014-06-03 22:28:06 +00:00
|
|
|
QShortcut *quitKey = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q), yearlyStats, 0, 0, Qt::WidgetShortcut);
|
2014-04-25 14:59:32 +00:00
|
|
|
connect(quitKey, SIGNAL(activated()), this, SLOT(close()));
|
2014-03-11 16:31:00 +00:00
|
|
|
}
|
|
|
|
/* problem here is that without more MainWindow variables or a separate YearlyStatistics
|
|
|
|
* class the user needs to close the window/widget and re-open it for it to update.
|
|
|
|
*/
|
|
|
|
if (yearlyStatsModel)
|
|
|
|
delete yearlyStatsModel;
|
|
|
|
yearlyStatsModel = new YearlyStatisticsModel();
|
|
|
|
yearlyStats->setModel(yearlyStatsModel);
|
|
|
|
yearlyStats->raise();
|
|
|
|
yearlyStats->show();
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
2013-06-12 18:54:55 +00:00
|
|
|
#define BEHAVIOR QList<int>()
|
2013-04-09 16:26:23 +00:00
|
|
|
void MainWindow::on_actionViewList_triggered()
|
|
|
|
{
|
2013-11-07 16:37:27 +00:00
|
|
|
beginChangeState(LIST_MAXIMIZED);
|
2014-01-16 04:50:56 +00:00
|
|
|
ui.listGlobeSplitter->setSizes(BEHAVIOR << EXPANDED << COLLAPSED);
|
|
|
|
ui.mainSplitter->setSizes(BEHAVIOR << COLLAPSED << EXPANDED);
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionViewProfile_triggered()
|
|
|
|
{
|
2013-11-07 16:37:27 +00:00
|
|
|
beginChangeState(PROFILE_MAXIMIZED);
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.infoProfileSplitter->setSizes(BEHAVIOR << COLLAPSED << EXPANDED);
|
2014-01-16 04:50:56 +00:00
|
|
|
ui.mainSplitter->setSizes(BEHAVIOR << EXPANDED << COLLAPSED);
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionViewInfo_triggered()
|
|
|
|
{
|
2013-11-07 16:37:27 +00:00
|
|
|
beginChangeState(INFO_MAXIMIZED);
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.infoProfileSplitter->setSizes(BEHAVIOR << EXPANDED << COLLAPSED);
|
2014-01-16 04:50:56 +00:00
|
|
|
ui.mainSplitter->setSizes(BEHAVIOR << EXPANDED << COLLAPSED);
|
2013-06-12 18:53:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionViewGlobe_triggered()
|
|
|
|
{
|
2013-11-07 16:37:27 +00:00
|
|
|
beginChangeState(GLOBE_MAXIMIZED);
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.mainSplitter->setSizes(BEHAVIOR << COLLAPSED << EXPANDED);
|
|
|
|
ui.listGlobeSplitter->setSizes(BEHAVIOR << COLLAPSED << EXPANDED);
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
2013-06-12 18:54:55 +00:00
|
|
|
#undef BEHAVIOR
|
2013-04-09 16:26:23 +00:00
|
|
|
|
|
|
|
void MainWindow::on_actionViewAll_triggered()
|
|
|
|
{
|
2013-11-07 16:37:27 +00:00
|
|
|
beginChangeState(VIEWALL);
|
2013-11-22 01:52:21 +00:00
|
|
|
static QList<int> mainSizes;
|
|
|
|
const int appH = qApp->desktop()->size().height();
|
|
|
|
const int appW = qApp->desktop()->size().width();
|
2014-01-16 04:50:56 +00:00
|
|
|
if (mainSizes.empty()) {
|
|
|
|
mainSizes.append(appH * 0.7);
|
|
|
|
mainSizes.append(appH * 0.3);
|
2013-11-22 01:52:21 +00:00
|
|
|
}
|
|
|
|
static QList<int> infoProfileSizes;
|
2014-01-16 04:50:56 +00:00
|
|
|
if (infoProfileSizes.empty()) {
|
|
|
|
infoProfileSizes.append(appW * 0.3);
|
|
|
|
infoProfileSizes.append(appW * 0.7);
|
2013-11-22 01:52:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static QList<int> listGlobeSizes;
|
2014-01-16 04:50:56 +00:00
|
|
|
if (listGlobeSizes.empty()) {
|
|
|
|
listGlobeSizes.append(appW * 0.7);
|
|
|
|
listGlobeSizes.append(appW * 0.3);
|
2013-11-22 01:52:21 +00:00
|
|
|
}
|
|
|
|
|
2013-11-07 16:37:27 +00:00
|
|
|
QSettings settings;
|
|
|
|
settings.beginGroup("MainWindow");
|
2014-01-16 04:50:56 +00:00
|
|
|
if (settings.value("mainSplitter").isValid()) {
|
2013-11-07 16:37:27 +00:00
|
|
|
ui.mainSplitter->restoreState(settings.value("mainSplitter").toByteArray());
|
|
|
|
ui.infoProfileSplitter->restoreState(settings.value("infoProfileSplitter").toByteArray());
|
|
|
|
ui.listGlobeSplitter->restoreState(settings.value("listGlobeSplitter").toByteArray());
|
2014-01-16 04:50:56 +00:00
|
|
|
if (ui.mainSplitter->sizes().first() == 0 || ui.mainSplitter->sizes().last() == 0)
|
2013-11-22 01:52:21 +00:00
|
|
|
ui.mainSplitter->setSizes(mainSizes);
|
2014-01-16 04:50:56 +00:00
|
|
|
if (ui.infoProfileSplitter->sizes().first() == 0 || ui.infoProfileSplitter->sizes().last() == 0)
|
2013-11-22 01:52:21 +00:00
|
|
|
ui.infoProfileSplitter->setSizes(infoProfileSizes);
|
2014-01-16 04:50:56 +00:00
|
|
|
if (ui.listGlobeSplitter->sizes().first() == 0 || ui.listGlobeSplitter->sizes().last() == 0)
|
2013-11-22 01:52:21 +00:00
|
|
|
ui.listGlobeSplitter->setSizes(listGlobeSizes);
|
|
|
|
|
2013-11-07 16:37:27 +00:00
|
|
|
} else {
|
2014-01-16 04:50:56 +00:00
|
|
|
ui.mainSplitter->setSizes(mainSizes);
|
2013-11-07 16:37:27 +00:00
|
|
|
ui.infoProfileSplitter->setSizes(infoProfileSizes);
|
|
|
|
ui.listGlobeSplitter->setSizes(listGlobeSizes);
|
|
|
|
}
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
2014-02-14 06:11:05 +00:00
|
|
|
void MainWindow::beginChangeState(CurrentState s)
|
|
|
|
{
|
2014-01-16 04:50:56 +00:00
|
|
|
if (state == VIEWALL && state != s) {
|
2013-11-07 16:37:27 +00:00
|
|
|
saveSplitterSizes();
|
|
|
|
}
|
|
|
|
state = s;
|
|
|
|
}
|
|
|
|
|
2014-02-14 06:11:05 +00:00
|
|
|
void MainWindow::saveSplitterSizes()
|
|
|
|
{
|
2013-11-07 16:37:27 +00:00
|
|
|
QSettings settings;
|
|
|
|
settings.beginGroup("MainWindow");
|
|
|
|
settings.setValue("mainSplitter", ui.mainSplitter->saveState());
|
|
|
|
settings.setValue("infoProfileSplitter", ui.infoProfileSplitter->saveState());
|
|
|
|
settings.setValue("listGlobeSplitter", ui.listGlobeSplitter->saveState());
|
|
|
|
}
|
|
|
|
|
2013-04-09 16:26:23 +00:00
|
|
|
void MainWindow::on_actionPreviousDC_triggered()
|
|
|
|
{
|
2014-03-17 15:19:09 +00:00
|
|
|
unsigned nrdc = number_of_computers(current_dive);
|
|
|
|
dc_number = (dc_number + nrdc - 1) % nrdc;
|
2013-11-20 06:50:02 +00:00
|
|
|
ui.InfoWidget->updateDiveInfo(selected_dive);
|
2014-02-14 06:11:05 +00:00
|
|
|
ui.newProfile->plotDives(QList<struct dive *>() << (current_dive));
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionNextDC_triggered()
|
|
|
|
{
|
2014-03-17 15:19:09 +00:00
|
|
|
unsigned nrdc = number_of_computers(current_dive);
|
|
|
|
dc_number = (dc_number + 1) % nrdc;
|
2013-11-20 06:50:02 +00:00
|
|
|
ui.InfoWidget->updateDiveInfo(selected_dive);
|
2014-02-14 06:11:05 +00:00
|
|
|
ui.newProfile->plotDives(QList<struct dive *>() << (current_dive));
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
2014-01-14 17:36:07 +00:00
|
|
|
void MainWindow::on_actionFullScreen_triggered(bool checked)
|
|
|
|
{
|
|
|
|
if (checked) {
|
|
|
|
setWindowState(windowState() | Qt::WindowFullScreen);
|
2014-01-16 04:50:56 +00:00
|
|
|
} else {
|
2014-01-14 17:36:07 +00:00
|
|
|
setWindowState(windowState() & ~Qt::WindowFullScreen);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-09 16:26:23 +00:00
|
|
|
void MainWindow::on_actionSelectEvents_triggered()
|
|
|
|
{
|
2013-04-10 06:27:38 +00:00
|
|
|
qDebug("actionSelectEvents");
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionInputPlan_triggered()
|
|
|
|
{
|
2013-04-10 06:27:38 +00:00
|
|
|
qDebug("actionInputPlan");
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionAboutSubsurface_triggered()
|
|
|
|
{
|
2014-02-08 07:50:39 +00:00
|
|
|
SubsurfaceAbout dlg(this);
|
|
|
|
|
|
|
|
dlg.exec();
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
2014-04-02 19:41:39 +00:00
|
|
|
void MainWindow::on_action_Check_for_Updates_triggered()
|
|
|
|
{
|
2014-04-02 19:56:14 +00:00
|
|
|
if (!updateManager)
|
|
|
|
updateManager = new UpdateManager(this);
|
|
|
|
|
2014-04-02 19:41:39 +00:00
|
|
|
updateManager->checkForUpdates();
|
|
|
|
}
|
|
|
|
|
2013-04-09 16:26:23 +00:00
|
|
|
void MainWindow::on_actionUserManual_triggered()
|
|
|
|
{
|
2014-03-26 22:35:24 +00:00
|
|
|
#ifndef NO_USERMANUAL
|
2014-01-16 04:50:56 +00:00
|
|
|
if (!helpView) {
|
2014-04-24 23:19:09 +00:00
|
|
|
helpView = new UserManual(this);
|
2013-05-30 21:26:08 +00:00
|
|
|
}
|
2013-05-30 13:54:06 +00:00
|
|
|
helpView->show();
|
2014-03-26 22:35:24 +00:00
|
|
|
#endif
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
2013-04-13 13:17:59 +00:00
|
|
|
|
|
|
|
QString MainWindow::filter()
|
|
|
|
{
|
|
|
|
QString f;
|
2013-10-02 06:34:12 +00:00
|
|
|
f += "ALL ( *.ssrf *.xml *.XML *.uddf *.udcf *.UDFC *.jlb *.JLB ";
|
2013-04-13 13:17:59 +00:00
|
|
|
f += "*.sde *.SDE *.dld *.DLD ";
|
|
|
|
f += "*.db";
|
|
|
|
f += ");;";
|
|
|
|
|
2013-10-02 06:34:12 +00:00
|
|
|
f += "Subsurface (*.ssrf);;";
|
2013-04-13 13:17:59 +00:00
|
|
|
f += "XML (*.xml *.XML);;";
|
|
|
|
f += "UDDF (*.uddf);;";
|
|
|
|
f += "UDCF (*.udcf *.UDCF);;";
|
|
|
|
f += "JLB (*.jlb *.JLB);;";
|
|
|
|
|
|
|
|
f += "SDE (*.sde *.SDE);;";
|
|
|
|
f += "DLD (*.dld *.DLD);;";
|
|
|
|
f += "DB (*.db)";
|
|
|
|
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MainWindow::askSaveChanges()
|
|
|
|
{
|
2013-05-19 21:46:53 +00:00
|
|
|
QString message;
|
2014-03-14 23:00:18 +00:00
|
|
|
QMessageBox response(MainWindow::instance());
|
2013-04-13 13:17:59 +00:00
|
|
|
|
2013-05-19 21:46:53 +00:00
|
|
|
if (existing_filename)
|
2013-05-24 07:28:48 +00:00
|
|
|
message = tr("Do you want to save the changes you made in the file %1?").arg(existing_filename);
|
2013-05-19 21:46:53 +00:00
|
|
|
else
|
2013-05-24 07:28:48 +00:00
|
|
|
message = tr("Do you want to save the changes you made in the datafile?");
|
|
|
|
|
|
|
|
response.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
|
|
|
|
response.setDefaultButton(QMessageBox::Save);
|
|
|
|
response.setText(message);
|
|
|
|
response.setWindowTitle(tr("Save Changes?")); // Not displayed on MacOSX as described in Qt API
|
|
|
|
response.setInformativeText(tr("Changes will be lost if you don't save them."));
|
|
|
|
response.setIcon(QMessageBox::Warning);
|
2014-03-14 23:00:18 +00:00
|
|
|
response.setWindowModality(Qt::WindowModal);
|
2013-05-24 07:28:48 +00:00
|
|
|
int ret = response.exec();
|
|
|
|
|
|
|
|
switch (ret) {
|
|
|
|
case QMessageBox::Save:
|
2013-05-19 22:25:47 +00:00
|
|
|
file_save();
|
2013-04-13 13:17:59 +00:00
|
|
|
return true;
|
2013-05-24 07:28:48 +00:00
|
|
|
case QMessageBox::Discard:
|
2013-05-19 21:46:53 +00:00
|
|
|
return true;
|
2013-04-13 13:17:59 +00:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2013-04-27 09:09:57 +00:00
|
|
|
|
2013-06-04 12:40:09 +00:00
|
|
|
void MainWindow::initialUiSetup()
|
2013-04-27 09:09:57 +00:00
|
|
|
{
|
2013-05-22 02:07:19 +00:00
|
|
|
QSettings settings;
|
2013-04-28 09:05:37 +00:00
|
|
|
settings.beginGroup("MainWindow");
|
2013-10-04 15:28:40 +00:00
|
|
|
QSize sz = settings.value("size", qApp->desktop()->size()).value<QSize>();
|
2013-12-02 10:32:27 +00:00
|
|
|
if (settings.value("maximized", isMaximized()).value<bool>())
|
|
|
|
showMaximized();
|
|
|
|
else
|
|
|
|
resize(sz);
|
2013-10-04 18:07:36 +00:00
|
|
|
|
2014-02-14 06:11:05 +00:00
|
|
|
state = (CurrentState)settings.value("lastState", 0).toInt();
|
2014-01-16 04:50:56 +00:00
|
|
|
switch (state) {
|
2014-02-14 06:11:05 +00:00
|
|
|
case VIEWALL:
|
|
|
|
on_actionViewAll_triggered();
|
|
|
|
break;
|
|
|
|
case GLOBE_MAXIMIZED:
|
|
|
|
on_actionViewGlobe_triggered();
|
|
|
|
break;
|
|
|
|
case INFO_MAXIMIZED:
|
|
|
|
on_actionViewInfo_triggered();
|
|
|
|
break;
|
|
|
|
case LIST_MAXIMIZED:
|
|
|
|
on_actionViewList_triggered();
|
|
|
|
break;
|
|
|
|
case PROFILE_MAXIMIZED:
|
|
|
|
on_actionViewProfile_triggered();
|
|
|
|
break;
|
2013-10-04 18:07:36 +00:00
|
|
|
}
|
2013-11-08 21:59:21 +00:00
|
|
|
settings.endGroup();
|
2013-06-04 12:40:09 +00:00
|
|
|
}
|
|
|
|
|
2014-06-12 18:52:59 +00:00
|
|
|
const char *getSetting(QSettings &s, QString name)
|
|
|
|
{
|
|
|
|
QVariant v;
|
|
|
|
v = s.value(name);
|
|
|
|
if (v.isValid()) {
|
|
|
|
return strdup(v.toString().toUtf8().data());
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2014-03-02 21:37:29 +00:00
|
|
|
#define TOOLBOX_PREF_BUTTON(pref, setting, button) \
|
2014-03-03 21:25:55 +00:00
|
|
|
prefs.pref = s.value(#setting).toBool(); \
|
2014-03-02 21:37:29 +00:00
|
|
|
ui.button->setChecked(prefs.pref);
|
|
|
|
|
2013-06-04 12:40:09 +00:00
|
|
|
void MainWindow::readSettings()
|
|
|
|
{
|
|
|
|
QSettings s;
|
|
|
|
s.beginGroup("Display");
|
2014-03-21 17:56:10 +00:00
|
|
|
QFont defaultFont = QFont(default_prefs.divelist_font);
|
|
|
|
defaultFont = s.value("divelist_font", defaultFont).value<QFont>();
|
|
|
|
defaultFont.setPointSizeF(s.value("font_size", default_prefs.font_size).toFloat());
|
2013-12-18 21:06:51 +00:00
|
|
|
qApp->setFont(defaultFont);
|
2014-02-06 16:59:06 +00:00
|
|
|
s.endGroup();
|
|
|
|
|
|
|
|
s.beginGroup("TecDetails");
|
2014-04-16 20:03:44 +00:00
|
|
|
TOOLBOX_PREF_BUTTON(calcalltissues, calcalltissues, profCalcAllTissues);
|
|
|
|
TOOLBOX_PREF_BUTTON(calcceiling, calcceiling, profCalcCeiling);
|
|
|
|
TOOLBOX_PREF_BUTTON(dcceiling, dcceiling, profDcCeiling);
|
2014-03-02 21:37:29 +00:00
|
|
|
TOOLBOX_PREF_BUTTON(ead, ead, profEad);
|
2014-04-16 20:03:44 +00:00
|
|
|
TOOLBOX_PREF_BUTTON(calcceiling3m, calcceiling3m, profIncrement3m);
|
2014-03-02 21:37:29 +00:00
|
|
|
TOOLBOX_PREF_BUTTON(mod, mod, profMod);
|
2014-04-16 20:03:44 +00:00
|
|
|
TOOLBOX_PREF_BUTTON(calcndltts, calcndltts, profNdl_tts);
|
2014-03-02 21:37:29 +00:00
|
|
|
TOOLBOX_PREF_BUTTON(pp_graphs.phe, phegraph, profPhe);
|
|
|
|
TOOLBOX_PREF_BUTTON(pp_graphs.pn2, pn2graph, profPn2);
|
|
|
|
TOOLBOX_PREF_BUTTON(pp_graphs.po2, po2graph, profPO2);
|
2014-04-16 20:03:44 +00:00
|
|
|
TOOLBOX_PREF_BUTTON(hrgraph, hrgraph, profHR);
|
2014-05-05 22:53:46 +00:00
|
|
|
TOOLBOX_PREF_BUTTON(rulergraph, rulergraph, profRuler);
|
2014-03-02 21:37:29 +00:00
|
|
|
TOOLBOX_PREF_BUTTON(show_sac, show_sac, profSAC);
|
2014-06-12 18:52:59 +00:00
|
|
|
s.endGroup();
|
|
|
|
s.beginGroup("DiveComputer");
|
|
|
|
default_dive_computer_vendor = getSetting(s, "dive_computer_vendor");
|
|
|
|
default_dive_computer_product = getSetting(s, "dive_computer_product");
|
|
|
|
default_dive_computer_device = getSetting(s, "dive_computer_device");
|
|
|
|
s.endGroup();
|
|
|
|
loadRecentFiles(&s);
|
2014-06-13 17:56:46 +00:00
|
|
|
checkSurvey(&s);
|
2013-04-27 09:09:57 +00:00
|
|
|
}
|
|
|
|
|
2014-03-02 21:37:29 +00:00
|
|
|
#undef TOOLBOX_PREF_BUTTON
|
|
|
|
|
2014-06-13 17:56:46 +00:00
|
|
|
void MainWindow::checkSurvey(QSettings *s)
|
|
|
|
{
|
|
|
|
s->beginGroup("UserSurvey");
|
|
|
|
if (!s->contains("FirstUse42")) {
|
|
|
|
QVariant value = QDate().currentDate();
|
|
|
|
s->setValue("FirstUse42", value);
|
2014-06-14 21:45:42 +00:00
|
|
|
}
|
|
|
|
// wait a week for production versions, but not at all for non-tagged builds
|
|
|
|
QString ver(VERSION_STRING);
|
|
|
|
int waitTime = ver.contains('-') ? -1 : 7;
|
|
|
|
QDate firstUse42 = s->value("FirstUse42").toDate();
|
|
|
|
if (run_survey || (firstUse42.daysTo(QDate().currentDate()) > waitTime && !s->contains("SurveyDone"))) {
|
|
|
|
if (!survey)
|
|
|
|
survey = new UserSurvey(this);
|
|
|
|
survey->show();
|
2014-06-13 17:56:46 +00:00
|
|
|
}
|
|
|
|
s->endGroup();
|
|
|
|
}
|
|
|
|
|
2013-04-27 09:09:57 +00:00
|
|
|
void MainWindow::writeSettings()
|
|
|
|
{
|
2013-05-22 02:07:19 +00:00
|
|
|
QSettings settings;
|
2013-05-03 05:06:01 +00:00
|
|
|
|
2013-04-27 09:09:57 +00:00
|
|
|
settings.beginGroup("MainWindow");
|
2014-02-14 06:11:05 +00:00
|
|
|
settings.setValue("lastState", (int)state);
|
2013-12-02 10:32:27 +00:00
|
|
|
settings.setValue("maximized", isMaximized());
|
|
|
|
if (!isMaximized())
|
|
|
|
settings.setValue("size", size());
|
2014-01-16 04:50:56 +00:00
|
|
|
if (state == VIEWALL)
|
2013-11-07 16:37:27 +00:00
|
|
|
saveSplitterSizes();
|
2013-04-27 09:09:57 +00:00
|
|
|
settings.endGroup();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::closeEvent(QCloseEvent *event)
|
|
|
|
{
|
2014-01-16 04:50:56 +00:00
|
|
|
if (DivePlannerPointsModel::instance()->currentMode() != DivePlannerPointsModel::NOTHING ||
|
|
|
|
ui.InfoWidget->isEditing()) {
|
2014-06-04 01:22:22 +00:00
|
|
|
on_actionQuit_triggered();
|
2013-12-17 00:37:44 +00:00
|
|
|
event->ignore();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-01-16 04:50:56 +00:00
|
|
|
if (helpView && helpView->isVisible()) {
|
2013-05-30 13:54:06 +00:00
|
|
|
helpView->close();
|
|
|
|
helpView->deleteLater();
|
|
|
|
}
|
2013-05-30 21:26:08 +00:00
|
|
|
|
2014-03-11 16:31:00 +00:00
|
|
|
if (yearlyStats && yearlyStats->isVisible()) {
|
|
|
|
yearlyStats->close();
|
|
|
|
yearlyStats->deleteLater();
|
|
|
|
yearlyStatsModel->deleteLater();
|
|
|
|
}
|
|
|
|
|
2014-01-15 08:30:42 +00:00
|
|
|
if (unsaved_changes() && (askSaveChanges() == false)) {
|
2013-04-27 09:09:57 +00:00
|
|
|
event->ignore();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
event->accept();
|
|
|
|
writeSettings();
|
2014-03-11 16:31:01 +00:00
|
|
|
QApplication::closeAllWindows();
|
2013-04-28 03:47:47 +00:00
|
|
|
}
|
2013-05-19 03:09:36 +00:00
|
|
|
|
2014-02-14 06:11:05 +00:00
|
|
|
DiveListView *MainWindow::dive_list()
|
2013-05-19 03:09:36 +00:00
|
|
|
{
|
2013-10-03 18:54:25 +00:00
|
|
|
return ui.ListWidget;
|
2013-05-19 03:09:36 +00:00
|
|
|
}
|
|
|
|
|
2014-02-14 06:11:05 +00:00
|
|
|
GlobeGPS *MainWindow::globe()
|
2013-05-19 03:09:36 +00:00
|
|
|
{
|
2013-10-03 18:54:25 +00:00
|
|
|
return ui.globe;
|
2013-05-19 03:09:36 +00:00
|
|
|
}
|
|
|
|
|
2014-02-14 06:11:05 +00:00
|
|
|
MainTab *MainWindow::information()
|
2013-05-19 03:09:36 +00:00
|
|
|
{
|
2013-10-03 18:54:25 +00:00
|
|
|
return ui.InfoWidget;
|
2013-05-19 03:09:36 +00:00
|
|
|
}
|
2013-05-19 22:25:47 +00:00
|
|
|
|
2014-02-13 21:48:07 +00:00
|
|
|
void MainWindow::loadRecentFiles(QSettings *s)
|
|
|
|
{
|
|
|
|
QStringList files;
|
|
|
|
bool modified = false;
|
|
|
|
|
|
|
|
s->beginGroup("Recent_Files");
|
2014-02-14 06:11:05 +00:00
|
|
|
for (int c = 1; c <= 4; c++) {
|
2014-02-13 21:48:07 +00:00
|
|
|
QString key = QString("File_%1").arg(c);
|
2014-02-14 06:11:05 +00:00
|
|
|
if (s->contains(key)) {
|
2014-02-13 21:48:07 +00:00
|
|
|
QString file = s->value(key).toString();
|
|
|
|
|
2014-02-14 06:11:05 +00:00
|
|
|
if (QFile::exists(file)) {
|
2014-02-13 21:48:07 +00:00
|
|
|
files.append(file);
|
2014-02-14 06:11:05 +00:00
|
|
|
} else {
|
2014-02-13 21:48:07 +00:00
|
|
|
modified = true;
|
|
|
|
}
|
2014-02-14 06:11:05 +00:00
|
|
|
} else {
|
2014-02-13 21:48:07 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-14 06:11:05 +00:00
|
|
|
if (modified) {
|
|
|
|
for (int c = 0; c < 4; c++) {
|
2014-02-13 21:48:07 +00:00
|
|
|
QString key = QString("File_%1").arg(c + 1);
|
|
|
|
|
2014-02-14 06:11:05 +00:00
|
|
|
if (files.count() > c) {
|
2014-02-13 21:48:07 +00:00
|
|
|
s->setValue(key, files.at(c));
|
2014-02-14 06:11:05 +00:00
|
|
|
} else {
|
|
|
|
if (s->contains(key)) {
|
2014-02-13 21:48:07 +00:00
|
|
|
s->remove(key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
s->sync();
|
|
|
|
}
|
|
|
|
s->endGroup();
|
|
|
|
|
2014-02-14 06:11:05 +00:00
|
|
|
for (int c = 0; c < 4; c++) {
|
2014-02-13 21:48:07 +00:00
|
|
|
QAction *action = this->findChild<QAction *>(QString("actionRecent%1").arg(c + 1));
|
|
|
|
|
2014-02-14 06:11:05 +00:00
|
|
|
if (files.count() > c) {
|
2014-02-13 21:48:07 +00:00
|
|
|
QFileInfo fi(files.at(c));
|
|
|
|
action->setText(fi.fileName());
|
|
|
|
action->setToolTip(fi.absoluteFilePath());
|
|
|
|
action->setVisible(true);
|
2014-02-14 06:11:05 +00:00
|
|
|
} else {
|
2014-02-13 21:48:07 +00:00
|
|
|
action->setVisible(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::addRecentFile(const QStringList &newFiles)
|
|
|
|
{
|
|
|
|
QStringList files;
|
|
|
|
QSettings s;
|
|
|
|
|
2014-02-28 09:04:00 +00:00
|
|
|
if (newFiles.isEmpty())
|
2014-02-13 21:48:07 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
s.beginGroup("Recent_Files");
|
|
|
|
|
2014-02-14 06:11:05 +00:00
|
|
|
for (int c = 1; c <= 4; c++) {
|
2014-02-13 21:48:07 +00:00
|
|
|
QString key = QString("File_%1").arg(c);
|
2014-02-14 06:11:05 +00:00
|
|
|
if (s.contains(key)) {
|
2014-02-13 21:48:07 +00:00
|
|
|
QString file = s.value(key).toString();
|
|
|
|
|
|
|
|
files.append(file);
|
2014-02-14 06:11:05 +00:00
|
|
|
} else {
|
2014-02-13 21:48:07 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-22 18:40:22 +00:00
|
|
|
foreach (const QString &file, newFiles) {
|
2014-02-13 21:48:07 +00:00
|
|
|
int index = files.indexOf(file);
|
|
|
|
|
2014-02-14 06:11:05 +00:00
|
|
|
if (index >= 0) {
|
2014-02-13 21:48:07 +00:00
|
|
|
files.removeAt(index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-22 18:40:22 +00:00
|
|
|
foreach (const QString &file, newFiles) {
|
2014-02-14 06:11:05 +00:00
|
|
|
if (QFile::exists(file)) {
|
2014-02-13 21:48:07 +00:00
|
|
|
files.prepend(file);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-14 06:11:05 +00:00
|
|
|
while (files.count() > 4) {
|
2014-02-13 21:48:07 +00:00
|
|
|
files.removeLast();
|
|
|
|
}
|
|
|
|
|
2014-02-28 09:04:00 +00:00
|
|
|
for (int c = 1; c <= 4; c++) {
|
|
|
|
QString key = QString("File_%1").arg(c);
|
2014-02-13 21:48:07 +00:00
|
|
|
|
2014-02-28 09:04:00 +00:00
|
|
|
if (files.count() >= c) {
|
|
|
|
s.setValue(key, files.at(c - 1));
|
2014-02-14 06:11:05 +00:00
|
|
|
} else {
|
|
|
|
if (s.contains(key)) {
|
2014-02-13 21:48:07 +00:00
|
|
|
s.remove(key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
s.endGroup();
|
|
|
|
s.sync();
|
|
|
|
|
|
|
|
loadRecentFiles(&s);
|
|
|
|
}
|
|
|
|
|
2014-02-28 09:04:00 +00:00
|
|
|
void MainWindow::removeRecentFile(QStringList failedFiles)
|
|
|
|
{
|
|
|
|
QStringList files;
|
|
|
|
QSettings s;
|
|
|
|
|
|
|
|
if (failedFiles.isEmpty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
s.beginGroup("Recent_Files");
|
|
|
|
|
|
|
|
for (int c = 1; c <= 4; c++) {
|
|
|
|
QString key = QString("File_%1").arg(c);
|
|
|
|
|
|
|
|
if (s.contains(key)) {
|
|
|
|
QString file = s.value(key).toString();
|
|
|
|
files.append(file);
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-22 18:40:22 +00:00
|
|
|
foreach (QString file, failedFiles)
|
2014-02-28 09:04:00 +00:00
|
|
|
files.removeAll(file);
|
|
|
|
|
|
|
|
for (int c = 1; c <= 4; c++) {
|
|
|
|
QString key = QString("File_%1").arg(c);
|
|
|
|
|
|
|
|
if (files.count() >= c) {
|
|
|
|
s.setValue(key, files.at(c - 1));
|
|
|
|
} else {
|
|
|
|
if (s.contains(key))
|
|
|
|
s.remove(key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
s.endGroup();
|
|
|
|
s.sync();
|
|
|
|
|
|
|
|
loadRecentFiles(&s);
|
|
|
|
}
|
|
|
|
|
2014-02-13 21:48:07 +00:00
|
|
|
void MainWindow::recentFileTriggered(bool checked)
|
|
|
|
{
|
|
|
|
Q_UNUSED(checked);
|
|
|
|
|
2014-06-09 02:46:43 +00:00
|
|
|
if (!okToClose(tr("Please save or cancel the current dive edit before opening a new file.")))
|
|
|
|
return;
|
|
|
|
|
2014-02-13 21:48:07 +00:00
|
|
|
QAction *actionRecent = (QAction *)sender();
|
|
|
|
|
|
|
|
const QString &filename = actionRecent->toolTip();
|
|
|
|
|
|
|
|
updateLastUsedDir(QFileInfo(filename).dir().path());
|
2014-06-09 02:46:43 +00:00
|
|
|
closeCurrentFile();
|
2014-02-13 21:48:07 +00:00
|
|
|
loadFiles(QStringList() << filename);
|
|
|
|
}
|
|
|
|
|
2014-03-14 17:19:23 +00:00
|
|
|
int MainWindow::file_save_as(void)
|
2013-05-19 22:25:47 +00:00
|
|
|
{
|
|
|
|
QString filename;
|
2014-05-13 21:13:03 +00:00
|
|
|
const char *default_filename = existing_filename;
|
2013-05-19 22:25:47 +00:00
|
|
|
filename = QFileDialog::getSaveFileName(this, tr("Save File as"), default_filename,
|
|
|
|
tr("Subsurface XML files (*.ssrf *.xml *.XML)"));
|
2014-03-14 17:19:23 +00:00
|
|
|
if (filename.isNull() || filename.isEmpty())
|
|
|
|
return report_error("No filename to save into");
|
2013-11-23 02:40:48 +00:00
|
|
|
|
2014-03-14 17:19:23 +00:00
|
|
|
if (ui.InfoWidget->isEditing())
|
|
|
|
ui.InfoWidget->acceptChanges();
|
2013-11-23 02:40:48 +00:00
|
|
|
|
2014-03-14 17:35:09 +00:00
|
|
|
if (save_dives(filename.toUtf8().data())) {
|
|
|
|
showError(get_error_string());
|
2014-03-14 17:19:23 +00:00
|
|
|
return -1;
|
2014-03-14 17:35:09 +00:00
|
|
|
}
|
2014-03-14 17:19:23 +00:00
|
|
|
|
2014-03-19 20:28:47 +00:00
|
|
|
showError(get_error_string());
|
2014-03-14 17:19:23 +00:00
|
|
|
set_filename(filename.toUtf8().data(), true);
|
|
|
|
setTitle(MWTF_FILENAME);
|
|
|
|
mark_divelist_changed(false);
|
|
|
|
addRecentFile(QStringList() << filename);
|
|
|
|
return 0;
|
2013-05-19 22:25:47 +00:00
|
|
|
}
|
|
|
|
|
2014-03-14 17:19:23 +00:00
|
|
|
int MainWindow::file_save(void)
|
2013-05-19 22:25:47 +00:00
|
|
|
{
|
|
|
|
const char *current_default;
|
|
|
|
|
|
|
|
if (!existing_filename)
|
|
|
|
return file_save_as();
|
|
|
|
|
2014-01-16 04:50:56 +00:00
|
|
|
if (ui.InfoWidget->isEditing())
|
2013-11-23 02:40:48 +00:00
|
|
|
ui.InfoWidget->acceptChanges();
|
|
|
|
|
2013-05-19 22:25:47 +00:00
|
|
|
current_default = prefs.default_filename;
|
2014-02-14 06:11:05 +00:00
|
|
|
if (strcmp(existing_filename, current_default) == 0) {
|
2013-05-19 22:25:47 +00:00
|
|
|
/* if we are using the default filename the directory
|
|
|
|
* that we are creating the file in may not exist */
|
2013-05-20 00:18:44 +00:00
|
|
|
QDir current_def_dir = QFileInfo(current_default).absoluteDir();
|
|
|
|
if (!current_def_dir.exists())
|
|
|
|
current_def_dir.mkpath(current_def_dir.absolutePath());
|
2013-05-19 22:25:47 +00:00
|
|
|
}
|
2014-03-14 17:35:09 +00:00
|
|
|
if (save_dives(existing_filename)) {
|
|
|
|
showError(get_error_string());
|
2014-03-14 17:19:23 +00:00
|
|
|
return -1;
|
2014-03-14 17:35:09 +00:00
|
|
|
}
|
2014-03-19 20:28:47 +00:00
|
|
|
showError(get_error_string());
|
2014-01-15 08:30:42 +00:00
|
|
|
mark_divelist_changed(false);
|
2014-02-13 21:48:07 +00:00
|
|
|
addRecentFile(QStringList() << QString(existing_filename));
|
2014-03-14 17:19:23 +00:00
|
|
|
return 0;
|
2013-05-19 22:25:47 +00:00
|
|
|
}
|
2013-05-22 06:13:45 +00:00
|
|
|
|
|
|
|
void MainWindow::showError(QString message)
|
|
|
|
{
|
|
|
|
if (message.isEmpty())
|
|
|
|
return;
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.mainErrorMessage->setText(message);
|
|
|
|
ui.mainErrorMessage->setCloseButtonVisible(true);
|
|
|
|
ui.mainErrorMessage->setMessageType(KMessageWidget::Error);
|
|
|
|
ui.mainErrorMessage->animatedShow();
|
2013-05-22 06:13:45 +00:00
|
|
|
}
|
2013-06-26 12:13:06 +00:00
|
|
|
|
|
|
|
void MainWindow::setTitle(enum MainWindowTitleFormat format)
|
|
|
|
{
|
|
|
|
switch (format) {
|
|
|
|
case MWTF_DEFAULT:
|
|
|
|
setWindowTitle("Subsurface");
|
|
|
|
break;
|
|
|
|
case MWTF_FILENAME:
|
2013-12-05 12:38:12 +00:00
|
|
|
if (!existing_filename) {
|
|
|
|
setTitle(MWTF_DEFAULT);
|
|
|
|
return;
|
|
|
|
}
|
2013-06-26 12:13:06 +00:00
|
|
|
QFile f(existing_filename);
|
|
|
|
QFileInfo fileInfo(f);
|
|
|
|
QString fileName(fileInfo.fileName());
|
|
|
|
setWindowTitle("Subsurface: " + fileName);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-09-09 08:59:03 +00:00
|
|
|
|
|
|
|
void MainWindow::importFiles(const QStringList fileNames)
|
|
|
|
{
|
2013-10-04 15:12:46 +00:00
|
|
|
if (fileNames.isEmpty())
|
|
|
|
return;
|
|
|
|
|
2013-09-09 08:59:03 +00:00
|
|
|
QByteArray fileNamePtr;
|
2014-03-14 18:26:07 +00:00
|
|
|
|
2013-09-09 08:59:03 +00:00
|
|
|
for (int i = 0; i < fileNames.size(); ++i) {
|
2013-12-20 01:02:34 +00:00
|
|
|
fileNamePtr = QFile::encodeName(fileNames.at(i));
|
2014-03-14 18:26:07 +00:00
|
|
|
parse_file(fileNamePtr.data());
|
2013-09-09 08:59:03 +00:00
|
|
|
}
|
2014-01-15 08:30:42 +00:00
|
|
|
process_dives(true, false);
|
2013-11-01 13:43:41 +00:00
|
|
|
refreshDisplay();
|
2013-09-09 08:59:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::loadFiles(const QStringList fileNames)
|
|
|
|
{
|
2013-10-04 15:12:46 +00:00
|
|
|
if (fileNames.isEmpty())
|
|
|
|
return;
|
|
|
|
|
2013-09-09 08:59:03 +00:00
|
|
|
QByteArray fileNamePtr;
|
2014-02-28 09:04:00 +00:00
|
|
|
QStringList failedParses;
|
2013-09-09 08:59:03 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < fileNames.size(); ++i) {
|
2014-03-14 18:26:07 +00:00
|
|
|
int error;
|
2013-09-09 08:59:03 +00:00
|
|
|
|
2014-03-14 18:26:07 +00:00
|
|
|
fileNamePtr = QFile::encodeName(fileNames.at(i));
|
|
|
|
error = parse_file(fileNamePtr.data());
|
|
|
|
if (!error) {
|
|
|
|
set_filename(fileNamePtr.data(), true);
|
|
|
|
setTitle(MWTF_FILENAME);
|
|
|
|
} else {
|
2014-02-28 09:04:00 +00:00
|
|
|
failedParses.append(fileNames.at(i));
|
2013-09-09 08:59:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-15 08:30:42 +00:00
|
|
|
process_dives(false, false);
|
2014-02-13 21:48:07 +00:00
|
|
|
addRecentFile(fileNames);
|
2014-02-28 09:04:00 +00:00
|
|
|
removeRecentFile(failedParses);
|
2013-09-09 08:59:03 +00:00
|
|
|
|
2013-11-01 13:43:41 +00:00
|
|
|
refreshDisplay();
|
2013-10-17 23:30:32 +00:00
|
|
|
ui.actionAutoGroup->setChecked(autogroup);
|
2013-09-09 08:59:03 +00:00
|
|
|
}
|
2013-10-16 19:05:19 +00:00
|
|
|
|
2013-12-29 16:11:20 +00:00
|
|
|
void MainWindow::on_actionImportDiveLog_triggered()
|
2013-10-16 19:05:19 +00:00
|
|
|
{
|
2014-01-07 20:01:28 +00:00
|
|
|
QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Open Dive Log File"), lastUsedDir(), tr("Dive Log Files (*.xml *.uddf *.udcf *.csv *.jlb *.dld *.sde *.db);;XML Files (*.xml);;UDDF/UDCF Files(*.uddf *.udcf);;JDiveLog Files(*.jlb);;Suunto Files(*.sde *.db);;CSV Files(*.csv);;All Files(*)"));
|
|
|
|
|
|
|
|
if (fileNames.isEmpty())
|
|
|
|
return;
|
|
|
|
updateLastUsedDir(QFileInfo(fileNames[0]).dir().path());
|
|
|
|
|
2014-02-14 06:11:05 +00:00
|
|
|
QStringList logFiles = fileNames.filter(QRegExp("^.*\\.(?!csv)", Qt::CaseInsensitive));
|
2014-01-07 20:01:28 +00:00
|
|
|
QStringList csvFiles = fileNames.filter(".csv", Qt::CaseInsensitive);
|
|
|
|
if (logFiles.size()) {
|
|
|
|
importFiles(logFiles);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (csvFiles.size()) {
|
2014-04-25 17:44:23 +00:00
|
|
|
DiveLogImportDialog *diveLogImport = new DiveLogImportDialog(&csvFiles, this);
|
2014-01-07 20:01:28 +00:00
|
|
|
diveLogImport->show();
|
2014-01-15 08:30:42 +00:00
|
|
|
process_dives(true, false);
|
2014-01-07 20:01:28 +00:00
|
|
|
refreshDisplay();
|
|
|
|
}
|
2013-10-16 19:05:19 +00:00
|
|
|
}
|
2013-11-01 15:48:34 +00:00
|
|
|
|
|
|
|
void MainWindow::editCurrentDive()
|
|
|
|
{
|
2014-01-16 04:50:56 +00:00
|
|
|
if (information()->isEditing() || DivePlannerPointsModel::instance()->currentMode() != DivePlannerPointsModel::NOTHING) {
|
2014-02-26 14:59:06 +00:00
|
|
|
QMessageBox::warning(this, tr("Warning"), tr("Please, first finish the current edition before trying to do another."));
|
2013-11-09 00:09:46 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-11-01 15:48:34 +00:00
|
|
|
struct dive *d = current_dive;
|
|
|
|
QString defaultDC(d->dc.model);
|
2013-11-09 00:09:46 +00:00
|
|
|
DivePlannerPointsModel::instance()->clear();
|
2014-01-16 04:50:56 +00:00
|
|
|
if (defaultDC == "manually added dive") {
|
2013-11-01 15:48:34 +00:00
|
|
|
disableDcShortcuts();
|
2013-11-09 00:09:46 +00:00
|
|
|
DivePlannerPointsModel::instance()->setPlanMode(DivePlannerPointsModel::ADD);
|
2014-05-25 03:51:05 +00:00
|
|
|
//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.
|
2013-11-01 15:48:34 +00:00
|
|
|
ui.infoPane->setCurrentIndex(MAINTAB);
|
|
|
|
DivePlannerPointsModel::instance()->loadFromDive(d);
|
|
|
|
ui.InfoWidget->enableEdition(MainTab::MANUALLY_ADDED_DIVE);
|
2014-01-16 04:50:56 +00:00
|
|
|
} else if (defaultDC == "planned dive") {
|
2013-12-07 15:25:43 +00:00
|
|
|
disableDcShortcuts();
|
|
|
|
DivePlannerPointsModel::instance()->setPlanMode(DivePlannerPointsModel::PLAN);
|
2014-05-25 03:51:05 +00:00
|
|
|
//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.
|
2013-12-07 15:25:43 +00:00
|
|
|
ui.infoPane->setCurrentIndex(PLANNERWIDGET);
|
|
|
|
DivePlannerPointsModel::instance()->loadFromDive(d);
|
|
|
|
ui.InfoWidget->enableEdition(MainTab::MANUALLY_ADDED_DIVE);
|
2013-11-01 15:48:34 +00:00
|
|
|
}
|
|
|
|
}
|
2014-02-06 13:38:28 +00:00
|
|
|
|
2014-02-14 06:11:05 +00:00
|
|
|
#define TOOLBOX_PREF_PROFILE(PREFS) \
|
|
|
|
QSettings s; \
|
|
|
|
s.beginGroup("TecDetails"); \
|
2014-02-06 13:38:28 +00:00
|
|
|
s.setValue(#PREFS, triggered); \
|
|
|
|
PreferencesDialog::instance()->emitSettingsChanged();
|
|
|
|
|
2014-03-02 18:37:07 +00:00
|
|
|
void MainWindow::on_profCalcAllTissues_clicked(bool triggered)
|
2014-02-06 13:38:28 +00:00
|
|
|
{
|
2014-04-16 20:03:44 +00:00
|
|
|
prefs.calcalltissues = triggered;
|
2014-02-06 13:38:28 +00:00
|
|
|
TOOLBOX_PREF_PROFILE(calcalltissues);
|
|
|
|
}
|
2014-03-02 18:37:07 +00:00
|
|
|
void MainWindow::on_profCalcCeiling_clicked(bool triggered)
|
2014-02-06 13:38:28 +00:00
|
|
|
{
|
2014-04-16 20:03:44 +00:00
|
|
|
prefs.calcceiling = triggered;
|
2014-02-06 13:38:28 +00:00
|
|
|
TOOLBOX_PREF_PROFILE(calcceiling);
|
|
|
|
}
|
2014-03-02 18:37:07 +00:00
|
|
|
void MainWindow::on_profDcCeiling_clicked(bool triggered)
|
2014-02-06 13:38:28 +00:00
|
|
|
{
|
2014-04-16 20:03:44 +00:00
|
|
|
prefs.dcceiling = triggered;
|
2014-02-06 13:38:28 +00:00
|
|
|
TOOLBOX_PREF_PROFILE(dcceiling);
|
|
|
|
}
|
2014-03-02 18:37:07 +00:00
|
|
|
void MainWindow::on_profEad_clicked(bool triggered)
|
2014-02-06 13:38:28 +00:00
|
|
|
{
|
2014-02-06 16:51:20 +00:00
|
|
|
prefs.ead = triggered;
|
2014-02-06 13:38:28 +00:00
|
|
|
TOOLBOX_PREF_PROFILE(ead);
|
|
|
|
}
|
2014-03-02 18:37:07 +00:00
|
|
|
void MainWindow::on_profIncrement3m_clicked(bool triggered)
|
2014-02-06 13:38:28 +00:00
|
|
|
{
|
2014-04-16 20:03:44 +00:00
|
|
|
prefs.calcceiling3m = triggered;
|
2014-02-06 13:38:28 +00:00
|
|
|
TOOLBOX_PREF_PROFILE(calcceiling3m);
|
|
|
|
}
|
2014-03-02 18:37:07 +00:00
|
|
|
void MainWindow::on_profMod_clicked(bool triggered)
|
2014-02-06 13:38:28 +00:00
|
|
|
{
|
2014-02-06 16:51:20 +00:00
|
|
|
prefs.mod = triggered;
|
2014-02-06 13:38:28 +00:00
|
|
|
TOOLBOX_PREF_PROFILE(mod);
|
|
|
|
}
|
2014-03-02 17:40:05 +00:00
|
|
|
void MainWindow::on_profNdl_tts_clicked(bool triggered)
|
2014-02-06 13:38:28 +00:00
|
|
|
{
|
2014-04-16 20:03:44 +00:00
|
|
|
prefs.calcndltts = triggered;
|
2014-02-06 13:38:28 +00:00
|
|
|
TOOLBOX_PREF_PROFILE(calcndltts);
|
|
|
|
}
|
2014-06-04 20:41:50 +00:00
|
|
|
void MainWindow::turnOffNdlTts()
|
|
|
|
{
|
2014-06-09 21:05:59 +00:00
|
|
|
const bool triggered = false;
|
|
|
|
prefs.calcndltts = triggered;
|
2014-06-04 20:41:50 +00:00
|
|
|
TOOLBOX_PREF_PROFILE(calcndltts);
|
|
|
|
}
|
|
|
|
|
2014-03-02 18:37:07 +00:00
|
|
|
void MainWindow::on_profPhe_clicked(bool triggered)
|
2014-02-06 13:38:28 +00:00
|
|
|
{
|
2014-02-06 16:51:20 +00:00
|
|
|
prefs.pp_graphs.phe = triggered;
|
2014-02-06 13:38:28 +00:00
|
|
|
TOOLBOX_PREF_PROFILE(phegraph);
|
|
|
|
}
|
2014-03-02 18:37:07 +00:00
|
|
|
void MainWindow::on_profPn2_clicked(bool triggered)
|
2014-02-06 13:38:28 +00:00
|
|
|
{
|
2014-02-06 16:51:20 +00:00
|
|
|
prefs.pp_graphs.pn2 = triggered;
|
2014-02-06 13:38:28 +00:00
|
|
|
TOOLBOX_PREF_PROFILE(pn2graph);
|
|
|
|
}
|
2014-03-02 18:37:07 +00:00
|
|
|
void MainWindow::on_profPO2_clicked(bool triggered)
|
2014-02-06 13:38:28 +00:00
|
|
|
{
|
2014-02-06 16:51:20 +00:00
|
|
|
prefs.pp_graphs.po2 = triggered;
|
2014-02-06 13:38:28 +00:00
|
|
|
TOOLBOX_PREF_PROFILE(po2graph);
|
|
|
|
}
|
2014-04-08 04:00:50 +00:00
|
|
|
void MainWindow::on_profHR_clicked(bool triggered)
|
|
|
|
{
|
2014-04-16 20:03:44 +00:00
|
|
|
prefs.hrgraph = triggered;
|
2014-04-08 04:00:50 +00:00
|
|
|
TOOLBOX_PREF_PROFILE(hrgraph);
|
|
|
|
}
|
2014-03-02 18:37:07 +00:00
|
|
|
void MainWindow::on_profRuler_clicked(bool triggered)
|
2014-02-06 13:38:28 +00:00
|
|
|
{
|
2014-05-05 22:53:46 +00:00
|
|
|
prefs.rulergraph = triggered;
|
2014-02-06 13:38:28 +00:00
|
|
|
TOOLBOX_PREF_PROFILE(rulergraph);
|
|
|
|
}
|
2014-03-02 18:37:07 +00:00
|
|
|
void MainWindow::on_profSAC_clicked(bool triggered)
|
2014-02-06 13:38:28 +00:00
|
|
|
{
|
2014-02-06 16:51:20 +00:00
|
|
|
prefs.show_sac = triggered;
|
2014-02-06 13:38:28 +00:00
|
|
|
TOOLBOX_PREF_PROFILE(show_sac);
|
|
|
|
}
|
2014-02-06 16:51:20 +00:00
|
|
|
|
2014-03-02 18:37:07 +00:00
|
|
|
void MainWindow::on_profScaled_clicked(bool triggered)
|
2014-02-27 15:31:00 +00:00
|
|
|
{
|
|
|
|
prefs.zoomed_plot = triggered;
|
|
|
|
TOOLBOX_PREF_PROFILE(zoomed_plot);
|
|
|
|
}
|
|
|
|
|
2014-02-08 07:50:39 +00:00
|
|
|
#undef TOOLBOX_PREF_PROFILE
|
2014-05-20 16:33:32 +00:00
|
|
|
|
|
|
|
void MainWindow::on_actionExport_triggered()
|
|
|
|
{
|
2014-05-21 12:41:46 +00:00
|
|
|
DiveLogExportDialog *diveLogExport = new DiveLogExportDialog(this);
|
2014-05-20 16:33:32 +00:00
|
|
|
diveLogExport->show();
|
|
|
|
}
|