1 /* This file is part of the KDE project
2 Copyright (C) 2003 Joseph Wenninger <jowenn@kde.org>
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.
20 #include <kio/slavebase.h>
21 #include <kcomponentdata.h>
27 #include <kservicegroup.h>
28 #include <kstandarddirs.h>
30 class ApplicationsProtocol
: public KIO::SlaveBase
33 enum RunMode
{ ProgramsMode
, ApplicationsMode
};
34 ApplicationsProtocol(const QByteArray
&protocol
, const QByteArray
&pool
, const QByteArray
&app
);
35 virtual ~ApplicationsProtocol();
36 virtual void get( const KUrl
& url
);
37 virtual void stat(const KUrl
& url
);
38 virtual void listDir(const KUrl
& url
);
45 KDE_EXPORT
int kdemain( int, char **argv
)
47 KComponentData
componentData( "kio_applications" );
48 ApplicationsProtocol
slave(argv
[1], argv
[2], argv
[3]);
55 static void createFileEntry(KIO::UDSEntry
& entry
, const KService::Ptr
& service
, const KUrl
& parentUrl
)
58 entry
.insert(KIO::UDSEntry::UDS_NAME
, KIO::encodeFileName(service
->name()));
59 entry
.insert(KIO::UDSEntry::UDS_FILE_TYPE
, S_IFREG
);
60 const QString fileUrl
= parentUrl
.url(KUrl::AddTrailingSlash
) + service
->desktopEntryName();
61 entry
.insert(KIO::UDSEntry::UDS_URL
, fileUrl
);
62 entry
.insert(KIO::UDSEntry::UDS_ACCESS
, 0500);
63 entry
.insert(KIO::UDSEntry::UDS_MIME_TYPE
, "application/x-desktop");
64 entry
.insert(KIO::UDSEntry::UDS_SIZE
, 0);
65 entry
.insert(KIO::UDSEntry::UDS_LOCAL_PATH
, KStandardDirs::locate("apps", service
->entryPath()));
66 entry
.insert(KIO::UDSEntry::UDS_MODIFICATION_TIME
, time(0));
67 entry
.insert(KIO::UDSEntry::UDS_ICON_NAME
, service
->icon());
70 static void createDirEntry(KIO::UDSEntry
& entry
, const QString
& name
, const QString
& url
, const QString
& mime
,const QString
& iconName
)
73 entry
.insert( KIO::UDSEntry::UDS_NAME
, name
);
74 entry
.insert( KIO::UDSEntry::UDS_FILE_TYPE
, S_IFDIR
);
75 entry
.insert( KIO::UDSEntry::UDS_ACCESS
, 0500 );
76 entry
.insert( KIO::UDSEntry::UDS_MIME_TYPE
, mime
);
78 entry
.insert( KIO::UDSEntry::UDS_URL
, url
);
79 entry
.insert( KIO::UDSEntry::UDS_ICON_NAME
, iconName
);
82 ApplicationsProtocol::ApplicationsProtocol( const QByteArray
&protocol
, const QByteArray
&pool
, const QByteArray
&app
)
83 : SlaveBase( protocol
, pool
, app
)
85 // Adjusts which part of the K Menu to virtualize.
86 if ( protocol
== "programs" )
87 m_runMode
= ProgramsMode
;
88 else // if (protocol == "applications")
89 m_runMode
= ApplicationsMode
;
92 ApplicationsProtocol::~ApplicationsProtocol()
96 void ApplicationsProtocol::get( const KUrl
& url
)
98 KService::Ptr service
= KService::serviceByDesktopName(url
.fileName());
99 if (service
&& service
->isValid()) {
100 KUrl
redirUrl(KStandardDirs::locate("apps", service
->entryPath()));
101 redirection(redirUrl
);
104 error( KIO::ERR_IS_DIRECTORY
, url
.prettyUrl() );
109 void ApplicationsProtocol::stat(const KUrl
& url
)
113 QString
servicePath( url
.path( KUrl::AddTrailingSlash
) );
114 servicePath
.remove(0, 1); // remove starting '/'
116 KServiceGroup::Ptr grp
= KServiceGroup::group(servicePath
);
118 if (grp
&& grp
->isValid()) {
119 createDirEntry(entry
, ((m_runMode
==ApplicationsMode
) ? i18n("Applications") : i18n("Programs")),
120 url
.url(), "inode/directory",grp
->icon() );
122 KService::Ptr service
= KService::serviceByDesktopName( url
.fileName() );
123 if (service
&& service
->isValid()) {
124 createFileEntry(entry
, service
, url
);
126 error(KIO::ERR_SLAVE_DEFINED
,i18n("Unknown application folder"));
136 void ApplicationsProtocol::listDir(const KUrl
& url
)
138 QString groupPath
= url
.path( KUrl::AddTrailingSlash
);
139 groupPath
.remove(0, 1); // remove starting '/'
141 KServiceGroup::Ptr grp
= KServiceGroup::group(groupPath
);
143 if (!grp
|| !grp
->isValid()) {
144 error(KIO::ERR_DOES_NOT_EXIST
, groupPath
);
148 unsigned int count
= 0;
151 foreach (const KSycocaEntry::Ptr
&e
, grp
->entries(true, true)) {
152 if (e
->isType(KST_KServiceGroup
)) {
153 KServiceGroup::Ptr
g(KServiceGroup::Ptr::staticCast(e
));
154 QString groupCaption
= g
->caption();
156 kDebug() << "ADDING SERVICE GROUP WITH PATH " << g
->relPath();
158 // Avoid adding empty groups.
159 KServiceGroup::Ptr subMenuRoot
= KServiceGroup::group(g
->relPath());
160 if (subMenuRoot
->childCount() == 0)
164 if ((g
->name().at(0) == '.'))
167 QString relPath
= g
->relPath();
168 KUrl dirUrl
= url
; // preserve protocol, whether that's programs:/ or applications:/
169 dirUrl
.setPath('/' + relPath
);
170 kDebug() << "ApplicationsProtocol: adding entry" << dirUrl
;
171 createDirEntry(entry
, groupCaption
, dirUrl
.url(), "inode/directory", g
->icon());
174 KService::Ptr
service(KService::Ptr::staticCast(e
));
176 kDebug() << "the entry name is" << service
->desktopEntryName()
177 << "with path" << service
->entryPath();
179 if (!service
->isApplication()) // how could this happen?
181 createFileEntry(entry
, service
, url
);
184 listEntry(entry
, false);
189 listEntry(entry
, true);