Calendar::Calendar(const QString &url, const QColor &color) { QByteArray urlArray; _url = QUrl::fromEncoded(urlArray.append(url)); _name = "Untitled Calendar"; _calChecksum = 0; _color = color; _status = NotLoaded; _aptCache = new AptCache(); buildCalendarImage(); // Wire QObjects connect(&_httpDl, SIGNAL(receivedData(bool,QString*)), this, SLOT(parseNetworkResponse(bool,QString*))); connect(&_nfyTimer, SIGNAL(timeout()), this, SLOT(sendNotifications())); _nfyTimer.setInterval(30000); _nfyTimer.setSingleShot(true); }
void JsonDbSortingListModelPrivate::_q_notificationsAvailable() { Q_Q(JsonDbSortingListModel); QJsonDbWatcher *watcher = qobject_cast<QJsonDbWatcher *>(q->sender()); int partitionIndex = indexOfWatcher(watcher); if (!watcher || partitionIndex == -1) return; QList<QJsonDbNotification> list = watcher->takeNotifications(); for (int i = 0; i < list.count(); i++) { const QJsonDbNotification & notification = list[i]; QVariantMap object = notification.object().toVariantMap(); if (state == JsonDbSortingListModel::Querying) { NotifyItem pending; pending.partitionIndex = partitionIndex; pending.item = object; pending.action = notification.action(); pendingNotifications.append(pending); } else if (state == JsonDbSortingListModel::Ready) { sendNotifications(partitionIndex, object, notification.action()); } } }
void Calendar::parseNetworkResponse(bool success, QString *data) { assert(data); engageBufferLock("accessing status and timer"); StatusCode oldStatus = _status; _nfyTimer.stop(); releaseBufferLock("releasing status and timer"); if (!success) { // In the event of a download error, set the calendar to Offline. Logger::instance()->add(CLASSNAME, this, "Error fetching update"); setStatus(Offline); if (oldStatus != Offline) emit formatNotRecognized(this); } else { Logger::instance()->add(CLASSNAME, this, "Parsing ICS data..."); ICSParser parser(*data); // Check ICS validity first if (!parser.holdsValidICS()) { Logger::instance()->add(CLASSNAME, this, "Downloaded data appears to be invalid ICS"); setStatus(Offline); } else { // Only repopulate the AptCache if the calendar changed if (calChecksum() != parser.checksum()) repopulateCache(parser); if (status() == Online) { // This will re-enable the timer and, if the cache was repopulated, // trigger the first batch of notifications. sendNotifications(); } } } Logger::instance()->add(CLASSNAME, this, "Finished updating"); }
void JsonDbSortingListModelPrivate::fillData(const QVariantList &newItems, int partitionIndex) { Q_Q(JsonDbSortingListModel); QVariantList items = newItems; generateCustomData(items); RequestInfo &r = partitionObjectDetails[partitionIndex]; r.lastSize = items.size(); if (resetModel) { // for the first chunk, add all items q->beginResetModel(); objects.clear(); objectUuids.clear(); objectSortValues.clear(); for (int i = 0; i < r.lastSize; i++) { const QVariantMap &item = items.at(i).toMap(); const QString &uuid = item.value(QLatin1String("_uuid")).toString(); SortingKey key(partitionIndex, item, ascendingOrders, orderPaths); objects.insert(uuid, item); objectUuids.insertMulti(key, uuid); objectSortValues.insert(uuid, key); } if (limit > 0 && r.lastSize > limit) { // remove extra objects QMap<SortingKey, QString>::iterator start = objectUuids.begin(); for (int i = limit; i < r.lastSize; i++) { const QString &uuid = (start+i).value(); objects.remove(uuid); objectSortValues.remove(uuid); } // remove extra items from the sorted map start += limit; while (start != objectUuids.end()) { start = objectUuids.erase(start); } } q->endResetModel(); emit q->rowCountChanged(objects.count()); resetModel = false; } else { // subsequent chunks, insert items, preserving the limit. for (int i = 0; i < r.lastSize; i++) { addItem(items.at(i).toMap(), partitionIndex); } } // Check if requests from different partitions returned // all the results bool allRequestsFinished = true; for (int i = 0; i<partitionObjectDetails.count(); i++) { if (partitionObjectDetails[i].lastSize >= chunkSize || partitionObjectDetails[i].lastSize == -1) { allRequestsFinished = false; break; } } if (allRequestsFinished) { // retrieved all elements state = JsonDbSortingListModel::Ready; emit q->stateChanged(state); for (int i = 0; i<pendingNotifications.size(); i++) { const NotifyItem &pending = pendingNotifications[i]; sendNotifications(pending.partitionIndex, pending.item, pending.action); } pendingNotifications.clear(); // overflow status is used when handling notifications. if (limit > 0 && objects.count() >= limit) overflow = true; else overflow = false; } else if (r.lastSize >= chunkSize){ // more items, fetch next chunk fetchPartition(partitionIndex, false); } }