File indexing completed on 2024-04-28 04:20:56
0001 // SPDX-FileCopyrightText: 2004 - 2010 Jesper K. Pedersen <jesper.pedersen@kdab.com> 0002 // SPDX-FileCopyrightText: 2005, 2007 Dirk Mueller <mueller@kde.org> 0003 // SPDX-FileCopyrightText: 2012 Miika Turkia <miika.turkia@gmail.com> 0004 // SPDX-FileCopyrightText: 2013 Dominik Broj <broj.dominik@gmail.com> 0005 // SPDX-FileCopyrightText: 2018 - 2020 Robert Krawitz <rlk@alum.mit.edu> 0006 // SPDX-FileCopyrightText: 2019, 2022 Tobias Leupold <tl@stonemx.de> 0007 // SPDX-FileCopyrightText: 2013 - 2023 Johannes Zarl-Zierl <johannes@zarl-zierl.at> 0008 // 0009 // SPDX-License-Identifier: GPL-2.0-or-later 0010 0011 #ifndef DATEBAR_H 0012 #define DATEBAR_H 0013 #include "ViewHandler.h" 0014 0015 #include <Utilities/FastDateTime.h> 0016 #include <QExplicitlySharedDataPointer> 0017 #include <QPixmap> 0018 #include <QWidget> 0019 0020 class KActionCollection; 0021 class QMenu; 0022 class QKeyEvent; 0023 class QMouseEvent; 0024 class QFocusEvent; 0025 class QResizeEvent; 0026 class QPaintEvent; 0027 class QWheelEvent; 0028 class QContextMenuEvent; 0029 class QToolButton; 0030 class QFontMetrics; 0031 0032 namespace DB 0033 { 0034 0035 class ImageInfoList; 0036 class ImageDateCollection; 0037 class ImageDate; 0038 } 0039 0040 namespace DateBar 0041 { 0042 class MouseHandler; 0043 class FocusItemDragHandler; 0044 class BarDragHandler; 0045 class SelectionHandler; 0046 0047 /** 0048 * @brief The DateBarWidget class provides a histogram-like depiction of the image distribution over time. 0049 * If \ref includeFuzzyCounts() is \c true, 0050 * then both exact and fuzzy dates are taken into account and shown in different style (currently yellow and green). 0051 * If enough space is available, the number of images within each time period is printed inside each box. 0052 * 0053 * ## "unit" concept 0054 * A central concept in the widget design is that of a time \c unit. 0055 * Units are an integer offset into the number of available "boxes". 0056 * The number of units (or boxes) is calculated according to the available space (see \ref numberOfUnits()). 0057 * Each unit corresponds to a time period at the current resolution and offset. 0058 * 0059 * The time resulution is represented by the \c ViewHandler, and the offset is stored in \c m_currentDate. 0060 * 0061 * ## UI Description 0062 * 0063 * The area below the histogram bars can be used to select a date range using mouse click or drag. 0064 * Clicking outside the selected range clears the selection (as does pressing the "Clear date selection" button). 0065 * 0066 * Clicking within the histogram bar area changes the focus item. The focus item of the DateBar can be used by other 0067 * components (e.g. the ThumbnailViewer) to jump to an item at or close to the date unit represented by the focus item. 0068 * 0069 */ 0070 class DateBarWidget : public QWidget 0071 { 0072 Q_OBJECT 0073 0074 public: 0075 explicit DateBarWidget(QWidget *parent); 0076 enum ViewType { DecadeView, 0077 YearView, 0078 MonthView, 0079 WeekView, 0080 DayView, 0081 HourView, 0082 TenMinuteView, 0083 MinuteView }; 0084 /** 0085 * @brief includeFuzzyCounts 0086 * @return \c true if date ranges are shown, \c false otherwise. 0087 * @see setIncludeFuzzyCounts 0088 */ 0089 bool includeFuzzyCounts() const; 0090 KActionCollection *actions(); 0091 0092 bool canZoomIn() const; 0093 bool canZoomOut() const; 0094 0095 public Q_SLOTS: 0096 /** 0097 * @brief centerDateRange centers the view on the given range. 0098 * If the date range does not fit withing the current view range, 0099 * the view is instead anchored to the \c range.start() date. 0100 * @param range 0101 */ 0102 void centerDateRange(const DB::ImageDate &range); 0103 /** 0104 * @brief centerDateRange centers the view on the given range. 0105 * If the date range does not fit withing the current view range, 0106 * the view is instead anchored to the \c min date. 0107 * @param min 0108 * @param max 0109 */ 0110 void centerDateRange(const Utilities::FastDateTime &min, const Utilities::FastDateTime &max); 0111 void clearSelection(); 0112 void setViewType(ViewType tp, bool redrawNow = true); 0113 void setDate(const Utilities::FastDateTime &date); 0114 /** 0115 * @brief setImageCollection sets the list of images that are counted for the histogram graph. 0116 * @param images 0117 */ 0118 void setImageCollection(const DB::ImageInfoList &images); 0119 void scrollLeft(); 0120 void scrollRight(); 0121 void scroll(int units); 0122 void zoomIn(); 0123 void zoomOut(); 0124 void setHistogramBarSize(const QSize &size); 0125 void setIncludeFuzzyCounts(bool); 0126 /** 0127 * @brief setShowResolutionIndicator 0128 * If set to \c true, an indicator is shown to indicate the current ViewType. 0129 * The indicator indicates the size of one unit / histogram box alongside a text 0130 * indicating the respective temporal resolution (e.g. "10 minutes"). 0131 */ 0132 void setShowResolutionIndicator(bool); 0133 /** 0134 * @brief setAutomaticRangeAdjustment 0135 * If set to \c true, the ViewType and range is adjusted automatically to best 0136 * match the current set of images. 0137 */ 0138 void setAutomaticRangeAdjustment(bool); 0139 0140 Q_SIGNALS: 0141 void zoomInEnabled(bool); 0142 void zoomOutEnabled(bool); 0143 void dateSelected(const DB::ImageDate &, bool includeRanges); 0144 void toolTipInfo(const QString &); 0145 void dateRangeChange(const DB::ImageDate &); 0146 void dateRangeCleared(); 0147 void dateRangeSelected(bool); 0148 0149 public: 0150 // Overridden methods for internal purpose 0151 QSize sizeHint() const override; 0152 QSize minimumSizeHint() const override; 0153 0154 protected: 0155 bool event(QEvent *event) override; 0156 void paintEvent(QPaintEvent *event) override; 0157 void resizeEvent(QResizeEvent *event) override; 0158 void mousePressEvent(QMouseEvent *event) override; 0159 void mouseMoveEvent(QMouseEvent *event) override; 0160 void mouseReleaseEvent(QMouseEvent *event) override; 0161 void contextMenuEvent(QContextMenuEvent *) override; 0162 void keyPressEvent(QKeyEvent *event) override; 0163 void focusInEvent(QFocusEvent *) override; 0164 void focusOutEvent(QFocusEvent *) override; 0165 void wheelEvent(QWheelEvent *e) override; 0166 0167 /** 0168 * @brief redraw the widget 0169 * This method creates a QPainter and then uses the draw* methods to draw the different parts of the widget. 0170 * \see drawTickMarks 0171 * \see drawHistograms 0172 * \see drawFocusRectangle 0173 * \see drawResolutionIndicator 0174 */ 0175 void redraw(); 0176 void drawTickMarks(QPainter &p, const QRect &textRect); 0177 void drawHistograms(QPainter &p); 0178 void drawFocusRectangle(QPainter &p); 0179 void drawResolutionIndicator(QPainter &p, int *leftEdge); 0180 /** 0181 * @brief zoom in or out by a number of steps. 0182 * One steps corresponds to one step in the ViewType. 0183 * @param steps positive steps to increase temporal resolution, negative to decrease. 0184 */ 0185 void zoom(int steps); 0186 QRect barAreaGeometry() const; 0187 QRect tickMarkGeometry() const; 0188 QRect dateAreaGeometry() const; 0189 int numberOfUnits() const; 0190 void drawArrow(QPainter &, const QPoint &start, const QPoint &end); 0191 void updateArrowState(); 0192 DB::ImageDate currentDateRange() const; 0193 void showStatusBarTip(const QPoint &pos); 0194 DB::ImageDate rangeAt(const QPoint &); 0195 DB::ImageDate rangeForUnit(int unit); 0196 void placeAndSizeButtons(); 0197 /** 0198 * @brief unitAtPos maps horizontal screen coordinates to units. 0199 * @param x a valid pixel offset in the histogram area 0200 * @return a unit index between 0 and numberOfUnits, or -1 if the pixel offset is not valid 0201 */ 0202 int unitAtPos(int x) const; 0203 Utilities::FastDateTime dateForUnit(int unit, const Utilities::FastDateTime &offset = Utilities::FastDateTime()) const; 0204 /** 0205 * @brief unitForDate return the unit index corresponding to the date/time. 0206 * @param date a valid Utilities::FastDateTime. 0207 * @return An integer greater or equal to 0 if \p date is in view, -1 otherwise. 0208 */ 0209 int unitForDate(const Utilities::FastDateTime &date) const; 0210 bool isUnitSelected(int unit) const; 0211 bool hasSelection() const; 0212 DB::ImageDate currentSelection() const; 0213 void emitDateSelected(); 0214 void emitRangeSelection(const DB::ImageDate &); 0215 void setImageDateCollection(const QExplicitlySharedDataPointer<DB::ImageDateCollection> &); 0216 0217 private: 0218 void setViewHandlerForType(ViewType tp); 0219 int stringWidth(const QFontMetrics &fontMetrics, const QString &text) const; 0220 QPixmap m_buffer; 0221 friend class DateBarTip; 0222 0223 QExplicitlySharedDataPointer<DB::ImageDateCollection> m_dates; 0224 DecadeViewHandler m_decadeViewHandler; 0225 YearViewHandler m_yearViewHandler; 0226 MonthViewHandler m_monthViewHandler; 0227 WeekViewHandler m_weekViewHandler; 0228 DayViewHandler m_dayViewHandler; 0229 HourViewHandler m_hourViewHandler; 0230 TenMinuteViewHandler m_tenMinuteViewHandler; 0231 MinuteViewHandler m_minuteViewHandler; 0232 ViewHandler *m_currentHandler; 0233 ViewType m_tp; 0234 0235 MouseHandler *m_currentMouseHandler; 0236 FocusItemDragHandler *m_focusItemDragHandler; 0237 BarDragHandler *m_barDragHandler; 0238 SelectionHandler *m_selectionHandler; 0239 friend class Handler; 0240 friend class FocusItemDragHandler; 0241 friend class BarDragHandler; 0242 friend class SelectionHandler; 0243 0244 QToolButton *m_rightArrow; 0245 QToolButton *m_leftArrow; 0246 QToolButton *m_zoomIn; 0247 QToolButton *m_zoomOut; 0248 QToolButton *m_cancelSelection; 0249 0250 int m_currentUnit; ///< focus unit; also offset for drawing. 0251 Utilities::FastDateTime m_currentDate; ///< reference frame for date bar. Equals unit 0. 0252 int m_barWidth; ///< width of a single unit in pixel 0253 int m_barHeight; 0254 bool m_includeFuzzyCounts; 0255 QMenu *m_contextMenu; 0256 bool m_showResolutionIndicator; 0257 bool m_doAutomaticRangeAdjustment; 0258 KActionCollection *m_actionCollection; 0259 }; 0260 } 0261 0262 #endif /* DATEBAR_H */ 0263 0264 // vi:expandtab:tabstop=4 shiftwidth=4: