/* Copyright 2007 Robert Knight This library 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 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // Own #include "models.h" #include "leavemodel.h" // Qt #include #include #include // KDE #include #include #include #include #include #include #include #include #include #include #include using namespace Kickoff; namespace Kickoff { Q_GLOBAL_STATIC_WITH_ARGS(KUrl, homeUrl, (QDir::homePath())) Q_GLOBAL_STATIC_WITH_ARGS(KUrl, remoteUrl, ("remote:/")) K_GLOBAL_STATIC(StandardItemFactoryData, factoryData) StandardItemFactoryData* deviceFactoryData() { return factoryData; } } // namespace Kickoff QStandardItem *StandardItemFactory::createItemForUrl(const QString& urlString, DisplayOrder displayOrder) { KUrl url(urlString); QStandardItem *item = 0; // Match files ending with ".desktop" and being local or having a relative // path. For instance applications that still installs .desktop files at // /usr/share/applnk, like KVirc 3 if (urlString.endsWith(QLatin1String(".desktop")) && (url.isLocalFile() || url.isRelative())) { // .desktop files may be services (type field == 'Application' or 'Service') // or they may be other types such as links. // // first look in the KDE service database to see if this file is a service, // then we try to look it up by storage id (for eg. system settings entries) // otherwise represent it as a generic .desktop file KService::Ptr service = KService::serviceByDesktopPath(url.toLocalFile()); if (service) { return createItemForService(service, displayOrder); } service = KService::serviceByStorageId(urlString); if (service) { return createItemForService(service, displayOrder); } item = new QStandardItem; KDesktopFile desktopFile(url.toLocalFile()); item->setText(QFileInfo(urlString.mid(0, urlString.lastIndexOf('.'))).completeBaseName()); item->setIcon(QIcon::fromTheme(desktopFile.readIcon(), QIcon::fromTheme("unknown"))); //FIXME: desktopUrl is a hack around borkage in KRecentDocuments which // stores a path in the URL field! KUrl desktopUrl(desktopFile.desktopGroup().readPathEntry("URL", QString())); if (!desktopUrl.url().isEmpty()) { item->setData(desktopUrl.url(), Kickoff::UrlRole); } else { // desktopUrl.url() is empty if the file doesn't exist so set the // url role to that which was passed so that the item can still be // manually removed item->setData(urlString, Kickoff::UrlRole); } QString subTitle = desktopUrl.isLocalFile() ? desktopUrl.toLocalFile() : desktopUrl.prettyUrl(); item->setData(subTitle, Kickoff::SubTitleRole); setSpecialUrlProperties(desktopUrl, item); } else if (url.scheme() == "leave") { item = LeaveModel::createStandardItem(urlString); } else { item = new QStandardItem; const QString subTitle = url.isLocalFile() ? url.toLocalFile() : url.prettyUrl(); QString basename = QFileInfo(url.prettyUrl()).completeBaseName(); if (basename.isNull()) { basename = subTitle; } item->setText(basename); //FIXME // item->setIcon(QIcon::fromTheme(KMimeType::iconNameForUrl(url), QIcon::fromTheme("unknown"))); item->setData(url.url(), Kickoff::UrlRole); item->setData(subTitle, Kickoff::SubTitleRole); setSpecialUrlProperties(url, item); } return item; } void StandardItemFactory::setSpecialUrlProperties(const KUrl& url, QStandardItem *item) { // specially handled URLs if (homeUrl() && url == *homeUrl()) { item->setText(i18n("Home Folder")); item->setIcon(QIcon::fromTheme("user-home")); } else if (remoteUrl() && url == *remoteUrl()) { item->setText(i18n("Network Folders")); } } QStandardItem *StandardItemFactory::createItem(const QIcon & icon, const QString & title, const QString & description, const QString & url, const QString & mimeData) { QStandardItem *appItem = new QStandardItem; appItem->setText(title); appItem->setIcon(icon); appItem->setData(description, Kickoff::SubTitleRole); appItem->setData(url, Kickoff::UrlRole); appItem->setData(mimeData, Kickoff::MimeDataRole); return appItem; } QStandardItem *StandardItemFactory::createItemForService(KService::Ptr service, DisplayOrder displayOrder) { QStandardItem *appItem = new QStandardItem; QString genericName = service->genericName(); QString appName = service->name(); bool nameFirst = displayOrder == NameBeforeDescription; appItem->setText(nameFirst || genericName.isEmpty() ? appName : genericName); appItem->setIcon(QIcon::fromTheme(service->icon(), QIcon::fromTheme("unknown"))); appItem->setData(service->entryPath(), Kickoff::UrlRole); if (nameFirst) { if (!genericName.isEmpty()) { appItem->setData(genericName, Kickoff::SubTitleRole); } } else if (!genericName.isEmpty()) { // we only set the subtitle to appname if the generic name is empty because if // the generic name IS empty, then the app name is used as the title role // and we don't want it repeated twice. appItem->setData(appName, Kickoff::SubTitleRole); } return appItem; } bool Kickoff::isLaterVersion(KService::Ptr first , KService::Ptr second) { // a very crude heuristic using the .desktop path names // which only understands kde3 vs kde4 bool firstIsKde4 = first->entryPath().contains("kde4"); bool secondIsKde4 = second->entryPath().contains("kde4"); return firstIsKde4 && !secondIsKde4; } QStringList Kickoff::systemApplicationList() { KConfigGroup appsGroup = componentData().config()->group("SystemApplications"); QStringList apps; apps << "systemsettings"; apps << appsGroup.readEntry("DesktopFiles", apps); apps.removeDuplicates(); return apps; } #if 0 void Kickoff::swapModelIndexes(QModelIndex& first, QModelIndex& second) { Q_ASSERT(first.isValid()); Q_ASSERT(second.isValid()); QAbstractItemModel *firstModel = const_cast(first.model()); QAbstractItemModel *secondModel = const_cast(second.model()); Q_ASSERT(firstModel && secondModel); QMap firstIndexData = firstModel->itemData(first); QMap secondIndexData = secondModel->itemData(second); firstModel->setItemData(first, secondIndexData); secondModel->setItemData(second, firstIndexData); } #endif K_GLOBAL_STATIC_WITH_ARGS(KComponentData, kickoffComponent, ("kickoff", QByteArray(), KComponentData::SkipMainComponentRegistration)) KComponentData Kickoff::componentData() { return *kickoffComponent; }