Esempio n. 1
0
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());
        }
    }
}
Esempio n. 3
0
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);
    }
}