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.
21 #include "core/recentlyusedmodel.h"
27 #include <KDesktopFile>
30 #include <KLocalizedString>
31 #include <KRecentDocument>
36 #include "core/models.h"
37 #include "core/recentapplications.h"
38 #include "recentadaptor.h"
40 using namespace Kickoff
;
42 class RecentlyUsedModel::Private
45 Private(RecentlyUsedModel
*parent
, RecentType recenttype
, int maxRecentApps
)
47 , recenttype(recenttype
)
48 , maxRecentApps(maxRecentApps
>= 0 ? maxRecentApps
: Kickoff::RecentApplications::self()->defaultMaximum())
49 , recentDocumentItem(0)
53 void removeExistingItem(const QString
& path
) {
54 if (!itemsByPath
.contains(path
)) {
58 QStandardItem
*existingItem
= itemsByPath
[path
];
59 //kDebug() << "Removing existing item" << existingItem;
60 Q_ASSERT(existingItem
->parent());
61 existingItem
->parent()->removeRow(existingItem
->row());
62 itemsByPath
.remove(path
);
64 void addRecentApplication(KService::Ptr service
, bool append
) {
65 // remove existing item if any
66 removeExistingItem(service
->entryPath());
68 QStandardItem
*appItem
= StandardItemFactory::createItemForService(service
);
69 itemsByPath
.insert(service
->entryPath(), appItem
);
72 recentAppItem
->appendRow(appItem
);
74 recentAppItem
->insertRow(0, appItem
);
77 while (recentAppItem
->rowCount() > maxRecentApps
) {
78 recentAppItem
->removeRow(recentAppItem
->rowCount() - 1);
81 void addRecentDocument(const QString
& desktopPath
, bool append
) {
82 // remove existing item if any
83 KDesktopFile
desktopFile(desktopPath
);
84 KUrl documentUrl
= desktopFile
.readUrl();
86 removeExistingItem(documentUrl
.url());
88 QStandardItem
*documentItem
= StandardItemFactory::createItemForUrl(desktopPath
);
89 documentItem
->setData(true, Kickoff::SubTitleMandatoryRole
);
90 itemsByPath
.insert(desktopPath
, documentItem
);
92 //kDebug() << "Document item" << documentItem << "text" << documentItem->text() << "url" << documentUrl.url();
94 recentDocumentItem
->appendRow(documentItem
);
96 recentDocumentItem
->insertRow(0, documentItem
);
99 void loadRecentDocuments() {
100 // create branch for documents and add existing items
101 recentDocumentItem
= new QStandardItem(i18n("Documents"));
102 QStringList documents
= KRecentDocument::recentDocuments();
103 foreach(const QString
& document
, documents
) {
104 addRecentDocument(document
, true);
106 q
->appendRow(recentDocumentItem
);
108 void loadRecentApplications() {
109 recentAppItem
= new QStandardItem(i18n("Applications"));
110 QList
<KService::Ptr
> services
= RecentApplications::self()->recentApplications();
111 for(int i
= 0; i
< maxRecentApps
&& i
< services
.count(); ++i
) {
112 addRecentApplication(services
[i
], true);
114 q
->appendRow(recentAppItem
);
117 RecentlyUsedModel
* const q
;
118 RecentType recenttype
;
121 QStandardItem
*recentDocumentItem
;
122 QStandardItem
*recentAppItem
;
123 QHash
<QString
, QStandardItem
*> itemsByPath
;
126 RecentlyUsedModel::RecentlyUsedModel(QObject
*parent
, RecentType recenttype
, int maxRecentApps
)
127 : KickoffModel(parent
)
128 , d(new Private(this, recenttype
, maxRecentApps
))
130 QDBusConnection dbus
= QDBusConnection::sessionBus();
131 (void)new RecentAdaptor(this);
132 QDBusConnection::sessionBus().registerObject("/kickoff/RecentAppDoc", this);
133 dbus
.connect(QString(), "/kickoff/RecentAppDoc", "org.kde.plasma", "clearRecentDocumentsAndApplications", this, SLOT(clearRecentDocumentsAndApplications()));
135 if(recenttype
!= DocumentsOnly
) {
136 d
->loadRecentApplications();
138 // listen for changes to the list of recent applications
139 connect(RecentApplications::self(), SIGNAL(applicationAdded(KService::Ptr
, int)),
140 this, SLOT(recentApplicationAdded(KService::Ptr
, int)));
141 connect(RecentApplications::self(), SIGNAL(applicationRemoved(KService::Ptr
)),
142 this, SLOT(recentApplicationRemoved(KService::Ptr
)));
143 connect(RecentApplications::self(), SIGNAL(cleared()),
144 this, SLOT(recentApplicationsCleared()));
146 if(recenttype
!= ApplicationsOnly
) {
147 d
->loadRecentDocuments();
149 // listen for changes to the list of recent documents
150 KDirWatch
*recentDocWatch
= new KDirWatch(this);
151 recentDocWatch
->addDir(KRecentDocument::recentDocumentDirectory(), KDirWatch::WatchFiles
);
152 connect(recentDocWatch
, SIGNAL(created(QString
)), this, SLOT(recentDocumentAdded(QString
)));
153 connect(recentDocWatch
, SIGNAL(deleted(QString
)), this, SLOT(recentDocumentRemoved(QString
)));
156 RecentlyUsedModel::~RecentlyUsedModel()
161 void RecentlyUsedModel::recentDocumentAdded(const QString
& path
)
163 kDebug() << "Recent document added" << path
;
164 d
->addRecentDocument(path
, false);
166 void RecentlyUsedModel::recentDocumentRemoved(const QString
& path
)
168 kDebug() << "Recent document removed" << path
;
169 d
->removeExistingItem(path
);
172 void RecentlyUsedModel::recentApplicationAdded(KService::Ptr service
, int)
175 d
->addRecentApplication(service
, false);
179 void RecentlyUsedModel::recentApplicationRemoved(KService::Ptr service
)
182 d
->removeExistingItem(service
->entryPath());
186 void RecentlyUsedModel::recentApplicationsCleared()
188 QSet
<QStandardItem
*> appItems
;
189 const int rows
= d
->recentAppItem
->rowCount();
190 for (int i
= 0;i
< rows
;i
++) {
191 appItems
<< d
->recentAppItem
->child(i
);
193 QMutableHashIterator
<QString
, QStandardItem
*> iter(d
->itemsByPath
);
194 while (iter
.hasNext()) {
196 if (appItems
.contains(iter
.value())) {
201 d
->recentAppItem
->removeRows(0, d
->recentAppItem
->rowCount());
203 void RecentlyUsedModel::clearRecentApplications()
205 RecentApplications::self()->clear();
207 void RecentlyUsedModel::clearRecentDocuments()
209 KRecentDocument::clear();
212 void RecentlyUsedModel::clearRecentDocumentsAndApplications()
214 clearRecentDocuments();
215 clearRecentApplications();
219 #include "recentlyusedmodel.moc"