2 Copyright 2013-2015 Mats Sjöberg
4 This file is part of the Pumpa programme.
6 Pumpa is free software: you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 Pumpa is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
16 You should have received a copy of the GNU General Public License
17 along with Pumpa. If not, see <http://www.gnu.org/licenses/>.
21 #include "activitywidget.h"
25 //------------------------------------------------------------------------------
27 ASWidget::ASWidget(QWidget
* parent
, int widgetLimit
, int purgeWait
) :
32 m_purgeWait(purgeWait
),
33 m_purgeCounter(purgeWait
),
34 m_widgetLimit(widgetLimit
)
36 m_reuseWidgets
= (m_widgetLimit
> 0);
38 m_itemLayout
= new QVBoxLayout
;
39 m_itemLayout
->setSpacing(10);
41 m_listContainer
= new QWidget
;
42 m_listContainer
->setLayout(m_itemLayout
);
43 m_listContainer
->setSizePolicy(QSizePolicy::Ignored
,
44 QSizePolicy::Ignored
);
46 setWidget(m_listContainer
);
47 setWidgetResizable(true);
50 //------------------------------------------------------------------------------
52 void ASWidget::clear() {
54 while ((item
= m_itemLayout
->takeAt(0)) != 0) {
55 if (dynamic_cast<QWidgetItem
*>(item
)) {
56 QWidget
* w
= item
->widget();
63 m_itemLayout
->addStretch();
66 //------------------------------------------------------------------------------
68 void ASWidget::setEndpoint(QString endpoint
, QObject
* parent
, int asMode
) {
70 m_list
= initList(endpoint
, parent
);
75 connect(m_list
, SIGNAL(changed()),
76 this, SLOT(update()), Qt::UniqueConnection
);
77 // connect(m_list, SIGNAL(request(QString, int)),
78 // this, SIGNAL(request(QString, int)), Qt::UniqueConnection);
81 //------------------------------------------------------------------------------
83 void ASWidget::refresh() {
85 if (c
> 200) c
= 200; // Count must be between 0 and 200
87 emit
request(QString("%1?count=%2").arg(m_list
->url()).arg(c
),
88 m_asMode
| QAS_UPDATE_ONLY
);
91 //------------------------------------------------------------------------------
93 void ASWidget::fetchNewer() {
94 emit
request(m_list
->prevLink(), m_asMode
| QAS_NEWER
);
97 //------------------------------------------------------------------------------
99 void ASWidget::fetchOlder(int count
) {
100 m_purgeCounter
= m_purgeWait
;
101 QString nextLink
= m_list
->nextLink();
102 if (!nextLink
.isEmpty()) {
104 nextLink
+= QString("&count=%1").arg(count
);
105 emit
request(nextLink
, m_asMode
| QAS_OLDER
);
109 //------------------------------------------------------------------------------
111 void ASWidget::refreshTimeLabels() {
112 for (int i
=0; i
<m_itemLayout
->count(); i
++) {
113 ObjectWidgetWithSignals
* ow
= widgetAt(i
);
115 ow
->refreshTimeLabels();
117 if (m_purgeCounter
> 0) {
120 qDebug() << "purgeCounter" << m_purgeCounter
<<
121 (m_list
? m_list
->url() : "NULL");
126 //------------------------------------------------------------------------------
128 void ASWidget::keyPressEvent(QKeyEvent
* event
) {
129 int key
= event
->key();
131 if (key
== Qt::Key_Home
|| key
== Qt::Key_End
) {
132 bool home
= key
==Qt::Key_Home
;
133 QScrollBar
* sb
= verticalScrollBar();
134 sb
->setValue(home
? sb
->minimum() : sb
->maximum());
136 QScrollArea::keyPressEvent(event
);
140 //------------------------------------------------------------------------------
142 ObjectWidgetWithSignals
* ASWidget::widgetAt(int idx
) {
143 QLayoutItem
* item
= m_itemLayout
->itemAt(idx
);
145 if (dynamic_cast<QWidgetItem
*>(item
))
146 return qobject_cast
<ObjectWidgetWithSignals
*>(item
->widget());
151 //------------------------------------------------------------------------------
153 QASAbstractObject
* ASWidget::objectAt(int idx
) {
154 ObjectWidgetWithSignals
* ows
= widgetAt(idx
);
158 ActivityWidget
* aw
= qobject_cast
<ActivityWidget
*>(ows
);
160 return aw
->activity();
162 ObjectWidget
* ow
= qobject_cast
<ObjectWidget
*>(ows
);
169 //------------------------------------------------------------------------------
171 void ASWidget::update() {
173 We assume m_list contains all objects, but new ones might have
174 been added either (or both) to the top or end. Go through from
175 top (newest) to bottom. If the object doesn't exist add it, if it
176 does increment the counter (go further down both in the
177 collection and widget list).
183 m_newObjects
.clear();
185 for (size_t i
=0; i
<m_list
->size(); i
++) {
186 QASAbstractObject
* cObj
= m_list
->at(i
);
188 if (cObj
->isDeleted())
191 #ifdef DEBUG_TIMELINE
192 qDebug() << "UPDATE: m_list" << i
<< cObj
->apiLink();
195 QASAbstractObject
* wObj
= objectAt(li
);
199 #ifdef DEBUG_TIMELINE
200 qDebug() << "UPDATE EXISTS1";
205 if (m_object_set
.contains(cObj
)) {
206 #ifdef DEBUG_TIMELINE
207 qDebug() << "UPDATE EXISTS2";
211 m_object_set
.insert(cObj
);
213 bool doCountAsNew
= false;
215 bool doReuse
= !older
&& m_reuseWidgets
&& (count() > m_widgetLimit
) &&
219 ObjectWidgetWithSignals
* ow
= NULL
;
220 int idx
= m_itemLayout
->count();
221 while (!ow
&& --idx
> 0)
225 qDebug() << "Reused widget" << idx
<< li
<< cObj
->apiLink()
229 QASAbstractObject
* obj
= ow
->asObject();
230 m_itemLayout
->removeWidget(ow
);
232 m_object_set
.remove(obj
);
233 m_list
->removeObject(obj
);
235 #ifdef DEBUG_TIMELINE
236 qDebug() << "UPDATE INSERTED AT" << li
<< "REUSE";
238 changeWidgetObject(ow
, cObj
);
239 m_itemLayout
->insertWidget(li
++, ow
);
241 doCountAsNew
= countAsNew(cObj
);
243 ObjectWidgetWithSignals
* ow
= createWidget(cObj
);
244 doCountAsNew
= countAsNew(cObj
);
245 ObjectWidgetWithSignals::connectSignals(ow
, this);
247 #ifdef DEBUG_TIMELINE
248 qDebug() << "UPDATE INSERTED AT" << li
<< "NEW";
250 m_itemLayout
->insertWidget(li
++, ow
);
253 qDebug() << "Created widget" << cObj
->apiLink() << m_list
->url();
257 if (!m_firstTime
&& doCountAsNew
&& !older
) {
259 m_newObjects
.push_back(cObj
);
263 if (newCount
&& !m_firstTime
)
264 emit
hasNewObjects();
266 if (newCount
&& !isVisible() && !m_firstTime
)
271 //------------------------------------------------------------------------------
273 void ASWidget::changeWidgetObject(ObjectWidgetWithSignals
* ow
,
274 QASAbstractObject
* obj
) {
275 ow
->changeObject(obj
);
278 //------------------------------------------------------------------------------
280 ObjectWidgetWithSignals
* ASWidget::createWidget(QASAbstractObject
*) {
284 //------------------------------------------------------------------------------
286 QASAbstractObjectList
* ASWidget::initList(QString
, QObject
*) {
290 //------------------------------------------------------------------------------
292 void ASWidget::refreshObject(QASAbstractObject
* obj
) {
296 QDateTime now
= QDateTime::currentDateTime();
297 QDateTime lr
= obj
->lastRefreshed();
299 if (lr
.isNull() || lr
.secsTo(now
) > 10) {
300 obj
->lastRefreshed(now
);
301 emit
request(obj
->apiLink(), obj
->asType());