Warning, file /network/ktp-contact-list/contact-delegate-overlay.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     Qt item view for images - delegate additions
0003 
0004     Copyright (C) 2009 Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
0005     Copyright (C) 2011 Martin Klapetek <martin dot klapetek at gmail dot com>
0006 
0007     This library is free software; you can redistribute it and/or
0008     modify it under the terms of the GNU Lesser General Public
0009     License as published by the Free Software Foundation; either
0010     version 2.1 of the License, or (at your option) any later version.
0011 
0012     This library is distributed in the hope that it will be useful,
0013     but WITHOUT ANY WARRANTY; without even the implied warranty of
0014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015     Lesser General Public License for more details.
0016 
0017     You should have received a copy of the GNU Lesser General Public
0018     License along with this library; if not, write to the Free Software
0019     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
0020 */
0021 
0022 #include "contact-delegate-overlay.h"
0023 
0024 #include <QEvent>
0025 #include <QTimer>
0026 #include <QMouseEvent>
0027 
0028 #include "contact-view-hover-button.h"
0029 #include "ktp-contactlist-debug.h"
0030 
0031 ContactDelegateOverlay::ContactDelegateOverlay(QObject *parent)
0032     : QObject(parent),
0033       m_view(0),
0034       m_delegate(0),
0035       m_mouseButtonPressedOnWidget(false)
0036 {
0037 }
0038 
0039 ContactDelegateOverlay::~ContactDelegateOverlay()
0040 {
0041 }
0042 
0043 void ContactDelegateOverlay::setActive(bool active)
0044 {
0045     if (active) {
0046         if (!m_button.isNull()) {
0047             m_button.data()->deleteLater();
0048         }
0049 
0050         m_button = createButton();
0051 
0052         m_button.data()->setFocusPolicy(Qt::NoFocus);
0053         m_button.data()->hide(); // hide per default
0054         m_button.data()->initIcon();
0055 
0056         m_view->viewport()->installEventFilter(this);
0057 
0058         if (view()->model()) {
0059             connect(m_view->model(), SIGNAL(rowsRemoved(QModelIndex,int,int)),
0060                     this, SLOT(slotHideButton()));
0061 
0062             connect(m_view->model(), SIGNAL(layoutChanged()),
0063                     this, SLOT(slotHideButton()));
0064 
0065             connect(m_view->model(), SIGNAL(modelReset()),
0066                     this, SLOT(slotReset()));
0067         }
0068 
0069         connect(m_view, SIGNAL(entered(QModelIndex)),
0070                 this, SLOT(slotEntered(QModelIndex)));
0071 
0072         connect(m_view, SIGNAL(viewportEntered()),
0073                 this, SLOT(slotHideButton()));
0074     } else {
0075         m_button.data()->deleteLater();
0076 
0077         if (m_view) {
0078             m_view->viewport()->removeEventFilter(this);
0079 
0080             if (view()->model()) {
0081                 disconnect(m_view->model(), 0, this, 0);
0082             }
0083 
0084             disconnect(m_view, SIGNAL(entered(QModelIndex)),
0085                        this, SLOT(slotEntered(QModelIndex)));
0086 
0087             disconnect(m_view, SIGNAL(viewportEntered()),
0088                        this, SLOT(slotHideButton()));
0089         }
0090     }
0091 }
0092 
0093 void ContactDelegateOverlay::visualChange()
0094 {
0095     if (!m_button.isNull() && m_button.data()->isVisible()) {
0096         updateButton(button()->index());
0097     }
0098 }
0099 
0100 void ContactDelegateOverlay::setView(QAbstractItemView *view)
0101 {
0102     if (m_view) {
0103         disconnect(this, SIGNAL(update(QModelIndex)),
0104                    m_view, SLOT(update(QModelIndex)));
0105     }
0106 
0107     m_view = view;
0108 
0109     if (m_view) {
0110         connect(this, SIGNAL(update(QModelIndex)),
0111                 m_view, SLOT(update(QModelIndex)));
0112     }
0113 }
0114 
0115 QAbstractItemView* ContactDelegateOverlay::view() const
0116 {
0117     return m_view;
0118 }
0119 
0120 void ContactDelegateOverlay::setDelegate(QAbstractItemDelegate *delegate)
0121 {
0122     m_delegate = delegate;
0123 }
0124 
0125 QAbstractItemDelegate* ContactDelegateOverlay::delegate() const
0126 {
0127     return m_delegate;
0128 }
0129 
0130 void ContactDelegateOverlay::slotHideButton()
0131 {
0132     if (!m_button.isNull()) {
0133         m_button.data()->hide();
0134     }
0135 }
0136 
0137 void ContactDelegateOverlay::slotReset()
0138 {
0139     slotHideButton();
0140     button()->reset();
0141 }
0142 
0143 void ContactDelegateOverlay::slotEntered(const QModelIndex& index)
0144 {
0145     slotHideButton();
0146 
0147     if (index.isValid() && checkIndex(index)) {
0148         m_button.data()->setIndex(index);
0149         updateButton(index);
0150         QTimer::singleShot(0, m_button.data(), SLOT(show()));
0151         emit overlayActivated(index);
0152     }
0153 }
0154 
0155 bool ContactDelegateOverlay::checkIndex(const QModelIndex& index) const
0156 {
0157     Q_UNUSED(index);
0158     return true;
0159 }
0160 
0161 bool ContactDelegateOverlay::eventFilter(QObject *obj, QEvent *event)
0162 {
0163     if (!m_button.isNull() && obj == m_button.data()) {
0164         switch (event->type()) {
0165             case QEvent::MouseButtonPress:
0166                 if (static_cast<QMouseEvent*>(event)->buttons() & Qt::LeftButton) {
0167                     m_mouseButtonPressedOnWidget = true;
0168                 }
0169                 break;
0170             case QEvent::MouseButtonRelease:
0171                 m_mouseButtonPressedOnWidget = false;
0172                 break;
0173             default:
0174                 break;
0175         }
0176     } else {   // events on view's viewport
0177         switch (event->type()) {
0178             case QEvent::Leave:
0179                 slotHideButton();
0180                 emit overlayHidden();
0181                 break;
0182             case QEvent::MouseMove:
0183                 if (m_mouseButtonPressedOnWidget) {
0184                     // Don't forward mouse move events to the viewport,
0185                     // otherwise a rubberband selection will be shown when
0186                     // clicking on the selection toggle and moving the mouse
0187                     // above the viewport.
0188                     return true;
0189                 }
0190                 break;
0191             case QEvent::MouseButtonRelease:
0192                 m_mouseButtonPressedOnWidget = false;
0193                 break;
0194             default:
0195                 break;
0196         }
0197     }
0198 
0199     return false;
0200 }
0201 
0202 ContactViewHoverButton* ContactDelegateOverlay::button() const
0203 {
0204     return m_button.data();
0205 }
0206 
0207 // -----------------------------
0208 
0209 ContactDelegateOverlayContainer::~ContactDelegateOverlayContainer()
0210 {
0211 }
0212 
0213 void ContactDelegateOverlayContainer::installOverlay(ContactDelegateOverlay *overlay)
0214 {
0215     if (!overlay->acceptsDelegate(asDelegate())) {
0216         qCCritical(KTP_CONTACTLIST_MODULE) << "Cannot accept delegate" << asDelegate() << "for installing" << overlay;
0217         return;
0218     }
0219 
0220     overlay->setDelegate(asDelegate());
0221     m_overlays << overlay;
0222 }
0223 
0224 void ContactDelegateOverlayContainer::removeOverlay(ContactDelegateOverlay *overlay)
0225 {
0226     overlay->setActive(false);
0227     overlay->setDelegate(0);
0228     m_overlays.removeAll(overlay);
0229     QObject::disconnect(overlay, 0, asDelegate(), 0);
0230 }
0231 
0232 void ContactDelegateOverlayContainer::setAllOverlaysActive(bool active)
0233 {
0234     foreach (ContactDelegateOverlay *overlay, m_overlays) {
0235         overlay->setActive(active);
0236     }
0237 }
0238 
0239 void ContactDelegateOverlayContainer::setViewOnAllOverlays(QAbstractItemView *view)
0240 {
0241     foreach (ContactDelegateOverlay *overlay, m_overlays) {
0242         overlay->setView(view);
0243     }
0244 }
0245 
0246 void ContactDelegateOverlayContainer::removeAllOverlays()
0247 {
0248     foreach (ContactDelegateOverlay *overlay, m_overlays) {
0249         overlay->setActive(false);
0250         overlay->setDelegate(0);
0251         overlay->setView(0);
0252     }
0253     m_overlays.clear();
0254 }
0255 
0256 void ContactDelegateOverlayContainer::overlayDestroyed(QObject *o)
0257 {
0258     ContactDelegateOverlay *overlay = qobject_cast<ContactDelegateOverlay*>(o);
0259     if (overlay) {
0260         removeOverlay(overlay);
0261     }
0262 }