diff options
-rw-r--r-- | desktop-widgets/diveplanner.cpp | 124 | ||||
-rw-r--r-- | desktop-widgets/diveplanner.h | 22 | ||||
-rw-r--r-- | desktop-widgets/mainwindow.cpp | 104 | ||||
-rw-r--r-- | desktop-widgets/mainwindow.h | 10 |
4 files changed, 143 insertions, 117 deletions
diff --git a/desktop-widgets/diveplanner.cpp b/desktop-widgets/diveplanner.cpp index 95375643f..e4f572498 100644 --- a/desktop-widgets/diveplanner.cpp +++ b/desktop-widgets/diveplanner.cpp @@ -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 } diff --git a/desktop-widgets/diveplanner.h b/desktop-widgets/diveplanner.h index af38f83af..32c3d1a48 100644 --- a/desktop-widgets/diveplanner.h +++ b/desktop-widgets/diveplanner.h @@ -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 diff --git a/desktop-widgets/mainwindow.cpp b/desktop-widgets/mainwindow.cpp index c4a234b72..6a9e378a3 100644 --- a/desktop-widgets/mainwindow.cpp +++ b/desktop-widgets/mainwindow.cpp @@ -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() diff --git a/desktop-widgets/mainwindow.h b/desktop-widgets/mainwindow.h index e0d53b20d..141f1d623 100644 --- a/desktop-widgets/mainwindow.h +++ b/desktop-widgets/mainwindow.h @@ -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); |