00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "core/recentlyusedmodel.h"
00022
00023
00024 #include <QFileInfo>
00025
00026
00027 #include <KDesktopFile>
00028 #include <KDirWatch>
00029 #include <KIcon>
00030 #include <KLocalizedString>
00031 #include <KRecentDocument>
00032 #include <KUrl>
00033 #include <KDebug>
00034
00035
00036 #include "core/models.h"
00037 #include "core/recentapplications.h"
00038 #include "recentadaptor.h"
00039
00040 using namespace Kickoff;
00041
00042 class RecentlyUsedModel::Private
00043 {
00044 public:
00045 Private(RecentlyUsedModel *parent, RecentType recenttype, int maxRecentApps)
00046 : q(parent)
00047 , recenttype(recenttype)
00048 , maxRecentApps(maxRecentApps >= 0 ? maxRecentApps : Kickoff::RecentApplications::self()->defaultMaximum())
00049 , recentDocumentItem(0)
00050 , recentAppItem(0)
00051 {
00052 }
00053 void removeExistingItem(const QString& path) {
00054 if (!itemsByPath.contains(path)) {
00055 return;
00056 }
00057
00058 QStandardItem *existingItem = itemsByPath[path];
00059
00060 Q_ASSERT(existingItem->parent());
00061 existingItem->parent()->removeRow(existingItem->row());
00062 itemsByPath.remove(path);
00063 }
00064 void addRecentApplication(KService::Ptr service, bool append) {
00065
00066 removeExistingItem(service->entryPath());
00067
00068 QStandardItem *appItem = StandardItemFactory::createItemForService(service);
00069 itemsByPath.insert(service->entryPath(), appItem);
00070
00071 if (append) {
00072 recentAppItem->appendRow(appItem);
00073 } else {
00074 recentAppItem->insertRow(0, appItem);
00075 }
00076
00077 while (recentAppItem->rowCount() > maxRecentApps) {
00078 recentAppItem->removeRow(recentAppItem->rowCount() - 1);
00079 }
00080 }
00081 void addRecentDocument(const QString& desktopPath, bool append) {
00082
00083 KDesktopFile desktopFile(desktopPath);
00084 KUrl documentUrl = desktopFile.readUrl();
00085
00086 removeExistingItem(documentUrl.url());
00087
00088 QStandardItem *documentItem = StandardItemFactory::createItemForUrl(desktopPath);
00089 documentItem->setData(true, Kickoff::SubTitleMandatoryRole);
00090 itemsByPath.insert(desktopPath, documentItem);
00091
00092
00093 if (append) {
00094 recentDocumentItem->appendRow(documentItem);
00095 } else {
00096 recentDocumentItem->insertRow(0, documentItem);
00097 }
00098 }
00099 void loadRecentDocuments() {
00100
00101 recentDocumentItem = new QStandardItem(i18n("Documents"));
00102 QStringList documents = KRecentDocument::recentDocuments();
00103 foreach(const QString& document, documents) {
00104 addRecentDocument(document, true);
00105 }
00106 q->appendRow(recentDocumentItem);
00107 }
00108 void loadRecentApplications() {
00109 recentAppItem = new QStandardItem(i18n("Applications"));
00110 QList<KService::Ptr> services = RecentApplications::self()->recentApplications();
00111 for(int i = 0; i < maxRecentApps && i < services.count(); ++i) {
00112 addRecentApplication(services[i], true);
00113 }
00114 q->appendRow(recentAppItem);
00115 }
00116
00117 RecentlyUsedModel * const q;
00118 RecentType recenttype;
00119 int maxRecentApps;
00120
00121 QStandardItem *recentDocumentItem;
00122 QStandardItem *recentAppItem;
00123 QHash<QString, QStandardItem*> itemsByPath;
00124 };
00125
00126 RecentlyUsedModel::RecentlyUsedModel(QObject *parent, RecentType recenttype, int maxRecentApps)
00127 : KickoffModel(parent)
00128 , d(new Private(this, recenttype, maxRecentApps))
00129 {
00130 QDBusConnection dbus = QDBusConnection::sessionBus();
00131 (void)new RecentAdaptor(this);
00132 QDBusConnection::sessionBus().registerObject("/kickoff/RecentAppDoc", this);
00133 dbus.connect(QString(), "/kickoff/RecentAppDoc", "org.kde.plasma", "clearRecentDocumentsAndApplications", this, SLOT(clearRecentDocumentsAndApplications()));
00134
00135 if(recenttype != DocumentsOnly) {
00136 d->loadRecentApplications();
00137
00138
00139 connect(RecentApplications::self(), SIGNAL(applicationAdded(KService::Ptr, int)),
00140 this, SLOT(recentApplicationAdded(KService::Ptr, int)));
00141 connect(RecentApplications::self(), SIGNAL(applicationRemoved(KService::Ptr)),
00142 this, SLOT(recentApplicationRemoved(KService::Ptr)));
00143 connect(RecentApplications::self(), SIGNAL(cleared()),
00144 this, SLOT(recentApplicationsCleared()));
00145 }
00146 if(recenttype != ApplicationsOnly) {
00147 d->loadRecentDocuments();
00148
00149
00150 KDirWatch *recentDocWatch = new KDirWatch(this);
00151 recentDocWatch->addDir(KRecentDocument::recentDocumentDirectory(), KDirWatch::WatchFiles);
00152 connect(recentDocWatch, SIGNAL(created(QString)), this, SLOT(recentDocumentAdded(QString)));
00153 connect(recentDocWatch, SIGNAL(deleted(QString)), this, SLOT(recentDocumentRemoved(QString)));
00154 }
00155 }
00156 RecentlyUsedModel::~RecentlyUsedModel()
00157 {
00158 delete d;
00159 }
00160
00161 void RecentlyUsedModel::recentDocumentAdded(const QString& path)
00162 {
00163 kDebug() << "Recent document added" << path;
00164 d->addRecentDocument(path, false);
00165 }
00166 void RecentlyUsedModel::recentDocumentRemoved(const QString& path)
00167 {
00168 kDebug() << "Recent document removed" << path;
00169 d->removeExistingItem(path);
00170 }
00171
00172 void RecentlyUsedModel::recentApplicationAdded(KService::Ptr service, int)
00173 {
00174 if (service) {
00175 d->addRecentApplication(service, false);
00176 }
00177 }
00178
00179 void RecentlyUsedModel::recentApplicationRemoved(KService::Ptr service)
00180 {
00181 if (service) {
00182 d->removeExistingItem(service->entryPath());
00183 }
00184 }
00185
00186 void RecentlyUsedModel::recentApplicationsCleared()
00187 {
00188 QSet<QStandardItem*> appItems;
00189 const int rows = d->recentAppItem->rowCount();
00190 for (int i = 0;i < rows;i++) {
00191 appItems << d->recentAppItem->child(i);
00192 }
00193 QMutableHashIterator<QString, QStandardItem*> iter(d->itemsByPath);
00194 while (iter.hasNext()) {
00195 iter.next();
00196 if (appItems.contains(iter.value())) {
00197 iter.remove();
00198 }
00199 }
00200
00201 d->recentAppItem->removeRows(0, d->recentAppItem->rowCount());
00202 }
00203 void RecentlyUsedModel::clearRecentApplications()
00204 {
00205 RecentApplications::self()->clear();
00206 }
00207 void RecentlyUsedModel::clearRecentDocuments()
00208 {
00209 KRecentDocument::clear();
00210 }
00211
00212 void RecentlyUsedModel::clearRecentDocumentsAndApplications()
00213 {
00214 clearRecentDocuments();
00215 clearRecentApplications();
00216 }
00217
00218
00219 #include "recentlyusedmodel.moc"
00220