not quite so much needs to be delayed to the init() function
[personal-kdebase.git] / workspace / plasma / applets / kickoff / core / recentapplications.cpp
blobdb3498e84f8fbff118c91f44df4d4d193bb204b9
1 /*
2 Copyright 2007 Robert Knight <robertknight@gmail.com>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
20 // Own
21 #include "core/recentapplications.h"
23 // Qt
24 #include <QtCore/QHash>
25 #include <QtCore/QLinkedList>
27 // KDE
28 #include <KConfigGroup>
29 #include <KGlobal>
30 #include <KDebug>
32 // Local
33 #include "core/models.h"
35 using namespace Kickoff;
37 class RecentApplications::Private
39 public:
40 class ServiceInfo;
42 Private() : defaultMaxServices(DEFAULT_MAX_SERVICES) {
43 KConfigGroup recentGroup = componentData().config()->group("RecentlyUsed");
44 QList<QString> recentApplications = recentGroup.readEntry("Applications", QList<QString>());
45 defaultMaxServices = maxServices = qMax(0, recentGroup.readEntry("MaxApplications", defaultMaxServices));
47 // TESTING
48 // the actual last date/time is not currently recorded, instead we just use
49 // the current date/time and adjust it by one second after each item is added
50 // to preserve the order of the applications in the list loaded from the KConfig
51 // source
52 QDateTime dateTime = QDateTime::currentDateTime();
53 foreach(const QString& application, recentApplications) {
54 ServiceInfo info;
55 info.storageId = application;
56 info.startCount = 1;
57 info.lastStartedTime = dateTime;
58 addEntry(info.storageId, info);
59 dateTime = dateTime.addSecs(1);
62 ~Private() {
63 KConfigGroup recentGroup = componentData().config()->group("RecentlyUsed");
65 QList<ServiceInfo> services = serviceInfo.values();
66 qSort(services.begin(), services.end());
68 // TESTING
69 // only the desktop file used is currently recorded, information such
70 // as start count and date/time of last used is lost
71 QList<QString> recentApplications;
72 foreach(const ServiceInfo& info, services) {
73 recentApplications << info.storageId;
76 recentGroup.writeEntry("Applications", recentApplications);
78 void addEntry(const QString& id, ServiceInfo& info) {
79 // if this service is already in the list then remove the existing
80 // queue entry (so that there are no duplicates in the queue)
81 if (serviceInfo.contains(id)) {
82 kDebug() << "Duplicate entry added. Removing existing entry from queue.";
83 serviceQueue.erase(serviceInfo[id].queueIter);
86 serviceQueue.append(id);
87 info.queueIter = --serviceQueue.end();
88 serviceInfo.insert(id, info);
91 void removeExpiredEntries() {
92 // if more than the maximum number of services have been added
93 // remove the least recently used service
94 while (serviceQueue.count() > maxServices) {
95 QString removeId = serviceQueue.takeFirst();
96 kDebug() << "More than the maximal " << maxServices << " services added. Removing" << removeId << "from queue.";
97 serviceInfo.remove(removeId);
98 emit instance.applicationRemoved(KService::serviceByStorageId(removeId));
102 class ServiceInfo
104 public:
105 ServiceInfo() : startCount(0) {}
107 QString storageId;
108 int startCount;
109 QDateTime lastStartedTime;
110 QLinkedList<QString>::iterator queueIter;
112 bool operator<(const ServiceInfo& rhs) const {
113 return this->lastStartedTime < rhs.lastStartedTime;
117 static const int DEFAULT_MAX_SERVICES = 5;
118 int defaultMaxServices, maxServices;
119 // queue to keep track of the order in which services have been used
120 // (most recently used at the back)
121 QLinkedList<QString> serviceQueue;
122 QHash<QString, ServiceInfo> serviceInfo;
123 RecentApplications instance;
125 K_GLOBAL_STATIC(RecentApplications::Private, privateSelf)
127 RecentApplications *RecentApplications::self()
129 return &privateSelf->instance;
132 RecentApplications::RecentApplications()
136 QList<KService::Ptr> RecentApplications::recentApplications() const
138 QList<Private::ServiceInfo> services = privateSelf->serviceInfo.values();
139 qSort(services.begin(), services.end(), qGreater<Private::ServiceInfo>());
141 QList<KService::Ptr> servicePtrs;
142 foreach(const Private::ServiceInfo& info, services) {
143 KService::Ptr s = KService::serviceByStorageId(info.storageId);
145 if (s) {
146 servicePtrs << s;
149 return servicePtrs;
151 int RecentApplications::startCount(KService::Ptr service) const
153 return privateSelf->serviceInfo[service->storageId()].startCount;
155 QDateTime RecentApplications::lastStartedTime(KService::Ptr service) const
157 return privateSelf->serviceInfo[service->storageId()].lastStartedTime;
159 void RecentApplications::setMaximum(int maximum)
161 Q_ASSERT(maximum >= 0);
162 privateSelf->maxServices = maximum;
163 privateSelf->removeExpiredEntries();
165 int RecentApplications::maximum() const
167 return privateSelf->maxServices;
169 int RecentApplications::defaultMaximum() const
171 return privateSelf->defaultMaxServices;
173 void RecentApplications::add(KService::Ptr service)
175 Private::ServiceInfo info = privateSelf->serviceInfo.value(service->storageId());
176 info.storageId = service->storageId();
177 info.startCount++;
178 info.lastStartedTime = QDateTime::currentDateTime();
180 privateSelf->addEntry(info.storageId, info);
182 kDebug() << "Recent app added" << info.storageId << info.startCount;
183 emit applicationAdded(service, info.startCount);
185 privateSelf->removeExpiredEntries();
187 void RecentApplications::clear()
189 privateSelf->serviceInfo.clear();
190 emit cleared();
193 #include "recentapplications.moc"