1 /* This file is part of the KDE project
2 Copyright (C) 2003 Joseph Wenninger <jowenn@kde.org>
3 Copyright (C) 2008 David Faure <faure@kde.org>
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
21 #include <kservicetypetrader.h>
22 #include <kio/slavebase.h>
23 #include <kcomponentdata.h>
29 #include <kservicegroup.h>
30 #include <kstandarddirs.h>
32 class SettingsProtocol
: public KIO::SlaveBase
35 SettingsProtocol(const QByteArray
&protocol
, const QByteArray
&pool
, const QByteArray
&app
);
36 virtual ~SettingsProtocol();
37 virtual void get( const KUrl
& url
);
38 virtual void stat(const KUrl
& url
);
39 virtual void listDir(const KUrl
& url
);
42 void initSettingsData();
45 bool m_settingsDataLoaded
;
46 KService::List m_modules
;
47 QHash
<QString
, KService::Ptr
> m_settingsServiceLookup
;
48 KService::List m_categories
;
49 QHash
<QString
, KService::Ptr
> m_categoryLookup
;
53 KDE_EXPORT
int kdemain( int, char **argv
)
55 kDebug() << "kdemain for settings kioslave";
56 KComponentData
componentData( "kio_settings" );
57 SettingsProtocol
slave(argv
[1], argv
[2], argv
[3]);
63 static void createFileEntry(KIO::UDSEntry
& entry
, const KService::Ptr
& service
)
66 entry
.insert(KIO::UDSEntry::UDS_NAME
, KIO::encodeFileName(service
->desktopEntryName()));
67 entry
.insert(KIO::UDSEntry::UDS_DISPLAY_NAME
, service
->name()); // translated name
68 entry
.insert(KIO::UDSEntry::UDS_FILE_TYPE
, S_IFREG
);
69 entry
.insert(KIO::UDSEntry::UDS_ACCESS
, 0500);
70 entry
.insert(KIO::UDSEntry::UDS_MIME_TYPE
, "application/x-desktop");
71 entry
.insert(KIO::UDSEntry::UDS_SIZE
, 0);
72 entry
.insert(KIO::UDSEntry::UDS_LOCAL_PATH
, KStandardDirs::locate("services", service
->entryPath()));
73 entry
.insert(KIO::UDSEntry::UDS_MODIFICATION_TIME
, time(0));
74 entry
.insert(KIO::UDSEntry::UDS_ICON_NAME
, service
->icon());
77 static void createDirEntry(KIO::UDSEntry
& entry
, const QString
& name
, const QString
& iconName
)
80 entry
.insert( KIO::UDSEntry::UDS_NAME
, name
);
81 entry
.insert( KIO::UDSEntry::UDS_FILE_TYPE
, S_IFDIR
);
82 entry
.insert( KIO::UDSEntry::UDS_ACCESS
, 0500 );
83 entry
.insert( KIO::UDSEntry::UDS_MIME_TYPE
, "inode/directory" );
84 entry
.insert( KIO::UDSEntry::UDS_ICON_NAME
, iconName
);
87 SettingsProtocol::SettingsProtocol( const QByteArray
&protocol
, const QByteArray
&pool
, const QByteArray
&app
)
88 : SlaveBase( protocol
, pool
, app
),
89 m_settingsDataLoaded(false)
93 SettingsProtocol::~SettingsProtocol()
97 void SettingsProtocol::initSettingsData()
99 if (m_settingsDataLoaded
)
102 // The code for settings:/ was inspired by kdebase/workspace/systemsettings/mainwindow.cpp readMenu().
104 m_modules
= KServiceTypeTrader::self()->query("KCModule");
105 m_categories
= KServiceTypeTrader::self()->query("SystemSettingsCategory");
107 for (int i
= 0; i
< m_categories
.size(); ++i
) {
108 const KService::Ptr service
= m_categories
.at(i
);
109 const QString category
= service
->property("X-KDE-System-Settings-Category").toString();
110 m_categoryLookup
.insert(category
, service
);
112 for (int i
= 0; i
< m_modules
.size(); ++i
) {
113 const KService::Ptr service
= m_modules
.at(i
);
114 // Since modules have a unique name, we can just look them up by name,
115 // no need to create a real hierarchical structure just for stat().
116 //const QString category = service->property("X-KDE-System-Settings-Parent-Category").toString();
117 m_settingsServiceLookup
.insert(service
->desktopEntryName(), service
);
121 void SettingsProtocol::stat(const KUrl
& url
)
124 const QString fileName
= url
.fileName();
125 kDebug() << fileName
;
129 if (fileName
.isEmpty()) {
130 createDirEntry(entry
, ".", "preferences-system");
137 QHash
<QString
, KService::Ptr
>::const_iterator it
= m_categoryLookup
.constFind(fileName
);
138 if (it
!= m_categoryLookup
.constEnd()) {
139 const KService::Ptr service
= it
.value();
140 QString parentCategory
= service
->property("X-KDE-System-Settings-Parent-Category").toString();
141 QString category
= service
->property("X-KDE-System-Settings-Category").toString();
142 //kDebug() << "category" << service->desktopEntryName() << service->name() << "category=" << category << "parentCategory=" << parentCategory;
143 createDirEntry(entry
, category
, service
->icon());
144 entry
.insert(KIO::UDSEntry::UDS_DISPLAY_NAME
, service
->name());
149 // Is it a config module?
150 it
= m_settingsServiceLookup
.constFind(fileName
);
151 if (it
!= m_settingsServiceLookup
.constEnd()) {
152 const KService::Ptr service
= it
.value();
153 createFileEntry(entry
, service
);
160 error(KIO::ERR_DOES_NOT_EXIST
, url
.url());
163 void SettingsProtocol::listDir(const KUrl
& url
)
166 QString fileName
= url
.fileName();
167 if (!fileName
.isEmpty() && !m_categoryLookup
.contains(fileName
)) {
168 error(KIO::ERR_DOES_NOT_EXIST
, fileName
);
172 unsigned int count
= 0;
175 // scan for any categories at this level and add them
176 for (int i
= 0; i
< m_categories
.size(); ++i
) {
177 const KService::Ptr service
= m_categories
.at(i
);
178 QString parentCategory
= service
->property("X-KDE-System-Settings-Parent-Category").toString();
179 QString category
= service
->property("X-KDE-System-Settings-Category").toString();
180 //kDebug() << "category" << service->desktopEntryName() << service->name() << "category=" << category << "parentCategory=" << parentCategory;
181 if (parentCategory
== fileName
) {
183 //dirUrl.addPath(category);
184 createDirEntry(entry
, category
, service
->icon());
185 entry
.insert(KIO::UDSEntry::UDS_DISPLAY_NAME
, service
->name());
186 listEntry(entry
, false);
191 // scan for any modules at this level and add them
192 for (int i
= 0; i
< m_modules
.size(); ++i
) {
193 const KService::Ptr service
= m_modules
.at(i
);
194 const QString category
= service
->property("X-KDE-System-Settings-Parent-Category").toString();
195 if (!fileName
.isEmpty() && category
== fileName
) {
196 createFileEntry(entry
, service
);
197 listEntry(entry
, false);
203 listEntry(entry
, true);
207 void SettingsProtocol::get( const KUrl
& url
)
209 KService::Ptr service
= KService::serviceByDesktopName(url
.fileName());
210 if (service
&& service
->isValid()) {
212 redirUrl
.setPath(KStandardDirs::locate("services", service
->entryPath()));
213 redirection(redirUrl
);
216 error( KIO::ERR_IS_DIRECTORY
, url
.prettyUrl() );