Changeset View
Changeset View
Standalone View
Standalone View
kioslave/applications/kio_applications.cpp
- This file was added.
1 | /* This file is part of the KDE project | ||||
---|---|---|---|---|---|
2 | Copyright (C) 2003 Joseph Wenninger <jowenn@kde.org> | ||||
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 | #include <kio/slavebase.h> | ||||
21 | #include <sys/stat.h> | ||||
22 | #include <time.h> | ||||
23 | #include <kservice.h> | ||||
24 | #include <kservicegroup.h> | ||||
25 | #include <KLocalizedString> | ||||
26 | | ||||
27 | #include <QStandardPaths> | ||||
28 | #include <QUrl> | ||||
29 | | ||||
30 | class ApplicationsProtocol : public KIO::SlaveBase | ||||
31 | { | ||||
32 | public: | ||||
33 | enum RunMode { ProgramsMode, ApplicationsMode }; | ||||
34 | ApplicationsProtocol(const QByteArray &protocol, const QByteArray &pool, const QByteArray &app); | ||||
35 | ~ApplicationsProtocol() override; | ||||
36 | void get( const QUrl& url ) override; | ||||
37 | void stat(const QUrl& url) override; | ||||
38 | void listDir(const QUrl& url) override; | ||||
39 | | ||||
40 | private: | ||||
41 | RunMode m_runMode; | ||||
42 | }; | ||||
43 | | ||||
44 | extern "C" { | ||||
45 | Q_DECL_EXPORT int kdemain( int argc, char **argv ) | ||||
46 | { | ||||
47 | QCoreApplication app(argc, argv); | ||||
48 | app.setApplicationName( "kio_applications" ); | ||||
49 | | ||||
50 | ApplicationsProtocol slave(argv[1], argv[2], argv[3]); | ||||
51 | slave.dispatchLoop(); | ||||
52 | return 0; | ||||
53 | } | ||||
54 | } | ||||
55 | | ||||
56 | | ||||
57 | static void createFileEntry(KIO::UDSEntry& entry, const KService::Ptr& service, const QUrl& parentUrl) | ||||
58 | { | ||||
59 | entry.clear(); | ||||
60 | entry.insert(KIO::UDSEntry::UDS_NAME, KIO::encodeFileName(service->name())); | ||||
61 | entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFREG); | ||||
62 | const QString fileUrl = parentUrl.url() + '/' + service->desktopEntryName(); | ||||
63 | entry.insert(KIO::UDSEntry::UDS_URL, fileUrl); | ||||
64 | entry.insert(KIO::UDSEntry::UDS_ACCESS, 0500); | ||||
65 | entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, QStringLiteral("application/x-desktop")); | ||||
66 | entry.insert(KIO::UDSEntry::UDS_SIZE, 0); | ||||
67 | const QString localPath = QStandardPaths::locate(QStandardPaths::ApplicationsLocation, QStringLiteral("%1.desktop").arg(service->desktopEntryName())); | ||||
68 | entry.insert(KIO::UDSEntry::UDS_LOCAL_PATH, localPath); | ||||
69 | entry.insert(KIO::UDSEntry::UDS_MODIFICATION_TIME, time(0)); | ||||
70 | entry.insert(KIO::UDSEntry::UDS_ICON_NAME, service->icon()); | ||||
71 | } | ||||
72 | | ||||
73 | static void createDirEntry(KIO::UDSEntry& entry, const QString& name, const QString& url, const QString& mime, const QString& iconName) | ||||
74 | { | ||||
75 | entry.clear(); | ||||
76 | entry.insert( KIO::UDSEntry::UDS_NAME, name ); | ||||
77 | entry.insert( KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR ); | ||||
78 | entry.insert( KIO::UDSEntry::UDS_ACCESS, 0500 ); | ||||
79 | entry.insert( KIO::UDSEntry::UDS_MIME_TYPE, mime ); | ||||
80 | if (!url.isEmpty()) | ||||
81 | entry.insert( KIO::UDSEntry::UDS_URL, url ); | ||||
82 | entry.insert( KIO::UDSEntry::UDS_ICON_NAME, iconName ); | ||||
83 | } | ||||
84 | | ||||
85 | ApplicationsProtocol::ApplicationsProtocol( const QByteArray &protocol, const QByteArray &pool, const QByteArray &app) | ||||
86 | : SlaveBase( protocol, pool, app ) | ||||
87 | { | ||||
88 | // Adjusts which part of the K Menu to virtualize. | ||||
89 | if ( protocol == "programs" ) | ||||
90 | m_runMode = ProgramsMode; | ||||
91 | else // if (protocol == "applications") | ||||
92 | m_runMode = ApplicationsMode; | ||||
93 | } | ||||
94 | | ||||
95 | ApplicationsProtocol::~ApplicationsProtocol() | ||||
96 | { | ||||
97 | } | ||||
98 | | ||||
99 | void ApplicationsProtocol::get( const QUrl & url ) | ||||
100 | { | ||||
101 | KService::Ptr service = KService::serviceByDesktopName(url.fileName()); | ||||
102 | if (service && service->isValid()) { | ||||
103 | const QString localPath = QStandardPaths::locate(QStandardPaths::ApplicationsLocation, QStringLiteral("%1.desktop").arg(service->desktopEntryName())); | ||||
104 | QUrl redirUrl(QUrl::fromLocalFile(localPath)); | ||||
105 | redirection(redirUrl); | ||||
106 | finished(); | ||||
107 | } else { | ||||
108 | error( KIO::ERR_IS_DIRECTORY, url.toDisplayString() ); | ||||
109 | } | ||||
110 | } | ||||
111 | | ||||
112 | | ||||
113 | void ApplicationsProtocol::stat(const QUrl& url) | ||||
114 | { | ||||
115 | KIO::UDSEntry entry; | ||||
116 | | ||||
117 | QString servicePath( url.path() ); | ||||
118 | if(!servicePath.endsWith('/')) | ||||
119 | servicePath.append('/'); | ||||
120 | servicePath.remove(0, 1); // remove starting '/' | ||||
121 | | ||||
122 | KServiceGroup::Ptr grp = KServiceGroup::group(servicePath); | ||||
123 | | ||||
124 | if (grp && grp->isValid()) { | ||||
125 | createDirEntry(entry, ((m_runMode==ApplicationsMode) ? i18n("Applications") : i18n("Programs")), | ||||
126 | url.url(), QStringLiteral("inode/directory"), grp->icon() ); | ||||
127 | } else { | ||||
128 | KService::Ptr service = KService::serviceByDesktopName( url.fileName() ); | ||||
129 | if (service && service->isValid()) { | ||||
130 | createFileEntry(entry, service, url ); | ||||
131 | } else { | ||||
132 | error(KIO::ERR_SLAVE_DEFINED, i18n("Unknown application folder")); | ||||
133 | return; | ||||
134 | } | ||||
135 | } | ||||
136 | | ||||
137 | statEntry(entry); | ||||
138 | finished(); | ||||
139 | } | ||||
140 | | ||||
141 | | ||||
142 | void ApplicationsProtocol::listDir(const QUrl& url) | ||||
143 | { | ||||
144 | QString groupPath = url.path(); | ||||
145 | if(!groupPath.endsWith('/')) | ||||
146 | groupPath.append('/'); | ||||
147 | groupPath.remove(0, 1); // remove starting '/' | ||||
148 | | ||||
149 | KServiceGroup::Ptr grp = KServiceGroup::group(groupPath); | ||||
150 | | ||||
151 | if (!grp || !grp->isValid()) { | ||||
152 | error(KIO::ERR_DOES_NOT_EXIST, groupPath); | ||||
153 | return; | ||||
154 | } | ||||
155 | | ||||
156 | unsigned int count = 0; | ||||
157 | KIO::UDSEntry entry; | ||||
158 | | ||||
159 | foreach (const KSycocaEntry::Ptr &e, grp->entries(true, true)) { | ||||
160 | if (e->isType(KST_KServiceGroup)) { | ||||
161 | KServiceGroup::Ptr g(static_cast<KServiceGroup*>(e.data())); | ||||
162 | | ||||
163 | //qDebug() << "ADDING SERVICE GROUP WITH PATH " << g->relPath(); | ||||
164 | | ||||
165 | // Avoid adding empty groups. | ||||
166 | KServiceGroup::Ptr subMenuRoot = KServiceGroup::group(g->relPath()); | ||||
167 | if (subMenuRoot->childCount() == 0) | ||||
168 | continue; | ||||
169 | | ||||
170 | // Ignore dotfiles. | ||||
171 | if (g->name().startsWith('.')) | ||||
172 | continue; | ||||
173 | | ||||
174 | QString relPath = g->relPath(); | ||||
175 | QUrl dirUrl = url; // preserve protocol, whether that's programs:/ or applications:/ | ||||
176 | dirUrl.setPath('/' + relPath); | ||||
177 | dirUrl = dirUrl.adjusted(QUrl::StripTrailingSlash); | ||||
178 | //qDebug() << "ApplicationsProtocol: adding entry" << dirUrl; | ||||
179 | createDirEntry(entry, g->caption(), dirUrl.url(), QStringLiteral("inode/directory"), g->icon()); | ||||
180 | } else { | ||||
181 | KService::Ptr service(static_cast<KService*>(e.data())); | ||||
182 | | ||||
183 | //qDebug() << "the entry name is" << service->desktopEntryName() | ||||
184 | // << "with path" << service->entryPath(); | ||||
185 | | ||||
186 | if (!service->isApplication()) // how could this happen? | ||||
187 | continue; | ||||
188 | createFileEntry(entry, service, url); | ||||
189 | } | ||||
190 | | ||||
191 | listEntry(entry); | ||||
192 | count++; | ||||
193 | } | ||||
194 | | ||||
195 | totalSize(count); | ||||
196 | listEntry(entry); | ||||
197 | finished(); | ||||
198 | } |