File indexing completed on 2025-01-05 03:56:42

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2010-12-26
0007  * Description : images versions QTreeView
0008  *
0009  * SPDX-FileCopyrightText: 2010 by Martin Klapetek <martin dot klapetek at gmail dot com>
0010  * SPDX-FileCopyrightText: 2010 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #include "versionstreeview.h"
0017 
0018 // Qt includes
0019 
0020 #include <QPaintEvent>
0021 
0022 // Local includes
0023 
0024 #include "digikam_debug.h"
0025 #include "dimagehistory.h"
0026 #include "itemhistorygraphmodel.h"
0027 #include "versionsdelegate.h"
0028 #include "iteminfo.h"
0029 #include "iteminfolist.h"
0030 #include "itemlistmodel.h"
0031 #include "ditemdelegate.h"
0032 #include "itemviewtooltip.h"
0033 #include "tooltipfiller.h"
0034 
0035 namespace Digikam
0036 {
0037 
0038 class Q_DECL_HIDDEN VersionsTreeView::ToolTip : public ItemViewToolTip
0039 {
0040     Q_OBJECT
0041 
0042 public:
0043 
0044     enum Mode
0045     {
0046         InvalidMode,
0047         ImageMode,
0048         FilterActionMode
0049     };
0050 
0051 public:
0052 
0053     explicit ToolTip(QAbstractItemView* const view)
0054         : ItemViewToolTip(view),
0055           m_mode         (InvalidMode)
0056     {
0057     }
0058 
0059     void show(const QStyleOptionViewItem& option, const QModelIndex& index, Mode mode)
0060     {
0061         m_mode = mode;
0062         ItemViewToolTip::show(option, index);
0063         m_mode = InvalidMode;
0064     }
0065 
0066 protected:
0067 
0068     QString tipContents() override
0069     {
0070         switch (m_mode)
0071         {
0072             default:
0073             case InvalidMode:
0074             {
0075                 return QString();
0076             }
0077 
0078             case ImageMode:
0079             {
0080                 ItemInfo info = ItemModel::retrieveItemInfo(currentIndex());
0081 
0082                 return ToolTipFiller::imageInfoTipContents(info);
0083             }
0084 
0085             case FilterActionMode:
0086             {
0087                 FilterAction action = currentIndex().data(ItemHistoryGraphModel::FilterActionRole).value<FilterAction>();
0088 
0089                 return ToolTipFiller::filterActionTipContents(action);
0090             }
0091         }
0092     }
0093 
0094 protected:
0095 
0096     Mode m_mode;
0097 };
0098 
0099 // --------------------------------------------------------------------------------------------------------------------------
0100 
0101 VersionsTreeView::VersionsTreeView(QWidget* const parent)
0102     : QTreeView        (parent),
0103       m_delegate       (nullptr),
0104       m_dragDropHandler(nullptr),
0105       m_showToolTip    (false),
0106       m_toolTip        (nullptr)
0107 {
0108     m_delegate = new VersionsDelegate(this);
0109     setItemDelegate(m_delegate);
0110     m_delegate->setViewOnAllOverlays(this);
0111     setMouseTracking(true);
0112 }
0113 
0114 /// NOTE: All overlay management code in a sophisticated form can be studied in ItemCategorizedView
0115 VersionsTreeView::~VersionsTreeView()
0116 {
0117     m_delegate->removeAllOverlays();
0118 }
0119 
0120 VersionsDelegate* VersionsTreeView::delegate() const
0121 {
0122     return m_delegate;
0123 }
0124 
0125 void VersionsTreeView::addOverlay(ItemDelegateOverlay* overlay)
0126 {
0127     m_delegate->installOverlay(overlay);
0128     overlay->setView(this);
0129     overlay->setActive(true);
0130 }
0131 
0132 void VersionsTreeView::removeOverlay(ItemDelegateOverlay* overlay)
0133 {
0134     m_delegate->removeOverlay(overlay);
0135     overlay->setView(nullptr);
0136 }
0137 
0138 void VersionsTreeView::setToolTipEnabled(bool on)
0139 {
0140     if (on == m_showToolTip)
0141     {
0142         return;
0143     }
0144 
0145     m_showToolTip = on;
0146 
0147     if (m_showToolTip && !m_toolTip)
0148     {
0149         m_toolTip = new ToolTip(this);
0150     }
0151 }
0152 
0153 void VersionsTreeView::paintEvent(QPaintEvent* e)
0154 {
0155     static_cast<VersionsDelegate*>(itemDelegate())->beginPainting();
0156     QTreeView::paintEvent(e);
0157     static_cast<VersionsDelegate*>(itemDelegate())->finishPainting();
0158 }
0159 
0160 QModelIndex VersionsTreeView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers)
0161 {
0162     // TODO: Need to find a solution to skip non-vertex items in CombinedTreeMode. Not easy.
0163 
0164     return QTreeView::moveCursor(cursorAction, modifiers);
0165 }
0166 
0167 void VersionsTreeView::mouseMoveEvent(QMouseEvent* event)
0168 {
0169     QTreeView::mouseMoveEvent(event);
0170 
0171     QModelIndex index = indexAt(event->pos());
0172     QRect indexVisualRect;
0173 
0174     if (index.isValid())
0175     {
0176         indexVisualRect = visualRect(index);
0177     }
0178 
0179     m_delegate->mouseMoved(event, indexVisualRect, index);
0180 }
0181 
0182 void VersionsTreeView::setDragDropHandler(AbstractItemDragDropHandler* handler)
0183 {
0184     m_dragDropHandler = handler;
0185 }
0186 
0187 AbstractItemDragDropHandler* VersionsTreeView::dragDropHandler() const
0188 {
0189     return m_dragDropHandler;
0190 }
0191 
0192 QModelIndex VersionsTreeView::mapIndexForDragDrop(const QModelIndex& index) const
0193 {
0194     return index; // no filter model involved
0195 }
0196 
0197 QPixmap VersionsTreeView::pixmapForDrag(const QList<QModelIndex>& indexes) const
0198 {
0199     QStyleOptionViewItem option;
0200 
0201 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
0202 
0203     initViewItemOption(&option);
0204 
0205 #else
0206 
0207     option = viewOptions();
0208 
0209 #endif
0210 
0211     option.rect                 = viewport()->rect();
0212     QPixmap pix;
0213 
0214     if (indexes.count() == 1)
0215     {
0216         pix = indexes.first().data(Qt::DecorationRole).value<QPixmap>();
0217     }
0218 
0219     return DItemDelegate::makeDragPixmap(option, indexes, devicePixelRatio(), pix);
0220 }
0221 
0222 bool VersionsTreeView::viewportEvent(QEvent* event)
0223 {
0224     switch (event->type())
0225     {
0226         case QEvent::ToolTip:
0227         {
0228             if (!m_showToolTip)
0229             {
0230                 break;
0231             }
0232 
0233             QHelpEvent* he          = static_cast<QHelpEvent*>(event);
0234             const QModelIndex index = indexAt(he->pos());
0235 
0236             if (!index.isValid())
0237             {
0238                 break;
0239             }
0240 
0241             ToolTip::Mode mode;
0242 
0243             if (index.data(ItemHistoryGraphModel::IsImageItemRole).toBool())
0244             {
0245                 mode = ToolTip::ImageMode;
0246             }
0247             else if (index.data(ItemHistoryGraphModel::IsFilterActionItemRole).toBool())
0248             {
0249                 mode = ToolTip::FilterActionMode;
0250             }
0251             else
0252             {
0253                 break;
0254             }
0255 
0256             QStyleOptionViewItem option;
0257 
0258 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
0259 
0260             initViewItemOption(&option);
0261 
0262 #else
0263 
0264             option = viewOptions();
0265 
0266 #endif
0267 
0268             option.rect                 = visualRect(index);
0269             option.state               |= (index == currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
0270 
0271             m_toolTip->show(option, index, mode);
0272 
0273             return true;
0274         }
0275 
0276         default:
0277         {
0278             break;
0279         }
0280     }
0281 
0282     return QTreeView::viewportEvent(event);
0283 }
0284 
0285 } // namespace Digikam
0286 
0287 #include "versionstreeview.moc"
0288 
0289 #include "moc_versionstreeview.cpp"