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-08-22 19:20:47 +00:00
|
|
|
#include <QWebView>
|
2013-06-17 23:02:30 +00:00
|
|
|
#include <QTableView>
|
2013-10-04 15:28:40 +00:00
|
|
|
#include <QDesktopWidget>
|
2013-04-12 07:24:07 +00:00
|
|
|
#include "divelistview.h"
|
2013-04-22 23:00:27 +00:00
|
|
|
#include "starwidget.h"
|
2013-04-12 07:24:07 +00:00
|
|
|
|
2013-04-13 13:17:59 +00:00
|
|
|
#include "../dive.h"
|
|
|
|
#include "../divelist.h"
|
|
|
|
#include "../pref.h"
|
2013-05-30 21:26:08 +00:00
|
|
|
#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"
|
2013-07-09 12:37:53 +00:00
|
|
|
#include "printdialog.h"
|
2013-10-16 19:05:19 +00:00
|
|
|
#include "csvimportdialog.h"
|
2013-04-13 13:17:59 +00:00
|
|
|
|
2013-05-19 03:09:36 +00:00
|
|
|
static MainWindow* instance = 0;
|
|
|
|
|
|
|
|
MainWindow* mainWindow()
|
|
|
|
{
|
|
|
|
return instance;
|
|
|
|
}
|
|
|
|
|
2013-10-03 18:54:25 +00:00
|
|
|
MainWindow::MainWindow() : helpView(0)
|
2013-04-07 22:20:43 +00:00
|
|
|
{
|
2013-09-16 14:38:41 +00:00
|
|
|
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()));
|
|
|
|
connect(PreferencesDialog::instance(), SIGNAL(settingsChanged()), ui.ProfileWidget, SLOT(refresh()));
|
|
|
|
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();
|
2013-11-08 22:46:25 +00:00
|
|
|
ui.ListWidget->expand(ui.ListWidget->model()->index(0,0));
|
|
|
|
ui.ListWidget->scrollTo(ui.ListWidget->model()->index(0,0), QAbstractItemView::PositionAtCenter);
|
2013-05-14 11:18:26 +00:00
|
|
|
}
|
|
|
|
|
2013-05-30 08:58:59 +00:00
|
|
|
// this gets called after we download dives from a divecomputer
|
2013-11-14 08:52:03 +00:00
|
|
|
void MainWindow::refreshDisplay(bool recreateDiveList)
|
2013-05-30 08:58:59 +00:00
|
|
|
{
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.InfoWidget->reload();
|
2013-11-12 05:41:29 +00:00
|
|
|
ui.ProfileWidget->refresh();
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.globe->reload();
|
2013-11-14 08:52:03 +00:00
|
|
|
if (recreateDiveList)
|
|
|
|
ui.ListWidget->reload(DiveTripModel::CURRENT);
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.ListWidget->setFocus();
|
Fix SIGSEGV after dive computer download
This fixes a crash in the current Qt subsurface code that can happen
after downloading dives from a dive computer, and the new dives merge
with old dives, causing the old dives to be re-allocated into the
merged one.
In that case, the list widgets don't get fully updated, and contain
stale pointers to old dives that no longer exists. Doing anything that
refreshes the display will hide this problem, and you do need to have
multiple dive computers on the same dive to trigger it in the first
place, so it's reasonably hard to hit, but very annoying when you do.
This patch just makes us reload all the dive UI tables, which may be
overkill. It also doesn't actually fix the fact that we seem to do
"process_dives()" within the context of the downloader thread, which
looks like a possible source of races. The "process_dives()" should
also be moved to the main thread, but needs the preferDownloaded()
information that is part of the download window, so it doesn't fit
here. Somebody else (Tomaz?) will hopefully fix that part.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2013-09-17 21:19:20 +00:00
|
|
|
WSInfoModel *wsim = WSInfoModel::instance();
|
|
|
|
wsim->updateInfo();
|
2013-05-30 08:58:59 +00:00
|
|
|
}
|
|
|
|
|
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);
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.globe->centerOn(get_dive(selected_dive));
|
2013-05-31 12:05:33 +00:00
|
|
|
redrawProfile();
|
|
|
|
}
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.InfoWidget->updateDiveInfo(divenr);
|
2013-05-02 23:32:57 +00:00
|
|
|
}
|
|
|
|
|
2013-05-10 17:45:13 +00:00
|
|
|
void MainWindow::redrawProfile()
|
|
|
|
{
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.ProfileWidget->refresh();
|
2013-05-10 17:45:13 +00:00
|
|
|
}
|
|
|
|
|
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()
|
|
|
|
{
|
2013-11-15 21:42:49 +00:00
|
|
|
if (ui.InfoWidget->isEditing()) {
|
|
|
|
QMessageBox::warning(this, tr("Warning"), "Please save or undo the current dive edit before opening a new file." );
|
|
|
|
return;
|
|
|
|
}
|
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());
|
2013-04-13 13:17:59 +00:00
|
|
|
on_actionClose_triggered();
|
2013-09-09 08:59:03 +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
|
|
|
|
|
|
|
void MainWindow::cleanUpEmpty()
|
|
|
|
{
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.InfoWidget->clearStats();
|
|
|
|
ui.InfoWidget->clearInfo();
|
|
|
|
ui.InfoWidget->clearEquipment();
|
|
|
|
ui.InfoWidget->updateDiveInfo(-1);
|
|
|
|
ui.ProfileWidget->clear();
|
|
|
|
ui.ListWidget->reload(DiveTripModel::TREE);
|
|
|
|
ui.globe->reload();
|
2013-09-23 05:24:28 +00:00
|
|
|
setTitle(MWTF_DEFAULT);
|
|
|
|
}
|
|
|
|
|
2013-04-09 16:26:23 +00:00
|
|
|
void MainWindow::on_actionClose_triggered()
|
|
|
|
{
|
2013-11-15 21:42:49 +00:00
|
|
|
if (ui.InfoWidget->isEditing()) {
|
|
|
|
QMessageBox::warning(this, tr("Warning"), "Please save or undo the current dive edit before closing the file." );
|
|
|
|
return;
|
|
|
|
}
|
2013-04-13 13:17:59 +00:00
|
|
|
if (unsaved_changes() && (askSaveChanges() == FALSE))
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* free the dives and trips */
|
|
|
|
while (dive_table.nr)
|
|
|
|
delete_single_dive(0);
|
2013-04-28 03:47:47 +00:00
|
|
|
|
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
|
|
|
|
2013-11-15 20:35:12 +00:00
|
|
|
existing_filename = NULL;
|
2013-09-23 05:24:28 +00:00
|
|
|
cleanUpEmpty();
|
2013-06-27 12:33:44 +00:00
|
|
|
mark_divelist_changed(FALSE);
|
2013-04-13 13:17:59 +00:00
|
|
|
|
|
|
|
clear_events();
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionImport_triggered()
|
2013-11-14 15:42:26 +00:00
|
|
|
{
|
2013-11-14 15:51:05 +00:00
|
|
|
QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Import Files"), lastUsedDir(), filter());
|
2013-11-14 15:42:26 +00:00
|
|
|
if (!fileNames.size())
|
|
|
|
return; // no selection
|
|
|
|
updateLastUsedDir(QFileInfo(fileNames.at(0)).dir().path());
|
|
|
|
importFiles(fileNames);
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
2013-11-14 15:42:26 +00:00
|
|
|
void MainWindow::updateLastUsedDir(const QString& dir)
|
|
|
|
{
|
|
|
|
QSettings s;
|
|
|
|
s.beginGroup("FileDialog");
|
|
|
|
s.setValue("LastDir", dir);
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionExportUDDF_triggered()
|
|
|
|
{
|
2013-10-19 17:35:36 +00:00
|
|
|
QFileInfo fi(system_default_filename());
|
2013-11-14 15:51:05 +00:00
|
|
|
QString filename = QFileDialog::getSaveFileName(this, tr("Save File as"), fi.absolutePath(),
|
2013-10-19 17:35:36 +00:00
|
|
|
tr("UDDF files (*.uddf *.UDDF)"));
|
|
|
|
if (!filename.isNull() && !filename.isEmpty())
|
2013-11-15 01:58:09 +00:00
|
|
|
export_dives_uddf(filename.toUtf8(), false);
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionPrint_triggered()
|
|
|
|
{
|
2013-07-09 12:37:53 +00:00
|
|
|
PrintDialog::instance()->runDialog();
|
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-20 21:48:21 +00:00
|
|
|
void MainWindow::on_actionDivePlanner_triggered()
|
|
|
|
{
|
2013-11-15 21:42:49 +00:00
|
|
|
if(DivePlannerPointsModel::instance()->currentMode() != DivePlannerPointsModel::NOTHING ||
|
|
|
|
ui.InfoWidget->isEditing()) {
|
|
|
|
QMessageBox::warning(this, tr("Warning"), "Please save or undo the current dive edit before trying to plan a dive." );
|
2013-11-09 00:09:46 +00:00
|
|
|
return;
|
|
|
|
}
|
2013-07-04 15:30:05 +00:00
|
|
|
disableDcShortcuts();
|
2013-11-09 00:09:46 +00:00
|
|
|
DivePlannerPointsModel::instance()->setPlanMode(DivePlannerPointsModel::PLAN);
|
|
|
|
DivePlannerPointsModel::instance()->clear();
|
2013-11-09 22:06:26 +00:00
|
|
|
CylindersModel::instance()->clear();
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.stackedWidget->setCurrentIndex(PLANNERPROFILE);
|
|
|
|
ui.infoPane->setCurrentIndex(PLANNERWIDGET);
|
2013-06-27 17:48:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::showProfile()
|
|
|
|
{
|
2013-07-04 15:30:05 +00:00
|
|
|
enableDcShortcuts();
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.stackedWidget->setCurrentIndex(PROFILE);
|
|
|
|
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()
|
|
|
|
{
|
2013-04-27 09:09:57 +00:00
|
|
|
if (unsaved_changes() && (askSaveChanges() == FALSE))
|
|
|
|
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()
|
|
|
|
{
|
2013-05-30 08:58:59 +00:00
|
|
|
DownloadFromDCWidget* downloadWidget = DownloadFromDCWidget::instance();
|
|
|
|
downloadWidget->runDialog();
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionDownloadWeb_triggered()
|
|
|
|
{
|
2013-10-25 00:30:21 +00:00
|
|
|
SubsurfaceWebServices::instance()->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()
|
|
|
|
{
|
|
|
|
DivelogsDeWebServices::instance()->exec();
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
|
|
|
void MainWindow::on_actionAddDive_triggered()
|
|
|
|
{
|
2013-11-15 21:42:49 +00:00
|
|
|
if(DivePlannerPointsModel::instance()->currentMode() != DivePlannerPointsModel::NOTHING ||
|
|
|
|
ui.InfoWidget->isEditing()) {
|
|
|
|
QMessageBox::warning(this, tr("Warning"), "Please save or undo the current dive edit before trying to add a dive." );
|
2013-11-09 00:09:46 +00:00
|
|
|
return;
|
|
|
|
}
|
2013-11-14 08:52:03 +00:00
|
|
|
dive_list()->rememberSelection();
|
2013-11-12 05:21:50 +00:00
|
|
|
dive_list()->unselectDives();
|
2013-09-19 02:33:53 +00:00
|
|
|
disableDcShortcuts();
|
2013-11-09 00:09:46 +00:00
|
|
|
DivePlannerPointsModel::instance()->setPlanMode(DivePlannerPointsModel::ADD);
|
2013-11-12 07:33:27 +00:00
|
|
|
|
2013-09-19 04:33:39 +00:00
|
|
|
// now cheat - create one dive that we use to store the info tab data in
|
|
|
|
struct dive *dive = alloc_dive();
|
2013-11-07 07:33:10 +00:00
|
|
|
dive->when = QDateTime::currentMSecsSinceEpoch() / 1000L + gettimezoneoffset();
|
2013-11-07 07:52:39 +00:00
|
|
|
dive->dc.model = "manually added dive"; // don't translate! this is stored in the XML file
|
2013-09-19 04:33:39 +00:00
|
|
|
record_dive(dive);
|
2013-11-12 05:21:50 +00:00
|
|
|
// this isn't in the UI yet, so let's call the C helper function - we'll fix this up when
|
|
|
|
// accepting the dive
|
2013-09-19 04:33:39 +00:00
|
|
|
select_dive(get_divenr(dive));
|
2013-11-14 03:18:33 +00:00
|
|
|
ui.InfoWidget->setCurrentIndex(0);
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.InfoWidget->updateDiveInfo(selected_dive);
|
2013-11-12 07:33:27 +00:00
|
|
|
ui.InfoWidget->addDiveStarted();
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.stackedWidget->setCurrentIndex(PLANNERPROFILE); // Planner.
|
|
|
|
ui.infoPane->setCurrentIndex(MAINTAB);
|
2013-11-12 07:33:27 +00:00
|
|
|
DivePlannerPointsModel::instance()->clear();
|
2013-09-20 12:36:14 +00:00
|
|
|
DivePlannerPointsModel::instance()->createSimpleDive();
|
2013-09-19 04:33:39 +00:00
|
|
|
refreshDisplay();
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionRenumber_triggered()
|
|
|
|
{
|
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_actionToggleZoom_triggered()
|
|
|
|
{
|
2013-09-08 18:50:09 +00:00
|
|
|
zoomed_plot = !zoomed_plot;
|
2013-10-03 18:54:25 +00:00
|
|
|
ui.ProfileWidget->refresh();
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionYearlyStatistics_triggered()
|
|
|
|
{
|
2013-06-18 00:05:17 +00:00
|
|
|
QTreeView *view = new QTreeView();
|
2013-06-17 23:02:30 +00:00
|
|
|
QAbstractItemModel *model = new YearlyStatisticsModel();
|
|
|
|
view->setModel(model);
|
2013-06-19 17:59:48 +00:00
|
|
|
view->setWindowModality(Qt::NonModal);
|
|
|
|
view->setMinimumWidth(600);
|
2013-06-28 12:20:42 +00:00
|
|
|
view->setAttribute(Qt::WA_QuitOnClose, false);
|
2013-06-17 23:02:30 +00:00
|
|
|
view->show();
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
2013-07-05 12:33:51 +00:00
|
|
|
void MainWindow::on_mainSplitter_splitterMoved(int pos, int idx)
|
|
|
|
{
|
|
|
|
redrawProfile();
|
|
|
|
}
|
|
|
|
|
2013-06-27 12:33:43 +00:00
|
|
|
void MainWindow::on_infoProfileSplitter_splitterMoved(int pos, int idx)
|
|
|
|
{
|
2013-07-05 12:33:51 +00:00
|
|
|
redrawProfile();
|
2013-06-27 12:33:43 +00:00
|
|
|
}
|
|
|
|
|
2013-06-12 18:54:55 +00:00
|
|
|
/**
|
|
|
|
* So, here's the deal.
|
|
|
|
* We have a few QSplitters that takes care of helping us with the
|
|
|
|
* size of a few widgets, they are ok, and we should continue using them
|
|
|
|
* to manage the visibility of them too. But the way that we did before was to
|
|
|
|
* widget->hide(); something, and if you hided something using the splitter,
|
|
|
|
* by holding it's handle and collapsing the widget, then you used the 'ctrl+number'
|
|
|
|
* shortcut to show it, it whould only show a gray panel.
|
|
|
|
*
|
|
|
|
* This patch makes everything behave using the splitters.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#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);
|
2013-10-03 18:54:25 +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);
|
|
|
|
ui.mainSplitter->setSizes( BEHAVIOR << EXPANDED << COLLAPSED);
|
2013-07-05 12:33:51 +00:00
|
|
|
redrawProfile();
|
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);
|
|
|
|
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);
|
|
|
|
QSettings settings;
|
|
|
|
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());
|
|
|
|
} else {
|
|
|
|
QList<int> mainSizes;
|
|
|
|
mainSizes.append( qApp->desktop()->size().height() * 0.7 );
|
|
|
|
mainSizes.append( qApp->desktop()->size().height() * 0.3 );
|
|
|
|
ui.mainSplitter->setSizes( mainSizes );
|
2013-06-12 18:54:55 +00:00
|
|
|
|
2013-11-07 16:37:27 +00:00
|
|
|
QList<int> infoProfileSizes;
|
|
|
|
infoProfileSizes.append( qApp->desktop()->size().width() * 0.3 );
|
|
|
|
infoProfileSizes.append( qApp->desktop()->size().width() * 0.7 );
|
|
|
|
ui.infoProfileSplitter->setSizes(infoProfileSizes);
|
2013-06-12 18:54:55 +00:00
|
|
|
|
2013-11-07 16:37:27 +00:00
|
|
|
QList<int> listGlobeSizes;
|
|
|
|
listGlobeSizes.append( qApp->desktop()->size().width() * 0.7 );
|
|
|
|
listGlobeSizes.append( qApp->desktop()->size().width() * 0.3 );
|
|
|
|
ui.listGlobeSplitter->setSizes(listGlobeSizes);
|
|
|
|
}
|
2013-07-05 12:33:51 +00:00
|
|
|
redrawProfile();
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
2013-11-07 16:37:27 +00:00
|
|
|
void MainWindow::beginChangeState(CurrentState s){
|
2013-11-12 20:25:49 +00:00
|
|
|
if (state == VIEWALL && state != s){
|
2013-11-07 16:37:27 +00:00
|
|
|
saveSplitterSizes();
|
|
|
|
}
|
|
|
|
state = s;
|
|
|
|
}
|
|
|
|
|
|
|
|
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());
|
|
|
|
}
|
|
|
|
|
2013-04-09 16:26:23 +00:00
|
|
|
void MainWindow::on_actionPreviousDC_triggered()
|
|
|
|
{
|
2013-05-10 17:45:13 +00:00
|
|
|
dc_number--;
|
|
|
|
redrawProfile();
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionNextDC_triggered()
|
|
|
|
{
|
2013-05-10 17:45:13 +00:00
|
|
|
dc_number++;
|
|
|
|
redrawProfile();
|
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()
|
|
|
|
{
|
2013-06-24 11:36:38 +00:00
|
|
|
SubsurfaceAbout::instance()->show();
|
2013-04-09 16:26:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::on_actionUserManual_triggered()
|
|
|
|
{
|
2013-05-30 13:54:06 +00:00
|
|
|
if(!helpView){
|
2013-08-22 19:20:47 +00:00
|
|
|
helpView = new QWebView();
|
2013-05-30 13:54:06 +00:00
|
|
|
}
|
2013-05-30 21:26:08 +00:00
|
|
|
QString searchPath = getSubsurfaceDataPath("Documentation");
|
|
|
|
if (searchPath != "") {
|
|
|
|
QUrl url(searchPath.append("/user-manual.html"));
|
2013-08-22 19:20:47 +00:00
|
|
|
helpView->setUrl(url);
|
2013-05-30 21:26:08 +00:00
|
|
|
} else {
|
2013-08-22 19:20:47 +00:00
|
|
|
helpView->setHtml(tr("Cannot find the Subsurface manual"));
|
2013-05-30 21:26:08 +00:00
|
|
|
}
|
2013-05-30 13:54:06 +00:00
|
|
|
helpView->show();
|
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
|
|
|
#ifdef LIBZIP
|
|
|
|
f += "*.sde *.SDE *.dld *.DLD ";
|
|
|
|
#endif
|
|
|
|
#ifdef SQLITE3
|
|
|
|
f += "*.db";
|
|
|
|
#endif
|
|
|
|
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);;";
|
|
|
|
|
|
|
|
#ifdef LIBZIP
|
|
|
|
f += "SDE (*.sde *.SDE);;";
|
|
|
|
f += "DLD (*.dld *.DLD);;";
|
|
|
|
#endif
|
|
|
|
#ifdef SQLITE3
|
|
|
|
f += "DB (*.db)";
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MainWindow::askSaveChanges()
|
|
|
|
{
|
2013-05-19 21:46:53 +00:00
|
|
|
QString message;
|
2013-05-24 07:28:48 +00:00
|
|
|
QMessageBox response;
|
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);
|
|
|
|
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
|
|
|
#define GET_UNIT(name, field, f, t) \
|
|
|
|
v = s.value(QString(name)); \
|
2013-05-06 04:06:45 +00:00
|
|
|
if (v.isValid()) \
|
2013-06-04 12:40:09 +00:00
|
|
|
prefs.units.field = (v.toInt() == (t)) ? (t) : (f); \
|
|
|
|
else \
|
|
|
|
prefs.units.field = default_prefs.units.field
|
2013-05-06 04:06:45 +00:00
|
|
|
|
2013-06-04 12:40:09 +00:00
|
|
|
#define GET_BOOL(name, field) \
|
|
|
|
v = s.value(QString(name)); \
|
|
|
|
if (v.isValid()) \
|
|
|
|
prefs.field = v.toInt() ? TRUE : FALSE; \
|
2013-05-06 04:06:45 +00:00
|
|
|
else \
|
2013-06-04 12:40:09 +00:00
|
|
|
prefs.field = default_prefs.field
|
2013-05-06 04:06:45 +00:00
|
|
|
|
2013-06-04 12:40:09 +00:00
|
|
|
#define GET_DOUBLE(name, field) \
|
|
|
|
v = s.value(QString(name)); \
|
|
|
|
if (v.isValid()) \
|
|
|
|
prefs.field = v.toDouble(); \
|
|
|
|
else \
|
|
|
|
prefs.field = default_prefs.field
|
|
|
|
|
|
|
|
#define GET_INT(name, field) \
|
|
|
|
v = s.value(QString(name)); \
|
|
|
|
if (v.isValid()) \
|
|
|
|
prefs.field = v.toInt(); \
|
|
|
|
else \
|
|
|
|
prefs.field = default_prefs.field
|
|
|
|
|
|
|
|
|
|
|
|
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-04-27 09:09:57 +00:00
|
|
|
resize(sz);
|
2013-10-04 18:07:36 +00:00
|
|
|
|
2013-11-12 20:25:49 +00:00
|
|
|
state = (CurrentState) settings.value("lastState", 0).toInt();
|
2013-11-07 16:37:27 +00:00
|
|
|
switch(state){
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::readSettings()
|
|
|
|
{
|
|
|
|
QVariant v;
|
|
|
|
QSettings s;
|
|
|
|
|
|
|
|
s.beginGroup("Units");
|
|
|
|
if (s.value("unit_system").toString() == "metric") {
|
2013-06-03 12:08:49 +00:00
|
|
|
prefs.unit_system = METRIC;
|
2013-06-02 10:52:18 +00:00
|
|
|
prefs.units = SI_units;
|
2013-06-04 12:40:09 +00:00
|
|
|
} else if (s.value("unit_system").toString() == "imperial") {
|
2013-06-03 12:08:49 +00:00
|
|
|
prefs.unit_system = IMPERIAL;
|
2013-06-02 10:52:18 +00:00
|
|
|
prefs.units = IMPERIAL_units;
|
|
|
|
} else {
|
2013-06-03 12:08:49 +00:00
|
|
|
prefs.unit_system = PERSONALIZE;
|
2013-06-04 12:40:09 +00:00
|
|
|
GET_UNIT("length", length, units::FEET, units::METERS);
|
|
|
|
GET_UNIT("pressure", pressure, units::PSI, units::BAR);
|
|
|
|
GET_UNIT("volume", volume, units::CUFT, units::LITER);
|
|
|
|
GET_UNIT("temperature", temperature, units::FAHRENHEIT, units::CELSIUS);
|
|
|
|
GET_UNIT("weight", weight, units::LBS, units::KG);
|
2013-06-02 10:52:18 +00:00
|
|
|
}
|
2013-10-04 05:57:48 +00:00
|
|
|
GET_UNIT("vertical_speed_time", vertical_speed_time, units::MINUTES, units::SECONDS);
|
2013-06-04 12:40:09 +00:00
|
|
|
s.endGroup();
|
|
|
|
s.beginGroup("TecDetails");
|
|
|
|
GET_BOOL("po2graph", pp_graphs.po2);
|
|
|
|
GET_BOOL("pn2graph", pp_graphs.pn2);
|
|
|
|
GET_BOOL("phegraph", pp_graphs.phe);
|
|
|
|
GET_DOUBLE("po2threshold", pp_graphs.po2_threshold);
|
|
|
|
GET_DOUBLE("pn2threshold", pp_graphs.pn2_threshold);
|
|
|
|
GET_DOUBLE("phethreshold", pp_graphs.phe_threshold);
|
|
|
|
GET_BOOL("mod", mod);
|
|
|
|
GET_DOUBLE("modppO2", mod_ppO2);
|
|
|
|
GET_BOOL("ead", ead);
|
|
|
|
GET_BOOL("redceiling", profile_red_ceiling);
|
|
|
|
GET_BOOL("dcceiling", profile_dc_ceiling);
|
|
|
|
GET_BOOL("calcceiling", profile_calc_ceiling);
|
|
|
|
GET_BOOL("calcceiling3m", calc_ceiling_3m_incr);
|
2013-11-12 22:09:57 +00:00
|
|
|
GET_BOOL("calcndltts", calc_ndl_tts);
|
2013-06-04 12:40:09 +00:00
|
|
|
GET_BOOL("calcalltissues", calc_all_tissues);
|
|
|
|
GET_INT("gflow", gflow);
|
|
|
|
GET_INT("gfhigh", gfhigh);
|
2013-05-06 04:06:45 +00:00
|
|
|
set_gf(prefs.gflow, prefs.gfhigh);
|
2013-10-14 21:48:44 +00:00
|
|
|
GET_BOOL("show_sac", show_sac);
|
2013-06-04 12:40:09 +00:00
|
|
|
s.endGroup();
|
2013-05-06 04:06:45 +00:00
|
|
|
|
2013-06-04 12:40:09 +00:00
|
|
|
s.beginGroup("Display");
|
|
|
|
v = s.value(QString("divelist_font"));
|
2013-05-06 04:06:45 +00:00
|
|
|
if (v.isValid())
|
2013-06-04 12:40:09 +00:00
|
|
|
prefs.divelist_font = strdup(v.toString().toUtf8().data());
|
2013-04-27 09:09:57 +00:00
|
|
|
}
|
|
|
|
|
2013-05-06 04:06:45 +00:00
|
|
|
#define SAVE_VALUE(name, field) \
|
|
|
|
if (prefs.field != default_prefs.field) \
|
2013-05-28 18:21:27 +00:00
|
|
|
settings.setValue(name, prefs.field); \
|
|
|
|
else \
|
|
|
|
settings.remove(name)
|
2013-05-06 04:06:45 +00:00
|
|
|
|
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");
|
2013-11-07 16:37:27 +00:00
|
|
|
settings.setValue("lastState", (int) state);
|
2013-04-27 09:09:57 +00:00
|
|
|
settings.setValue("size",size());
|
2013-11-07 16:37:27 +00:00
|
|
|
if (state == VIEWALL){
|
|
|
|
saveSplitterSizes();
|
|
|
|
}
|
2013-04-27 09:09:57 +00:00
|
|
|
settings.endGroup();
|
2013-05-03 05:06:01 +00:00
|
|
|
|
2013-05-06 04:06:45 +00:00
|
|
|
settings.beginGroup("Units");
|
2013-05-26 18:33:45 +00:00
|
|
|
SAVE_VALUE("length", units.length);
|
|
|
|
SAVE_VALUE("pressure", units.pressure);
|
|
|
|
SAVE_VALUE("volume", units.volume);
|
|
|
|
SAVE_VALUE("temperature", units.temperature);
|
|
|
|
SAVE_VALUE("weight", units.weight);
|
2013-10-04 05:57:48 +00:00
|
|
|
SAVE_VALUE("vertical_speed_time", units.vertical_speed_time);
|
2013-05-06 04:06:45 +00:00
|
|
|
settings.endGroup();
|
|
|
|
settings.beginGroup("TecDetails");
|
|
|
|
SAVE_VALUE("po2graph", pp_graphs.po2);
|
|
|
|
SAVE_VALUE("pn2graph", pp_graphs.pn2);
|
|
|
|
SAVE_VALUE("phegraph", pp_graphs.phe);
|
|
|
|
SAVE_VALUE("po2threshold", pp_graphs.po2_threshold);
|
|
|
|
SAVE_VALUE("pn2threshold", pp_graphs.pn2_threshold);
|
|
|
|
SAVE_VALUE("phethreshold", pp_graphs.phe_threshold);
|
|
|
|
SAVE_VALUE("mod", mod);
|
|
|
|
SAVE_VALUE("modppO2", mod_ppO2);
|
|
|
|
SAVE_VALUE("ead", ead);
|
|
|
|
SAVE_VALUE("redceiling", profile_red_ceiling);
|
|
|
|
SAVE_VALUE("calcceiling", profile_calc_ceiling);
|
|
|
|
SAVE_VALUE("calcceiling3m", calc_ceiling_3m_incr);
|
2013-05-30 18:56:00 +00:00
|
|
|
SAVE_VALUE("calcalltissues", calc_all_tissues);
|
2013-05-29 06:32:31 +00:00
|
|
|
SAVE_VALUE("dcceiling", profile_dc_ceiling);
|
2013-05-06 04:06:45 +00:00
|
|
|
SAVE_VALUE("gflow", gflow);
|
|
|
|
SAVE_VALUE("gfhigh", gfhigh);
|
|
|
|
settings.endGroup();
|
2013-05-10 04:37:21 +00:00
|
|
|
settings.beginGroup("GeneralSettings");
|
|
|
|
SAVE_VALUE("default_filename", default_filename);
|
|
|
|
settings.endGroup();
|
2013-04-27 09:09:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::closeEvent(QCloseEvent *event)
|
|
|
|
{
|
2013-05-30 13:54:06 +00:00
|
|
|
if (helpView && helpView->isVisible()){
|
|
|
|
helpView->close();
|
|
|
|
helpView->deleteLater();
|
|
|
|
}
|
2013-05-30 21:26:08 +00:00
|
|
|
|
2013-04-28 03:47:47 +00:00
|
|
|
if (unsaved_changes() && (askSaveChanges() == FALSE)) {
|
2013-04-27 09:09:57 +00:00
|
|
|
event->ignore();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
event->accept();
|
|
|
|
writeSettings();
|
2013-04-28 03:47:47 +00:00
|
|
|
}
|
2013-05-19 03:09:36 +00:00
|
|
|
|
|
|
|
DiveListView* MainWindow::dive_list()
|
|
|
|
{
|
2013-10-03 18:54:25 +00:00
|
|
|
return ui.ListWidget;
|
2013-05-19 03:09:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GlobeGPS* MainWindow::globe()
|
|
|
|
{
|
2013-10-03 18:54:25 +00:00
|
|
|
return ui.globe;
|
2013-05-19 03:09:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ProfileGraphicsView* MainWindow::graphics()
|
|
|
|
{
|
2013-10-03 18:54:25 +00:00
|
|
|
return ui.ProfileWidget;
|
2013-05-19 03:09:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
MainTab* MainWindow::information()
|
|
|
|
{
|
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
|
|
|
|
|
|
|
void MainWindow::file_save_as(void)
|
|
|
|
{
|
|
|
|
QString filename;
|
|
|
|
const char *default_filename;
|
|
|
|
|
|
|
|
if (existing_filename)
|
|
|
|
default_filename = existing_filename;
|
|
|
|
else
|
|
|
|
default_filename = prefs.default_filename;
|
|
|
|
filename = QFileDialog::getSaveFileName(this, tr("Save File as"), default_filename,
|
|
|
|
tr("Subsurface XML files (*.ssrf *.xml *.XML)"));
|
|
|
|
if (!filename.isNull() && !filename.isEmpty()) {
|
|
|
|
save_dives(filename.toUtf8().data());
|
|
|
|
set_filename(filename.toUtf8().data(), TRUE);
|
2013-06-26 12:13:06 +00:00
|
|
|
setTitle(MWTF_FILENAME);
|
2013-05-19 22:25:47 +00:00
|
|
|
mark_divelist_changed(FALSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::file_save(void)
|
|
|
|
{
|
|
|
|
const char *current_default;
|
|
|
|
|
|
|
|
if (!existing_filename)
|
|
|
|
return file_save_as();
|
|
|
|
|
|
|
|
current_default = prefs.default_filename;
|
|
|
|
if (strcmp(existing_filename, current_default) == 0) {
|
|
|
|
/* 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
|
|
|
}
|
|
|
|
save_dives(existing_filename);
|
|
|
|
mark_divelist_changed(FALSE);
|
|
|
|
}
|
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:
|
|
|
|
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;
|
|
|
|
char *error = NULL;
|
|
|
|
for (int i = 0; i < fileNames.size(); ++i) {
|
|
|
|
fileNamePtr = fileNames.at(i).toLocal8Bit();
|
|
|
|
parse_file(fileNamePtr.data(), &error);
|
|
|
|
if (error != NULL) {
|
|
|
|
showError(error);
|
|
|
|
free(error);
|
|
|
|
error = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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
|
|
|
char *error = NULL;
|
|
|
|
QByteArray fileNamePtr;
|
|
|
|
|
|
|
|
for (int i = 0; i < fileNames.size(); ++i) {
|
|
|
|
fileNamePtr = fileNames.at(i).toLocal8Bit();
|
|
|
|
parse_file(fileNamePtr.data(), &error);
|
|
|
|
set_filename(fileNamePtr.data(), TRUE);
|
|
|
|
setTitle(MWTF_FILENAME);
|
|
|
|
|
|
|
|
if (error != NULL) {
|
|
|
|
showError(error);
|
|
|
|
free(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
process_dives(FALSE, FALSE);
|
|
|
|
|
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
|
|
|
|
|
|
|
void MainWindow::on_actionImportCSV_triggered()
|
|
|
|
{
|
2013-11-01 13:43:41 +00:00
|
|
|
CSVImportDialog *csvImport = new CSVImportDialog();
|
2013-10-16 19:05:19 +00:00
|
|
|
csvImport->show();
|
|
|
|
process_dives(TRUE, FALSE);
|
2013-11-01 13:43:41 +00:00
|
|
|
refreshDisplay();
|
2013-10-16 19:05:19 +00:00
|
|
|
}
|
2013-11-01 15:48:34 +00:00
|
|
|
|
|
|
|
void MainWindow::editCurrentDive()
|
|
|
|
{
|
2013-11-09 00:09:46 +00:00
|
|
|
if(DivePlannerPointsModel::instance()->currentMode() != DivePlannerPointsModel::NOTHING){
|
|
|
|
QMessageBox::warning(this, tr("Warning"), "First finish the current edition before trying to do another." );
|
|
|
|
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();
|
2013-11-07 07:52:39 +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);
|
2013-11-01 15:48:34 +00:00
|
|
|
ui.stackedWidget->setCurrentIndex(PLANNERPROFILE); // Planner.
|
|
|
|
ui.infoPane->setCurrentIndex(MAINTAB);
|
|
|
|
DivePlannerPointsModel::instance()->loadFromDive(d);
|
|
|
|
ui.InfoWidget->enableEdition(MainTab::MANUALLY_ADDED_DIVE);
|
|
|
|
}
|
2013-11-07 07:52:39 +00:00
|
|
|
else if (defaultDC == "planned dive"){
|
2013-11-05 04:54:44 +00:00
|
|
|
// this looks like something is missing here
|
2013-11-01 15:48:34 +00:00
|
|
|
}
|
|
|
|
}
|