mirror of
https://github.com/subsurface/subsurface.git
synced 2025-01-19 06:15:26 +00:00
desktop: move planner-code to diveplanner.cpp
Around 2015 there was a push to move planner UI code from mainwindow.cpp to diveplanner.cpp. That never was completed, presumably because the planner is actually three widgets. Collect these widgets in one PlannerWidgets class and move the code there. This is not a full dis-entanglement, as the plannerwidgets have to access the profile via the mainwindow. But at least it collects the planner UI code at a single place. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
16f86f2f65
commit
bb76cb56d4
4 changed files with 143 additions and 117 deletions
|
@ -19,6 +19,11 @@
|
|||
#include <QMessageBox>
|
||||
#include <QSettings>
|
||||
#include <QShortcut>
|
||||
#ifndef NO_PRINTING
|
||||
#include <QPrintDialog>
|
||||
#include <QPrinter>
|
||||
#include <QBuffer>
|
||||
#endif
|
||||
|
||||
#define TIME_INITIAL_MAX 30
|
||||
|
||||
|
@ -149,7 +154,6 @@ DivePlannerWidget::DivePlannerWidget(QWidget *parent) : QWidget(parent, QFlag(0)
|
|||
connect(cylinders, &CylindersModel::dataChanged, plannerModel, &DivePlannerPointsModel::cylinderModelEdited);
|
||||
connect(cylinders, &CylindersModel::rowsInserted, plannerModel, &DivePlannerPointsModel::cylinderModelEdited);
|
||||
connect(cylinders, &CylindersModel::rowsRemoved, plannerModel, &DivePlannerPointsModel::cylinderModelEdited);
|
||||
connect(plannerModel, &DivePlannerPointsModel::calculatedPlanNotes, MainWindow::instance(), &MainWindow::setPlanNotes);
|
||||
|
||||
|
||||
ui.tableWidget->setBtnToolTip(tr("Add dive data point"));
|
||||
|
@ -182,6 +186,8 @@ DivePlannerWidget::DivePlannerWidget(QWidget *parent) : QWidget(parent, QFlag(0)
|
|||
ui.ATMPressure->setValue(1013);
|
||||
ui.atmHeight->setValue(0);
|
||||
|
||||
settingsChanged();
|
||||
|
||||
setMinimumWidth(0);
|
||||
setMinimumHeight(0);
|
||||
}
|
||||
|
@ -423,11 +429,6 @@ void PlannerSettingsWidget::disableBackgasBreaks(bool enabled)
|
|||
}
|
||||
}
|
||||
|
||||
void DivePlannerWidget::printDecoPlan()
|
||||
{
|
||||
MainWindow::instance()->printPlan();
|
||||
}
|
||||
|
||||
PlannerSettingsWidget::PlannerSettingsWidget(QWidget *parent) : QWidget(parent, QFlag(0))
|
||||
{
|
||||
ui.setupUi(this);
|
||||
|
@ -603,10 +604,6 @@ void PlannerSettingsWidget::settingsChanged()
|
|||
ui.descRate->setSuffix(vs);
|
||||
}
|
||||
|
||||
void PlannerSettingsWidget::printDecoPlan()
|
||||
{
|
||||
}
|
||||
|
||||
void PlannerSettingsWidget::setBackgasBreaks(bool dobreaks)
|
||||
{
|
||||
PlannerShared::set_doo2breaks(dobreaks);
|
||||
|
@ -621,4 +618,111 @@ void PlannerSettingsWidget::setBailoutVisibility(int mode)
|
|||
PlannerDetails::PlannerDetails(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
ui.setupUi(this);
|
||||
#ifdef NO_PRINTING
|
||||
ui.printPlan->hide();
|
||||
#endif
|
||||
}
|
||||
|
||||
void PlannerDetails::setPlanNotes(QString plan)
|
||||
{
|
||||
ui.divePlanOutput->setHtml(plan);
|
||||
}
|
||||
|
||||
PlannerWidgets::PlannerWidgets()
|
||||
{
|
||||
connect(plannerDetails.printPlan(), &QPushButton::pressed, this, &PlannerWidgets::printDecoPlan);
|
||||
connect(DivePlannerPointsModel::instance(), &DivePlannerPointsModel::calculatedPlanNotes,
|
||||
&plannerDetails, &PlannerDetails::setPlanNotes);
|
||||
}
|
||||
|
||||
void PlannerWidgets::planDive()
|
||||
{
|
||||
DivePlannerPointsModel::instance()->setPlanMode(DivePlannerPointsModel::PLAN);
|
||||
|
||||
MainWindow::instance()->graphics->setPlanState();
|
||||
dc_number = 0;
|
||||
|
||||
// create a simple starting dive, using the first gas from the just copied cylinders
|
||||
DivePlannerPointsModel::instance()->createSimpleDive();
|
||||
|
||||
// plan the dive in the same mode as the currently selected one
|
||||
if (current_dive) {
|
||||
plannerSettingsWidget.setDiveMode(current_dive->dc.divemode);
|
||||
plannerSettingsWidget.setBailoutVisibility(current_dive->dc.divemode);
|
||||
if (current_dive->salinity)
|
||||
plannerWidget.setSalinity(current_dive->salinity);
|
||||
else // No salinity means salt water
|
||||
plannerWidget.setSalinity(SEAWATER_SALINITY);
|
||||
}
|
||||
plannerWidget.setReplanButton(false);
|
||||
}
|
||||
|
||||
void PlannerWidgets::replanDive()
|
||||
{
|
||||
DivePlannerPointsModel::instance()->clear();
|
||||
DivePlannerPointsModel::instance()->setPlanMode(DivePlannerPointsModel::PLAN);
|
||||
|
||||
MainWindow::instance()->graphics->setPlanState();
|
||||
MainWindow::instance()->graphics->clearHandlers();
|
||||
|
||||
plannerWidget.setReplanButton(true);
|
||||
plannerWidget.setupStartTime(timestampToDateTime(current_dive->when));
|
||||
if (current_dive->surface_pressure.mbar)
|
||||
plannerWidget.setSurfacePressure(current_dive->surface_pressure.mbar);
|
||||
if (current_dive->salinity)
|
||||
plannerWidget.setSalinity(current_dive->salinity);
|
||||
DivePlannerPointsModel::instance()->loadFromDive(current_dive);
|
||||
reset_cylinders(&displayed_dive, true);
|
||||
DivePlannerPointsModel::instance()->cylindersModel()->updateDive(&displayed_dive);
|
||||
}
|
||||
|
||||
void PlannerWidgets::printDecoPlan()
|
||||
{
|
||||
#ifndef NO_PRINTING
|
||||
char *disclaimer = get_planner_disclaimer_formatted();
|
||||
// Prepend a logo and a disclaimer to the plan.
|
||||
// Save the old plan so that it can be restored at the end of the function.
|
||||
QString origPlan = plannerDetails.divePlanOutput()->toHtml();
|
||||
QString diveplan = QStringLiteral("<img height=50 src=\":subsurface-icon\"> ") +
|
||||
QString(disclaimer) + origPlan;
|
||||
free(disclaimer);
|
||||
|
||||
QPrinter printer;
|
||||
QPrintDialog *dialog = new QPrintDialog(&printer, MainWindow::instance());
|
||||
dialog->setWindowTitle(tr("Print runtime table"));
|
||||
if (dialog->exec() != QDialog::Accepted)
|
||||
return;
|
||||
|
||||
/* render the profile as a pixmap that is inserted as base64 data into a HTML <img> tag
|
||||
* make it fit a page width defined by 2 cm margins via QTextDocument->print() (cannot be changed?)
|
||||
* the height of the profile is 40% of the page height.
|
||||
*/
|
||||
QSizeF renderSize = printer.pageRect(QPrinter::Inch).size();
|
||||
const qreal marginsInch = 1.57480315; // = (2 x 2cm) / 2.45cm/inch
|
||||
renderSize.setWidth((renderSize.width() - marginsInch) * printer.resolution());
|
||||
renderSize.setHeight(((renderSize.height() - marginsInch) * printer.resolution()) / 2.5);
|
||||
|
||||
QPixmap pixmap(renderSize.toSize());
|
||||
QPainter painter(&pixmap);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
|
||||
ProfileWidget2 *profile = MainWindow::instance()->graphics;
|
||||
QSize origSize = profile->size();
|
||||
profile->resize(renderSize.toSize());
|
||||
profile->setPrintMode(true);
|
||||
profile->render(&painter);
|
||||
profile->resize(origSize);
|
||||
profile->setPrintMode(false);
|
||||
|
||||
QByteArray byteArray;
|
||||
QBuffer buffer(&byteArray);
|
||||
pixmap.save(&buffer, "PNG");
|
||||
QString profileImage = QString("<img src=\"data:image/png;base64,") + byteArray.toBase64() + "\"/><br><br>";
|
||||
diveplan = profileImage + diveplan;
|
||||
|
||||
plannerDetails.divePlanOutput()->setHtml(diveplan);
|
||||
plannerDetails.divePlanOutput()->print(&printer);
|
||||
plannerDetails.divePlanOutput()->setHtml(origPlan); // restore original plan
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -53,7 +53,6 @@ slots:
|
|||
void heightChanged(const int height);
|
||||
void waterTypeChanged(const int index);
|
||||
void customSalinityChanged(double density);
|
||||
void printDecoPlan();
|
||||
void setSurfacePressure(int surface_pressure);
|
||||
void setSalinity(int salinity);
|
||||
private:
|
||||
|
@ -72,7 +71,6 @@ public:
|
|||
public
|
||||
slots:
|
||||
void settingsChanged();
|
||||
void printDecoPlan();
|
||||
void setBackgasBreaks(bool dobreaks);
|
||||
void disableDecoElements(int mode);
|
||||
void disableBackgasBreaks(bool enabled);
|
||||
|
@ -92,10 +90,28 @@ public:
|
|||
explicit PlannerDetails(QWidget *parent = 0);
|
||||
QPushButton *printPlan() const { return ui.printPlan; }
|
||||
QTextEdit *divePlanOutput() const { return ui.divePlanOutput; }
|
||||
QLabel *divePlannerOutputLabel() const { return ui.divePlanOutputLabel; }
|
||||
public
|
||||
slots:
|
||||
void setPlanNotes(QString plan);
|
||||
|
||||
private:
|
||||
Ui::plannerDetails ui;
|
||||
};
|
||||
|
||||
// The planner widgets make up three quadrants
|
||||
class PlannerWidgets : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
PlannerWidgets();
|
||||
void planDive();
|
||||
void replanDive();
|
||||
public
|
||||
slots:
|
||||
void printDecoPlan();
|
||||
public:
|
||||
DivePlannerWidget plannerWidget;
|
||||
PlannerSettingsWidget plannerSettingsWidget;
|
||||
PlannerDetails plannerDetails;
|
||||
};
|
||||
|
||||
#endif // DIVEPLANNER_H
|
||||
|
|
|
@ -137,9 +137,7 @@ MainWindow::MainWindow() : QMainWindow(),
|
|||
diveList = new DiveListView(this);
|
||||
graphics = new ProfileWidget2(this);
|
||||
MapWidget *mapWidget = MapWidget::instance();
|
||||
divePlannerSettingsWidget = new PlannerSettingsWidget(this);
|
||||
divePlannerWidget = new DivePlannerWidget(this);
|
||||
plannerDetails = new PlannerDetails(this);
|
||||
plannerWidgets.reset(new PlannerWidgets);
|
||||
|
||||
// what is a sane order for those icons? we should have the ones the user is
|
||||
// most likely to want towards the top so they are always visible
|
||||
|
@ -174,9 +172,9 @@ MainWindow::MainWindow() : QMainWindow(),
|
|||
{ diveList, FLAG_NONE }, { mapWidget, FLAG_NONE } });
|
||||
registerApplicationState(ApplicationState::EditDive, { { mainTab.get(), FLAG_NONE }, { profileContainer, FLAG_NONE },
|
||||
{ diveList, FLAG_NONE }, { mapWidget, FLAG_NONE } });
|
||||
registerApplicationState(ApplicationState::PlanDive, { { divePlannerWidget, FLAG_NONE }, { profileContainer, FLAG_NONE },
|
||||
{ divePlannerSettingsWidget, FLAG_NONE }, { plannerDetails, FLAG_NONE } });
|
||||
registerApplicationState(ApplicationState::EditPlannedDive, { { divePlannerWidget, FLAG_NONE }, { profileContainer, FLAG_NONE },
|
||||
registerApplicationState(ApplicationState::PlanDive, { { &plannerWidgets->plannerWidget, FLAG_NONE }, { profileContainer, FLAG_NONE },
|
||||
{ &plannerWidgets->plannerSettingsWidget, FLAG_NONE }, { &plannerWidgets->plannerDetails, FLAG_NONE } });
|
||||
registerApplicationState(ApplicationState::EditPlannedDive, { { &plannerWidgets->plannerWidget, FLAG_NONE }, { profileContainer, FLAG_NONE },
|
||||
{ diveList, FLAG_NONE }, { mapWidget, FLAG_NONE } });
|
||||
registerApplicationState(ApplicationState::EditDiveSite, { { diveSiteEdit, FLAG_NONE }, { profileContainer, FLAG_DISABLED },
|
||||
{ diveList, FLAG_DISABLED }, { mapWidget, FLAG_NONE } });
|
||||
|
@ -199,7 +197,6 @@ MainWindow::MainWindow() : QMainWindow(),
|
|||
ui.menuFile->insertSeparator(ui.actionQuit);
|
||||
connect(DivePlannerPointsModel::instance(), SIGNAL(planCreated()), this, SLOT(planCreated()));
|
||||
connect(DivePlannerPointsModel::instance(), SIGNAL(planCanceled()), this, SLOT(planCanceled()));
|
||||
connect(plannerDetails->printPlan(), SIGNAL(pressed()), divePlannerWidget, SLOT(printDecoPlan()));
|
||||
connect(this, &MainWindow::showError, ui.mainErrorMessage, &NotificationWidget::showError, Qt::AutoConnection);
|
||||
|
||||
connect(&windowTitleUpdate, &WindowTitleUpdate::updateTitle, this, &MainWindow::setAutomaticTitle);
|
||||
|
@ -210,7 +207,6 @@ MainWindow::MainWindow() : QMainWindow(),
|
|||
connect(&diveListNotifier, &DiveListNotifier::divesChanged, this, &MainWindow::divesChanged);
|
||||
|
||||
#ifdef NO_PRINTING
|
||||
plannerDetails->printPlan()->hide();
|
||||
ui.menuFile->removeAction(ui.actionPrint);
|
||||
#endif
|
||||
enableDisableCloudActions();
|
||||
|
@ -223,8 +219,6 @@ MainWindow::MainWindow() : QMainWindow(),
|
|||
MapWidget::instance()->reload();
|
||||
diveList->expand(diveList->model()->index(0, 0));
|
||||
diveList->scrollTo(diveList->model()->index(0, 0), QAbstractItemView::PositionAtCenter);
|
||||
divePlannerWidget->settingsChanged();
|
||||
divePlannerSettingsWidget->settingsChanged();
|
||||
#ifdef NO_USERMANUAL
|
||||
ui.menuHelp->removeAction(ui.actionUserManual);
|
||||
#endif
|
||||
|
@ -761,62 +755,6 @@ void MainWindow::planCreated()
|
|||
diveList->setFocus();
|
||||
}
|
||||
|
||||
void MainWindow::setPlanNotes(QString plan)
|
||||
{
|
||||
plannerDetails->divePlanOutput()->setHtml(plan);
|
||||
}
|
||||
|
||||
void MainWindow::printPlan()
|
||||
{
|
||||
#ifndef NO_PRINTING
|
||||
char *disclaimer = get_planner_disclaimer_formatted();
|
||||
// Prepend a logo and a disclaimer to the plan.
|
||||
// Save the old plan so that it can be restored at the end of the function.
|
||||
QString origPlan = plannerDetails->divePlanOutput()->toHtml();
|
||||
QString diveplan = QStringLiteral("<img height=50 src=\":subsurface-icon\"> ") +
|
||||
QString(disclaimer) + origPlan;
|
||||
free(disclaimer);
|
||||
|
||||
QPrinter printer;
|
||||
QPrintDialog *dialog = new QPrintDialog(&printer, this);
|
||||
dialog->setWindowTitle(tr("Print runtime table"));
|
||||
if (dialog->exec() != QDialog::Accepted)
|
||||
return;
|
||||
|
||||
/* render the profile as a pixmap that is inserted as base64 data into a HTML <img> tag
|
||||
* make it fit a page width defined by 2 cm margins via QTextDocument->print() (cannot be changed?)
|
||||
* the height of the profile is 40% of the page height.
|
||||
*/
|
||||
QSizeF renderSize = printer.pageRect(QPrinter::Inch).size();
|
||||
const qreal marginsInch = 1.57480315; // = (2 x 2cm) / 2.45cm/inch
|
||||
renderSize.setWidth((renderSize.width() - marginsInch) * printer.resolution());
|
||||
renderSize.setHeight(((renderSize.height() - marginsInch) * printer.resolution()) / 2.5);
|
||||
|
||||
QPixmap pixmap(renderSize.toSize());
|
||||
QPainter painter(&pixmap);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
|
||||
ProfileWidget2 *profile = graphics;
|
||||
QSize origSize = profile->size();
|
||||
profile->resize(renderSize.toSize());
|
||||
profile->setPrintMode(true);
|
||||
profile->render(&painter);
|
||||
profile->resize(origSize);
|
||||
profile->setPrintMode(false);
|
||||
|
||||
QByteArray byteArray;
|
||||
QBuffer buffer(&byteArray);
|
||||
pixmap.save(&buffer, "PNG");
|
||||
QString profileImage = QString("<img src=\"data:image/png;base64,") + byteArray.toBase64() + "\"/><br><br>";
|
||||
diveplan = profileImage + diveplan;
|
||||
|
||||
plannerDetails->divePlanOutput()->setHtml(diveplan);
|
||||
plannerDetails->divePlanOutput()->print(&printer);
|
||||
plannerDetails->divePlanOutput()->setHtml(origPlan); // restore original plan
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainWindow::on_actionReplanDive_triggered()
|
||||
{
|
||||
if (!plannerStateClean() || !current_dive)
|
||||
|
@ -826,22 +764,11 @@ void MainWindow::on_actionReplanDive_triggered()
|
|||
QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)
|
||||
return;
|
||||
}
|
||||
// put us in PLAN mode
|
||||
DivePlannerPointsModel::instance()->clear();
|
||||
DivePlannerPointsModel::instance()->setPlanMode(DivePlannerPointsModel::PLAN);
|
||||
|
||||
graphics->setPlanState();
|
||||
graphics->clearHandlers();
|
||||
// put us in PLAN mode
|
||||
setApplicationState(ApplicationState::PlanDive);
|
||||
divePlannerWidget->setReplanButton(true);
|
||||
divePlannerWidget->setupStartTime(timestampToDateTime(current_dive->when));
|
||||
if (current_dive->surface_pressure.mbar)
|
||||
divePlannerWidget->setSurfacePressure(current_dive->surface_pressure.mbar);
|
||||
if (current_dive->salinity)
|
||||
divePlannerWidget->setSalinity(current_dive->salinity);
|
||||
DivePlannerPointsModel::instance()->loadFromDive(current_dive);
|
||||
reset_cylinders(&displayed_dive, true);
|
||||
DivePlannerPointsModel::instance()->cylindersModel()->updateDive(&displayed_dive);
|
||||
|
||||
plannerWidgets->replanDive();
|
||||
}
|
||||
|
||||
void MainWindow::on_actionDivePlanner_triggered()
|
||||
|
@ -850,24 +777,9 @@ void MainWindow::on_actionDivePlanner_triggered()
|
|||
return;
|
||||
|
||||
// put us in PLAN mode
|
||||
DivePlannerPointsModel::instance()->setPlanMode(DivePlannerPointsModel::PLAN);
|
||||
setApplicationState(ApplicationState::PlanDive);
|
||||
|
||||
graphics->setPlanState();
|
||||
dc_number = 0;
|
||||
|
||||
// create a simple starting dive, using the first gas from the just copied cylinders
|
||||
DivePlannerPointsModel::instance()->createSimpleDive();
|
||||
// plan the dive in the same mode as the currently selected one
|
||||
if (current_dive) {
|
||||
divePlannerSettingsWidget->setDiveMode(current_dive->dc.divemode);
|
||||
divePlannerSettingsWidget->setBailoutVisibility(current_dive->dc.divemode);
|
||||
if (current_dive->salinity)
|
||||
divePlannerWidget->setSalinity(current_dive->salinity);
|
||||
else // No salinity means salt water
|
||||
divePlannerWidget->setSalinity(SEAWATER_SALINITY);
|
||||
}
|
||||
divePlannerWidget->setReplanButton(false);
|
||||
plannerWidgets->planDive();
|
||||
}
|
||||
|
||||
void MainWindow::on_actionAddDive_triggered()
|
||||
|
|
|
@ -35,10 +35,8 @@ class QWebView;
|
|||
class QSettings;
|
||||
class UpdateManager;
|
||||
class UserManual;
|
||||
class DivePlannerWidget;
|
||||
class PlannerWidgets;
|
||||
class ProfileWidget2;
|
||||
class PlannerDetails;
|
||||
class PlannerSettingsWidget;
|
||||
class LocationInformationWidget;
|
||||
|
||||
typedef std::pair<QByteArray, QVariant> WidgetProperty;
|
||||
|
@ -73,7 +71,6 @@ public:
|
|||
void loadFiles(const QStringList files);
|
||||
void importFiles(const QStringList importFiles);
|
||||
void setToolButtonsEnabled(bool enabled);
|
||||
void printPlan();
|
||||
void setApplicationState(ApplicationState state);
|
||||
bool inPlanner();
|
||||
NotificationWidget *getNotificationWidget();
|
||||
|
@ -82,10 +79,8 @@ public:
|
|||
void editDiveSite(dive_site *ds);
|
||||
|
||||
std::unique_ptr<MainTab> mainTab;
|
||||
PlannerDetails *plannerDetails;
|
||||
PlannerSettingsWidget *divePlannerSettingsWidget;
|
||||
std::unique_ptr<PlannerWidgets> plannerWidgets;
|
||||
ProfileWidget2 *graphics;
|
||||
DivePlannerWidget *divePlannerWidget;
|
||||
DiveListView *diveList;
|
||||
private
|
||||
slots:
|
||||
|
@ -164,7 +159,6 @@ slots:
|
|||
void planCanceled();
|
||||
void planCreated();
|
||||
void setEnabledToolbar(bool arg1);
|
||||
void setPlanNotes(QString plan);
|
||||
// Some shortcuts like "change DC" or "copy/paste dive components"
|
||||
// should only be enabled when the profile's visible.
|
||||
void disableShortcuts(bool disablePaste = true);
|
||||
|
|
Loading…
Add table
Reference in a new issue