/* * Copyright 2009 Andrew Stromme * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef RTM_SESSION_P_H #define RTM_SESSION_P_H #include "session.h" #include "xmlreaders.h" #include "request.h" #include "auth.h" #include "task.h" #include #include #include #include #include #include #include #include #include #include #ifndef QTONLY #include #include #include #endif class RTM::SessionPrivate { SessionPrivate(Session *parent) : q(parent), auth(0), online(true), tasksChanged(false), listsChanged(false) { #ifndef QTONLY QObject::connect(Solid::Networking::notifier(), SIGNAL(statusChanged(Solid::Networking::Status)), q, SLOT(networkStatusChanged(Solid::Networking::Status))); if (Solid::Networking::status() == Solid::Networking::Unconnected) { online = false; qDebug() << "We are NOT Online :("; } #endif } ~SessionPrivate() { if (auth) auth->deleteLater(); } #ifndef QTONLY void networkStatusChanged(Solid::Networking::Status status) { switch (status) { case Solid::Networking::Connected: case Solid::Networking::Unknown: if (online) return; online = true; q->checkToken(); refreshSettings(); break; case Solid::Networking::Unconnected: case Solid::Networking::Disconnecting: case Solid::Networking::Connecting: if (!online) return; online = false; break; } } #endif void offlineError() { online = false; qDebug() << "retesting offline status in 60 seconds"; QTimer::singleShot(60*1000, q, SLOT(retestOfflineStatus())); } void retestOfflineStatus() { online = true; qDebug() << "retesting offline status"; q->checkToken(); } void connectOfflineSignal(RTM::Request *request) { QObject::connect(request, SIGNAL(offlineError()), q, SLOT(offlineError())); } void populateSmartList(List * list) { if (!online) return; qDebug() << "Populating Smart List: " << list->name() << " with id " << list->id(); // We do this next bit manually so it doesn't get auto-connected to taskUpdate() RTM::Request *smartListRequest = new RTM::Request("rtm.tasks.getList", q->apiKey(), q->sharedSecret()); smartListRequest->addArgument("auth_token", q->token()); smartListRequest->addArgument("list_id", QString::number(list->id())); smartListRequest->addArgument("filter", list->filter()); QObject::connect(smartListRequest, SIGNAL(replyReceived(RTM::Request*)), q, SLOT(smartListReply(RTM::Request*))); smartListRequest->sendRequest(); } void updateSmartLists() { if (!online) return; foreach (RTM::List* list, lists) { if (list->isSmart()) { populateSmartList(list); } } } void taskUpdate(RTM::Request* reply) { TasksReader reader(reply, q); reader.read(); lastRefresh = QDateTime::currentDateTime(); reply->deleteLater(); applyTaskChanges(); if (!reply->readOnly()) { updateSmartLists(); } else { completeTaskChanges(); } } void listUpdate(RTM::Request* reply) { TasksReader reader(reply, q); reader.read(); reply->deleteLater(); applyListChanges(); if (reply->readOnly()) { completeListChanges(); } } void applyTaskChanges() { foreach(RTM::Task* task, changedTasks) { tags.unite(task->tags().toSet()); emit q->taskChanged(task); } if (changedTasks.count() > 0) { tasksChanged = true; } changedTasks.clear(); qDebug() << "taskchanges complete, tags contains " << tags; } void completeTaskChanges() { if (tasksChanged) { emit q->tasksChanged(); } tasksChanged = false; } void applyListChanges() { foreach(RTM::List* list, changedLists) { emit q->listChanged(list); } if (changedLists.count() > 0) { listsChanged = true; } changedLists.clear(); } void completeListChanges() { if (listsChanged) { emit q->listsChanged(); } listsChanged = false; } void applyChanges() { applyTaskChanges(); completeTaskChanges(); applyListChanges(); completeListChanges(); } void smartListReply(RTM::Request* reply) { QStringList parts = reply->requestUrl().split("&"); RTM::ListId id = 0; foreach(const QString &part, parts) if (part.contains("list_id")) id = part.split("=").last().toLongLong(); qDebug() << id; TasksReader reader(reply, q); reader.read(); RTM::List* list = lists.value(id); if (list) { list->setTasks(changedTasks); changedLists.push_back(list); } applyChanges(); reply->deleteLater(); } void settingsReply(RTM::Request* request) { QString reply = request->data(); // Get the full data of the reply, readAll() doesn't guarentee that. // We're basically assuming no error here.... FIXME QString timezone = reply.remove(0, reply.indexOf("")+10); timezone.truncate(timezone.indexOf("")); QString dateformat = reply.remove(0, reply.indexOf(""+12)); dateformat.truncate(dateformat.indexOf("")); this->dateFormat = (dateformat.toInt() == 0 ? "dd/MM/yy" : "MM/dd/yy"); QString timeformat = reply.remove(0, reply.indexOf(""+12)); timeformat.truncate(timeformat.indexOf("")); this->timeFormat = (timeformat.toInt() == 0 ? "hh:mm ap" : "hh:mm"); QString defaultlist = reply.remove(0, reply.indexOf(""+13)); defaultlist.truncate(defaultlist.indexOf("")); #ifndef QTONLY this->timezone = KSystemTimeZones::zone(timezone); qDebug() << "Timezone Set To: " << timezone << " i.e. " << this->timezone.name(); #endif request->deleteLater(); emit q->settingsUpdated(); } void refreshSettings() { if (!online) return; RTM::Request *settingsRequest = new RTM::Request("rtm.settings.getList", q->apiKey(), q->sharedSecret()); settingsRequest->addArgument("auth_token", q->token()); QObject::connect(settingsRequest, SIGNAL(replyReceived(RTM::Request*)), q, SLOT(settingsReply(RTM::Request*))); settingsRequest->sendRequest(); } friend class TasksReader; friend class Session; Session *q; RTM::Auth *auth; QString authUrl; QString frob; QString apiKey; QString sharedSecret; QString token; QDateTime lastRefresh; bool online; RTM::Permissions permissions; #ifndef QTONLY KTimeZone timezone; #endif QString dateFormat; // user's dateformat choice: 0 - DD/MM/YY ,1 - MM/DD/YY QString timeFormat; // user's timeformat choice: 0 - hh:mm ap ,1 - hh:mm RTM::Timeline timeline; QHash tasks; QHash lists; QSet tags; QList changedTasks; QList changedLists; bool tasksChanged; bool listsChanged; }; #endif