From 86309374cb7ab5a2537cc13c05e7c19c6860d1df Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Sat, 9 Mar 2024 16:09:36 +0100 Subject: [PATCH] profile: remove profilewidget2.cpp The functionality was ported to QtQuick. Now let's make the planner work. Signed-off-by: Berthold Stoeger --- profile-widget/profilewidget2.cpp | 311 ------------------------------ profile-widget/profilewidget2.h | 142 -------------- 2 files changed, 453 deletions(-) delete mode 100644 profile-widget/profilewidget2.cpp delete mode 100644 profile-widget/profilewidget2.h diff --git a/profile-widget/profilewidget2.cpp b/profile-widget/profilewidget2.cpp deleted file mode 100644 index 4b5e60329..000000000 --- a/profile-widget/profilewidget2.cpp +++ /dev/null @@ -1,311 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "profile-widget/profilescene.h" -#include "core/device.h" -#include "core/event.h" -#include "core/eventtype.h" -#include "core/subsurface-string.h" -#include "core/qthelper.h" -#include "core/range.h" -#include "core/settings/qPrefTechnicalDetails.h" -#include "core/settings/qPrefPartialPressureGas.h" -#include "profile-widget/diveeventitem.h" -#include "profile-widget/divetextitem.h" -#include "profile-widget/divetooltipitem.h" -#include "profile-widget/divehandler.h" -#include "core/planner.h" -#include "core/pref.h" -#include "qt-models/diveplannermodel.h" -#include "qt-models/models.h" -#include "core/errorhelper.h" -#ifndef SUBSURFACE_MOBILE -#include "desktop-widgets/simplewidgets.h" -#include "commands/command.h" -#include "core/gettextfromc.h" -#include "core/imagedownloader.h" -#endif - -#include -#include -#include -#include -#include -#include -#include - -#ifndef QT_NO_DEBUG -#include -#endif - -// Constant describing at which z-level the thumbnails are located. -// We might add more constants here for easier customability. -static const double thumbnailBaseZValue = 100.0; - -static double calcZoom(int zoomLevel) -{ - // Base of exponential zoom function: one wheel-click will increase the zoom by 15%. - constexpr double zoomFactor = 1.15; - return zoomLevel == 0 ? 1.0 : pow(zoomFactor, zoomLevel); -} - -ProfileWidget2::ProfileWidget2(DivePlannerPointsModel *plannerModelIn, double dpr, QWidget *parent) : QGraphicsView(parent), - profileScene(new ProfileScene(dpr, false, false)), - currentState(INIT), - plannerModel(plannerModelIn), - zoomLevel(0), - zoomedPosition(0.0), -#ifndef SUBSURFACE_MOBILE - toolTipItem(new ToolTipItem()), -#endif - d(nullptr), - dc(0), - empty(true), - panning(false), - shouldCalculateMax(true) -{ - setupSceneAndFlags(); - setupItemOnScene(); - addItemsToScene(); - scene()->installEventFilter(this); -#ifndef SUBSURFACE_MOBILE - setAcceptDrops(true); - - connect(Thumbnailer::instance(), &Thumbnailer::thumbnailChanged, this, &ProfileWidget2::updateThumbnail, Qt::QueuedConnection); - connect(&diveListNotifier, &DiveListNotifier::cylinderEdited, this, &ProfileWidget2::profileChanged); - connect(&diveListNotifier, &DiveListNotifier::eventsChanged, this, &ProfileWidget2::profileChanged); - connect(&diveListNotifier, &DiveListNotifier::divesChanged, this, &ProfileWidget2::divesChanged); - connect(&diveListNotifier, &DiveListNotifier::deviceEdited, this, &ProfileWidget2::replot); - connect(&diveListNotifier, &DiveListNotifier::diveComputerEdited, this, &ProfileWidget2::replot); -#endif // SUBSURFACE_MOBILE - -#if !defined(QT_NO_DEBUG) && defined(SHOW_PLOT_INFO_TABLE) - QTableView *diveDepthTableView = new QTableView(); - diveDepthTableView->setModel(profileScene->dataModel); - diveDepthTableView->show(); -#endif - - setProfileState(); -} - -ProfileWidget2::~ProfileWidget2() -{ -} - -#ifndef SUBSURFACE_MOBILE -void ProfileWidget2::keyPressEvent(QKeyEvent *e) -{ - switch (e->key()) { - case Qt::Key_Delete: return keyDeleteAction(); - case Qt::Key_Up: return keyUpAction(); - case Qt::Key_Down: return keyDownAction(); - case Qt::Key_Left: return keyLeftAction(); - case Qt::Key_Right: return keyRightAction(); - } - QGraphicsView::keyPressEvent(e); -} -#endif // SUBSURFACE_MOBILE - -void ProfileWidget2::addItemsToScene() -{ -#ifndef SUBSURFACE_MOBILE - scene()->addItem(toolTipItem); - QPen pen(QColor(Qt::red).lighter()); - pen.setWidth(0); -#endif -} - -void ProfileWidget2::setupItemOnScene() -{ -#ifndef SUBSURFACE_MOBILE - toolTipItem->setZValue(9998); - toolTipItem->setTimeAxis(profileScene->timeAxis); -#endif -} - -void ProfileWidget2::replot() -{ - plotDive(d, dc); -} - -void ProfileWidget2::setupSceneAndFlags() -{ - setScene(profileScene.get()); - setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setOptimizationFlags(QGraphicsView::DontSavePainterState); - setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate); - setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform); - setMouseTracking(true); -} - -// Currently just one dive, but the plan is to enable All of the selected dives. -void ProfileWidget2::plotDive(const struct dive *dIn, int dcIn, int flags) -{ - d = dIn; - dc = dcIn; - if (!d) { - clear(); - return; - } - - // If there was no previously displayed dive, turn off animations - if (empty) - flags |= RenderFlags::Instant; - empty = false; - - QElapsedTimer measureDuration; // let's measure how long this takes us (maybe we'll turn of TTL calculation later - measureDuration.start(); - - DivePlannerPointsModel *model = currentState == EDIT || currentState == PLAN ? plannerModel : nullptr; - bool inPlanner = currentState == PLAN; - - double zoom = calcZoom(zoomLevel); - profileScene->plotDive(d, dc, model, inPlanner, flags & RenderFlags::Instant, - flags & RenderFlags::DontRecalculatePlotInfo, - shouldCalculateMax, zoom, zoomedPosition); - -#ifndef SUBSURFACE_MOBILE - toolTipItem->setVisible(prefs.infobox); - toolTipItem->setPlotInfo(profileScene->plotInfo); - - if ((currentState == EDIT || currentState == PLAN) && plannerModel) { - repositionDiveHandlers(); - plannerModel->deleteTemporaryPlan(); - } - - // On zoom / pan don't recreate the picture thumbnails, only change their position. - if (flags & RenderFlags::DontRecalculatePlotInfo) - updateThumbnails(); - else - plotPicturesInternal(d, flags & RenderFlags::Instant); - - toolTipItem->refresh(d, mapToScene(mapFromGlobal(QCursor::pos())), currentState == PLAN); -#endif - - // OK, how long did this take us? Anything above the second is way too long, - // so if we are calculation TTS / NDL then let's force that off. - qint64 elapsedTime = measureDuration.elapsed(); - if (verbose) - qDebug() << "Profile calculation for dive " << d->number << "took" << elapsedTime << "ms" << " -- calculated ceiling preference is" << prefs.calcceiling; - if (elapsedTime > 1000 && prefs.calcndltts) { - qPrefTechnicalDetails::set_calcndltts(false); - report_error("%s", qPrintable(tr("Show NDL / TTS was disabled because of excessive processing time"))); - } -} - -void ProfileWidget2::divesChanged(const QVector &dives, DiveField field) -{ - // If the mode of the currently displayed dive changed, replot - if (field.mode && - std::find(dives.begin(), dives.end(), d) != dives.end()) - replot(); -} - -void ProfileWidget2::actionRequestedReplot(bool) -{ - settingsChanged(); -} - -void ProfileWidget2::settingsChanged() -{ - replot(); -} - -void ProfileWidget2::resizeEvent(QResizeEvent *event) -{ - QGraphicsView::resizeEvent(event); - profileScene->resize(viewport()->size()); - plotDive(d, dc, RenderFlags::Instant | RenderFlags::DontRecalculatePlotInfo); // disable animation on resize events -} - -#ifndef SUBSURFACE_MOBILE -bool ProfileWidget2::eventFilter(QObject *object, QEvent *event) -{ - QGraphicsScene *s = qobject_cast(object); - if (s && event->type() == QEvent::GraphicsSceneHelp) { - event->ignore(); - return true; - } - return QGraphicsView::eventFilter(object, event); -} -#endif - -template -static void hideAll(const T &container) -{ - for (auto &item: container) - item->setVisible(false); -} - -void ProfileWidget2::setProfileState(const dive *dIn, int dcIn) -{ - d = dIn; - dc = dcIn; - - setProfileState(); -} - -void ProfileWidget2::setProfileState() -{ - if (currentState == PROFILE) - return; - - currentState = PROFILE; - setBackgroundBrush(getColor(::BACKGROUND, profileScene->isGrayscale)); - -#ifndef SUBSURFACE_MOBILE - toolTipItem->readPos(); - toolTipItem->setVisible(prefs.infobox); -#endif - - handles.clear(); - gases.clear(); -} - -#ifndef SUBSURFACE_MOBILE - -void ProfileWidget2::setEditState(const dive *d, int dc) -{ - if (currentState == EDIT) - return; - - setProfileState(d, dc); - - currentState = EDIT; - - repositionDiveHandlers(); -} - -void ProfileWidget2::setPlanState(const dive *d, int dc) -{ - if (currentState == PLAN) - return; - - setProfileState(d, dc); - - currentState = PLAN; - setBackgroundBrush(QColor("#D7E3EF")); - - repositionDiveHandlers(); -} -#endif - -bool ProfileWidget2::isPlanner() const -{ - return currentState == PLAN; -} - -#ifndef SUBSURFACE_MOBILE - -void ProfileWidget2::profileChanged(dive *dive) -{ - if (dive != d) - return; // Cylinders of a differnt dive than the shown one changed. - replot(); -} - -#endif - -struct dive *ProfileWidget2::mutable_dive() const -{ - return const_cast(d); -} diff --git a/profile-widget/profilewidget2.h b/profile-widget/profilewidget2.h deleted file mode 100644 index a49979954..000000000 --- a/profile-widget/profilewidget2.h +++ /dev/null @@ -1,142 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#ifndef PROFILEWIDGET2_H -#define PROFILEWIDGET2_H - -#include -#include -#include - -// /* The idea of this widget is to display and edit the profile. -// * It has: -// * 1 - ToolTip / Legend item, displays every information of the current mouse position on it, plus the legends of the maps. -// * 2 - ToolBox, displays the QActions that are used to do special stuff on the profile ( like activating the plugins. ) -// * 3 - Cartesian Axis for depth ( y ) -// * 4 - Cartesian Axis for Gases ( y ) -// * 5 - Cartesian Axis for Time ( x ) -// * -// * It needs to be dynamic, things should *flow* on it, not just appear / disappear. -// */ -#include "core/pictureobj.h" -#include "core/units.h" -#include "core/subsurface-qt/divelistnotifier.h" - -class ProfileScene; -class RulerItem2; -struct dive; -class ToolTipItem; -class DiveEventItem; -class DivePlannerPointsModel; -class DiveHandler; -class QGraphicsSimpleTextItem; -class QModelIndex; - -class ProfileWidget2 : public QGraphicsView { - Q_OBJECT -public: - enum State { - PROFILE, - EDIT, - PLAN, - INIT - }; - - struct RenderFlags { - static constexpr int None = 0; - static constexpr int Instant = 1 << 0; - static constexpr int DontRecalculatePlotInfo = 1 << 1; - }; - - // Pass null as plannerModel if no support for planning required - ProfileWidget2(DivePlannerPointsModel *plannerModel, double dpr, QWidget *parent = 0); - ~ProfileWidget2(); - void resetZoom(); - void plotDive(const struct dive *d, int dc, int flags = RenderFlags::None); - void setProfileState(const struct dive *d, int dc); - void setPlanState(const struct dive *d, int dc); - void setEditState(const struct dive *d, int dc); - bool isPlanner() const; - void clear(); -#ifndef SUBSURFACE_MOBILE - bool eventFilter(QObject *, QEvent *) override; -#endif - State currentState; - -signals: - void stopAdded(); // only emitted in edit mode - void stopRemoved(int count); // only emitted in edit mode - void stopMoved(int count); // only emitted in edit mode - -public -slots: // Necessary to call from QAction's signals. - void settingsChanged(); - void actionRequestedReplot(bool triggered); - void divesChanged(const QVector &dives, DiveField field); -#ifndef SUBSURFACE_MOBILE - void updateThumbnail(QString filename, QImage thumbnail, duration_t duration); - void profileChanged(dive *d); - - /* this is called for every move on the handlers. maybe we can speed up this a bit? */ - void divePlannerHandlerMoved(); - void divePlannerHandlerClicked(); - void divePlannerHandlerReleased(); -#endif - -private: - void setProfileState(); // keep currently displayed dive - void resizeEvent(QResizeEvent *event) override; -#ifndef SUBSURFACE_MOBILE - void wheelEvent(QWheelEvent *event) override; - void mouseMoveEvent(QMouseEvent *event) override; - void contextMenuEvent(QContextMenuEvent *event) override; - void mouseDoubleClickEvent(QMouseEvent *event) override; - void mousePressEvent(QMouseEvent *event) override; - void mouseReleaseEvent(QMouseEvent *event) override; - void keyPressEvent(QKeyEvent *e) override; -#endif - void replot(); - void setZoom(int level); - void changeGas(int tank, int seconds); - void setupSceneAndFlags(); - void addItemsToScene(); - void setupItemOnScene(); - struct plot_data *getEntryFromPos(QPointF pos); - void updateThumbnails(); - void addDivemodeSwitch(int seconds, int divemode); - void addBookmark(int seconds); - void splitDive(int seconds); - void addSetpointChange(int seconds); - void removeEvent(DiveEventItem *item); - void editName(DiveEventItem *item); - void makeFirstDC(); - void deleteCurrentDC(); - void splitCurrentDC(); - void renameCurrentDC(); - - DivePlannerPointsModel *plannerModel; // If null, no planning supported. - int zoomLevel; - double zoomedPosition; // Position, when zoomed: 0.0 = beginning, 1.0 = end. -#ifndef SUBSURFACE_MOBILE - ToolTipItem *toolTipItem; -#endif - const struct dive *d; - int dc; - bool empty; // No dive shown. - bool panning; // Currently panning. - double panningOriginalMousePosition; - double panningOriginalProfilePosition; - -#ifndef SUBSURFACE_MOBILE - void repositionDiveHandlers(); -#endif - friend class DiveHandler; - bool shouldCalculateMax; // Calculate maximum time and depth (default). False when dragging handles. - std::vector selectedDiveHandleIndices() const; - - // We store a const pointer to the shown dive. However, the undo commands want - // (understandably) a non-const pointer. Since the profile has a context-menu - // with actions, it needs such a non-const pointer. This function turns the - // currently shown dive into such a pointer. Ugly, yes. - struct dive *mutable_dive() const; -}; - -#endif // PROFILEWIDGET2_H