Akonadi

progressspinnerdelegate.cpp
1 /*
2  Copyright (C) 2010 Klarälvdalens Datakonsult AB,
3  a KDAB Group company, [email protected],
4  author Stephen Kelly <[email protected]>
5 
6  This library is free software; you can redistribute it and/or modify it
7  under the terms of the GNU Library General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or (at your
9  option) any later version.
10 
11  This library is distributed in the hope that it will be useful, but WITHOUT
12  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14  License for more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to the
18  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  02110-1301, USA.
20 */
21 
22 #include "progressspinnerdelegate_p.h"
23 
24 
25 #include "entitytreemodel.h"
26 
27 #include <KIconLoader>
28 
29 #include <QTimerEvent>
30 #include <QAbstractItemView>
31 
32 using namespace Akonadi;
33 
34 DelegateAnimator::DelegateAnimator(QAbstractItemView *view)
35  : QObject(view)
36  , m_view(view)
37  , m_timerId(-1)
38 {
39  m_pixmapSequence = KIconLoader::global()->loadPixmapSequence(QStringLiteral("process-working"), 22);
40 }
41 
42 void DelegateAnimator::push(const QModelIndex &index)
43 {
44  if (m_animations.isEmpty()) {
45  m_timerId = startTimer(200);
46  }
47  m_animations.insert(Animation(index));
48 }
49 
50 void DelegateAnimator::pop(const QModelIndex &index)
51 {
52  if (m_animations.remove(Animation(index))) {
53  if (m_animations.isEmpty() && m_timerId != -1) {
54  killTimer(m_timerId);
55  m_timerId = -1;
56  }
57  }
58 }
59 
60 void DelegateAnimator::timerEvent(QTimerEvent *event)
61 {
62  if (!(event->timerId() == m_timerId && m_view)) {
63  QObject::timerEvent(event);
64  return;
65  }
66 
67  QRegion region;
68  // Do no port this to for(:)! The pop() inside the loop invalidates (even implicit) iterators.
69  Q_FOREACH (const Animation &animation, m_animations) {
70  // Check if loading is finished (we might not be notified, if the index is scrolled out of view)
71  const QVariant fetchState = animation.index.data(Akonadi::EntityTreeModel::FetchStateRole);
72  if (fetchState.toInt() != Akonadi::EntityTreeModel::FetchingState) {
73  pop(animation.index);
74  continue;
75  }
76 
77  // This repaints the entire delegate (icon and text).
78  // TODO: See if there's a way to repaint only part of it (the icon).
79  animation.nextFrame();
80  const QRect rect = m_view->visualRect(animation.index);
81  region += rect;
82  }
83 
84  if (!region.isEmpty()) {
85  m_view->viewport()->update(region);
86  }
87 }
88 
89 QPixmap DelegateAnimator::sequenceFrame(const QModelIndex &index)
90 {
91  for (const Animation &animation : qAsConst(m_animations)) {
92  if (animation.index == index) {
93  return m_pixmapSequence.frameAt(animation.frame);
94  }
95  }
96  return QPixmap();
97 }
98 
99 ProgressSpinnerDelegate::ProgressSpinnerDelegate(DelegateAnimator *animator, QObject *parent)
100  : QStyledItemDelegate(parent)
101  , m_animator(animator)
102 {
103 
104 }
105 
106 void ProgressSpinnerDelegate::initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const
107 {
109 
110  const QVariant fetchState = index.data(Akonadi::EntityTreeModel::FetchStateRole);
111  if (!fetchState.isValid() || fetchState.toInt() != Akonadi::EntityTreeModel::FetchingState) {
112  m_animator->pop(index);
113  return;
114  }
115 
116  m_animator->push(index);
117 
118  if (QStyleOptionViewItem *v = qstyleoption_cast<QStyleOptionViewItem *>(option)) {
119  v->icon = m_animator->sequenceFrame(index);
120  }
121 }
122 
123 uint Akonadi::qHash(const Akonadi::DelegateAnimator::Animation &anim)
124 {
125  return qHash(anim.index);
126 }
Returns the FetchState of a particular item.
virtual void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const const
virtual void timerEvent(QTimerEvent *event)
virtual bool event(QEvent *e)
int toInt(bool *ok) const const
static KIconLoader * global()
KCALENDARCORE_EXPORT uint qHash(const KCalendarCore::Period &key)
int startTimer(int interval, Qt::TimerType timerType)
QVariant data(int role) const const
Helper integration between Akonadi and Qt.
KPixmapSequence loadPixmapSequence(const QString &iconName, int size=SizeSmall) const
There is a fetch of items in this collection in progress.
int timerId() const const
bool isEmpty() const const
bool isValid() const const
QObject * parent() const const
void killTimer(int id)
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Fri Jun 5 2020 23:08:55 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.