File indexing completed on 2025-01-05 03:51:11

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2009-04-30
0007  * Description : rating icon view item at mouse hover
0008  *
0009  * SPDX-FileCopyrightText: 2008      by Peter Penz <peter dot penz at gmx dot at>
0010  * SPDX-FileCopyrightText: 2009      by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
0011  * SPDX-FileCopyrightText: 2009-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0012  *
0013  * SPDX-License-Identifier: GPL-2.0-or-later
0014  *
0015  * ============================================================ */
0016 
0017 #include "itemratingoverlay.h"
0018 
0019 // Local includes
0020 
0021 #include "itemdelegate.h"
0022 #include "itemmodel.h"
0023 #include "itemcategorizedview.h"
0024 #include "ratingwidget.h"
0025 
0026 namespace Digikam
0027 {
0028 
0029 ItemRatingOverlay::ItemRatingOverlay(QObject* const parent)
0030     : AbstractWidgetDelegateOverlay(parent)
0031 {
0032 }
0033 
0034 RatingWidget* ItemRatingOverlay::ratingWidget() const
0035 {
0036     return static_cast<RatingWidget*>(m_widget);
0037 }
0038 
0039 QWidget* ItemRatingOverlay::createWidget()
0040 {
0041     RatingWidget* const w = new RatingWidget(parentWidget());
0042     w->setFading(true);
0043     w->setTracking(false);
0044 
0045     return w;
0046 }
0047 
0048 void ItemRatingOverlay::setActive(bool active)
0049 {
0050     AbstractWidgetDelegateOverlay::setActive(active);
0051 
0052     if (active)
0053     {
0054         connect(ratingWidget(), SIGNAL(signalRatingChanged(int)),
0055                 this, SLOT(slotRatingChanged(int)));
0056 
0057         if (view()->model())
0058         {
0059             connect(view()->model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
0060                     this, SLOT(slotDataChanged(QModelIndex,QModelIndex)));
0061         }
0062     }
0063     else
0064     {
0065         // widget is deleted
0066 
0067         if (view() && view()->model())
0068         {
0069             disconnect(view()->model(), nullptr, this, nullptr);
0070         }
0071     }
0072 }
0073 
0074 void ItemRatingOverlay::visualChange()
0075 {
0076     if (m_widget &&
0077         m_widget->isVisible())
0078     {
0079         updatePosition();
0080     }
0081 }
0082 
0083 void ItemRatingOverlay::widgetEnterEvent()
0084 {
0085     widgetEnterNotifyMultiple(m_index);
0086 }
0087 
0088 void ItemRatingOverlay::widgetLeaveEvent()
0089 {
0090     widgetLeaveNotifyMultiple();
0091 }
0092 
0093 void ItemRatingOverlay::hide()
0094 {
0095     delegate()->setRatingEdited(QModelIndex());
0096     AbstractWidgetDelegateOverlay::hide();
0097 }
0098 
0099 void ItemRatingOverlay::updatePosition()
0100 {
0101     if (!m_index.isValid() || !m_widget)
0102     {
0103         return;
0104     }
0105 
0106     QRect rect = delegate()->ratingRect();
0107 
0108     if (rect.width() > ratingWidget()->maximumVisibleWidth())
0109     {
0110         int offset = (rect.width() - ratingWidget()->maximumVisibleWidth()) / 2;
0111         rect.adjust(offset, 0, -offset, 0);
0112     }
0113 
0114     QRect visualRect = m_view->visualRect(m_index);
0115     rect.translate(visualRect.topLeft());
0116 
0117     m_widget->setFixedSize(rect.width() + 1, rect.height() + 1);
0118     m_widget->move(rect.topLeft());
0119 }
0120 
0121 void ItemRatingOverlay::updateRating()
0122 {
0123     if (!m_index.isValid() || !m_widget)
0124     {
0125         return;
0126     }
0127 
0128     ItemInfo info = ItemModel::retrieveItemInfo(m_index);
0129     ratingWidget()->setRating(info.rating());
0130 }
0131 
0132 void ItemRatingOverlay::slotRatingChanged(int rating)
0133 {
0134     if (m_widget              &&
0135         m_widget->isVisible() &&
0136         m_index.isValid())
0137     {
0138         Q_EMIT ratingEdited(affectedIndexes(m_index), rating);
0139     }
0140 }
0141 
0142 void ItemRatingOverlay::slotEntered(const QModelIndex& index)
0143 {
0144     AbstractWidgetDelegateOverlay::slotEntered(index);
0145 
0146     // See bug 228810, this is a small workaround
0147     if (m_widget              &&
0148         m_widget->isVisible() &&
0149         m_index.isValid()     &&
0150         index == m_index)
0151     {
0152         ratingWidget()->setVisibleImmediately();
0153     }
0154 
0155     m_index = index;
0156 
0157     updatePosition();
0158     updateRating();
0159 
0160     delegate()->setRatingEdited(m_index);
0161     view()->update(m_index);
0162 }
0163 
0164 void ItemRatingOverlay::slotDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight)
0165 {
0166     if (m_widget              &&
0167         m_widget->isVisible() &&
0168         QItemSelectionRange(topLeft, bottomRight).contains(m_index))
0169     {
0170         updateRating();
0171     }
0172 }
0173 
0174 } // namespace Digikam
0175 
0176 #include "moc_itemratingoverlay.cpp"