~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to plasma/desktop/applets/kickoff/core/recentapplications.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    Copyright 2007 Robert Knight <robertknight@gmail.com>
 
3
 
 
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.
 
8
 
 
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.
 
13
 
 
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.
 
18
*/
 
19
 
 
20
// Own
 
21
#include "core/recentapplications.h"
 
22
 
 
23
// Qt
 
24
#include <QtCore/QHash>
 
25
#include <QtCore/QLinkedList>
 
26
 
 
27
// KDE
 
28
#include <KConfigGroup>
 
29
#include <KDebug>
 
30
 
 
31
// Local
 
32
#include "core/models.h"
 
33
 
 
34
using namespace Kickoff;
 
35
 
 
36
class RecentApplications::Private
 
37
{
 
38
public:
 
39
    class ServiceInfo;
 
40
 
 
41
    Private() : defaultMaxServices(DEFAULT_MAX_SERVICES) {
 
42
        KConfigGroup recentGroup = componentData().config()->group("RecentlyUsed");
 
43
        QList<QString> recentApplications = recentGroup.readEntry("Applications", QList<QString>());
 
44
        defaultMaxServices = maxServices = qMax(0, recentGroup.readEntry("MaxApplications", defaultMaxServices));
 
45
 
 
46
        // TESTING
 
47
        //      the actual last date/time is not currently recorded, instead we just use
 
48
        //      the current date/time and adjust it by one second after each item is added
 
49
        //      to preserve the order of the applications in the list loaded from the KConfig
 
50
        //      source
 
51
        QDateTime dateTime = QDateTime::currentDateTime();
 
52
        foreach(const QString& application, recentApplications) {
 
53
            ServiceInfo info;
 
54
            info.storageId = application;
 
55
            info.startCount = 1;
 
56
            info.lastStartedTime = dateTime;
 
57
            addEntry(info.storageId, info);
 
58
            dateTime = dateTime.addSecs(1);
 
59
        }
 
60
    };
 
61
    ~Private() {
 
62
        KConfigGroup recentGroup = componentData().config()->group("RecentlyUsed");
 
63
 
 
64
        QList<ServiceInfo> services = serviceInfo.values();
 
65
        qSort(services.begin(), services.end());
 
66
 
 
67
        // TESTING
 
68
        //      only the desktop file used is currently recorded, information such
 
69
        //      as start count and date/time of last used is lost
 
70
        QList<QString> recentApplications;
 
71
        foreach(const ServiceInfo& info, services) {
 
72
            recentApplications << info.storageId;
 
73
        }
 
74
 
 
75
        recentGroup.writeEntry("Applications", recentApplications);
 
76
        recentGroup.config()->sync();
 
77
    }
 
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);
 
84
        }
 
85
 
 
86
        serviceQueue.append(id);
 
87
        info.queueIter = --serviceQueue.end();
 
88
        serviceInfo.insert(id, info);
 
89
    }
 
90
 
 
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));
 
99
        }
 
100
    }
 
101
 
 
102
    class ServiceInfo
 
103
    {
 
104
    public:
 
105
        ServiceInfo() : startCount(0) {}
 
106
 
 
107
        QString storageId;
 
108
        int startCount;
 
109
        QDateTime lastStartedTime;
 
110
        QLinkedList<QString>::iterator queueIter;
 
111
 
 
112
        bool operator<(const ServiceInfo& rhs) const {
 
113
            return this->lastStartedTime < rhs.lastStartedTime;
 
114
        }
 
115
    };
 
116
 
 
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;
 
124
};
 
125
K_GLOBAL_STATIC(RecentApplications::Private, privateSelf)
 
126
 
 
127
RecentApplications *RecentApplications::self()
 
128
{
 
129
    return &privateSelf->instance;
 
130
}
 
131
 
 
132
RecentApplications::RecentApplications()
 
133
{
 
134
}
 
135
 
 
136
QList<KService::Ptr> RecentApplications::recentApplications() const
 
137
{
 
138
    QList<Private::ServiceInfo> services = privateSelf->serviceInfo.values();
 
139
    qSort(services.begin(), services.end(), qGreater<Private::ServiceInfo>());
 
140
 
 
141
    QList<KService::Ptr> servicePtrs;
 
142
    foreach(const Private::ServiceInfo& info, services) {
 
143
        KService::Ptr s = KService::serviceByStorageId(info.storageId);
 
144
 
 
145
        if (s) {
 
146
            servicePtrs << s;
 
147
        }
 
148
    }
 
149
    return servicePtrs;
 
150
}
 
151
int RecentApplications::startCount(KService::Ptr service) const
 
152
{
 
153
    return privateSelf->serviceInfo[service->storageId()].startCount;
 
154
}
 
155
QDateTime RecentApplications::lastStartedTime(KService::Ptr service) const
 
156
{
 
157
    return privateSelf->serviceInfo[service->storageId()].lastStartedTime;
 
158
}
 
159
void RecentApplications::setMaximum(int maximum)
 
160
{
 
161
    Q_ASSERT(maximum >= 0);
 
162
    privateSelf->maxServices = maximum;
 
163
    privateSelf->removeExpiredEntries();
 
164
}
 
165
int RecentApplications::maximum() const
 
166
{
 
167
    return privateSelf->maxServices;
 
168
}
 
169
int RecentApplications::defaultMaximum() const
 
170
{
 
171
    return privateSelf->defaultMaxServices;
 
172
}
 
173
void RecentApplications::add(KService::Ptr service)
 
174
{
 
175
    Private::ServiceInfo info = privateSelf->serviceInfo.value(service->storageId());
 
176
    info.storageId = service->storageId();
 
177
    info.startCount++;
 
178
    info.lastStartedTime = QDateTime::currentDateTime();
 
179
 
 
180
    privateSelf->addEntry(info.storageId, info);
 
181
 
 
182
    kDebug() << "Recent app added" << info.storageId << info.startCount;
 
183
    emit applicationAdded(service, info.startCount);
 
184
 
 
185
    privateSelf->removeExpiredEntries();
 
186
}
 
187
void RecentApplications::clear()
 
188
{
 
189
    privateSelf->serviceInfo.clear();
 
190
    emit cleared();
 
191
}
 
192
 
 
193
#include "recentapplications.moc"