1
// vim: set tabstop=4 shiftwidth=4 noexpandtab
3
Gwenview - A simple image viewer for KDE
4
Copyright 2000-2004 Aur�lien G�teau
6
This program is free software; you can redistribute it and/or
7
modify it under the terms of the GNU General Public License
8
as published by the Free Software Foundation; either version 2
9
of the License, or (at your option) any later version.
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29
#include <kdesktopfile.h>
32
#include <kstandarddirs.h>
36
#include "externaltoolcontext.h"
37
#include "externaltoolmanager.h"
42
#define LOG(x) kdDebug() << k_funcinfo << x << endl
47
// Helper functions for createContextInternal
48
inline bool mimeTypeMatches(const QString& candidate, const QString& reference) {
49
if (reference=="*") return true;
51
if (reference.right(1)=="*") {
52
return candidate.startsWith(reference.left(reference.length()-1));
54
return candidate==reference;
58
inline bool isSubSetOf(const QStringList& subSet, const QStringList& set) {
59
// Simple implementation, might need some optimization
60
QStringList::ConstIterator itSubSet=subSet.begin();
61
QStringList::ConstIterator itSetBegin=set.begin();
62
QStringList::ConstIterator itSetEnd=set.end();
64
for (; itSubSet!=subSet.end(); ++itSubSet) {
65
bool matchFound=false;
66
QStringList::ConstIterator itSet=itSetBegin;
67
for (; itSet!=itSetEnd; ++itSet) {
68
if (mimeTypeMatches(*itSubSet, *itSet)) {
81
struct ExternalToolManagerPrivate {
82
QDict<KDesktopFile> mDesktopFiles;
83
QPtrList<KService> mServices;
87
* Helper function for createContextInternal
89
static bool compareKServicePtrByName(const KService* s1, const KService* s2) {
92
return s1->name() < s2->name();
95
ExternalToolContext* createContextInternal(
96
QObject* parent, const KURL::List& urls, const QStringList& mimeTypes)
98
bool onlyOneURL=urls.size()==1;
100
// Only add to selectionServices the services which can handle all the
101
// different mime types present in the selection
103
// We use std::list instead of QValueList because it's not possible to
104
// pass a sort functor to qHeapSort
105
std::list<KService*> selectionServices;
106
QPtrListIterator<KService> it(mServices);
107
for (; it.current(); ++it) {
108
KService* service=it.current();
109
if (!onlyOneURL && !service->allowMultipleFiles()) {
113
QStringList serviceTypes=service->serviceTypes();
114
if (isSubSetOf(mimeTypes, serviceTypes)) {
115
selectionServices.push_back(service);
118
selectionServices.sort(compareKServicePtrByName);
120
return new ExternalToolContext(parent, selectionServices, urls);
126
// Helper function for ctor
127
void loadDesktopFiles(QDict<KDesktopFile>& dict, const QString& dirString) {
129
QStringList list=dir.entryList("*.desktop");
130
QStringList::ConstIterator it=list.begin();
131
for (; it!=list.end(); ++it) {
132
KDesktopFile* df=new KDesktopFile( dir.filePath(*it) );
133
dict.insert(*it, df);
137
inline QString addSlash(const QString& _str) {
139
if (str.right(1)!="/") str.append('/');
143
ExternalToolManager::ExternalToolManager() {
144
d=new ExternalToolManagerPrivate;
147
d->mUserToolDir=KGlobal::dirs()->saveLocation("appdata", "tools");
148
d->mUserToolDir=addSlash(d->mUserToolDir);
149
Q_ASSERT(!d->mUserToolDir.isEmpty());
150
LOG("d->mUserToolDir:" << d->mUserToolDir);
152
QStringList dirs=KGlobal::dirs()->findDirs("appdata", "tools");
153
LOG("dirs:" << dirs.join(","));
155
// Loading desktop files
156
QDict<KDesktopFile> systemDesktopFiles;
157
QStringList::ConstIterator it;
158
for (it=dirs.begin(); it!=dirs.end(); ++it) {
159
if (addSlash(*it)==d->mUserToolDir) {
160
LOG("skipping " << *it);
163
LOG("loading system desktop files from " << *it);
164
loadDesktopFiles(systemDesktopFiles, *it);
166
QDict<KDesktopFile> userDesktopFiles;
167
loadDesktopFiles(userDesktopFiles, d->mUserToolDir);
169
// Merge system and user desktop files into our KDesktopFile dictionary
170
d->mDesktopFiles=systemDesktopFiles;
171
d->mDesktopFiles.setAutoDelete(true);
172
QDictIterator<KDesktopFile> itDict(userDesktopFiles);
174
for (; itDict.current(); ++itDict) {
175
QString name=itDict.currentKey();
176
KDesktopFile* df=itDict.current();
177
if (d->mDesktopFiles.find(name)) {
178
d->mDesktopFiles.remove(name);
180
if (df->readBoolEntry("Hidden")) {
183
d->mDesktopFiles.insert(name, df);
187
d->mServices.setAutoDelete(true);
192
ExternalToolManager::~ExternalToolManager() {
197
ExternalToolManager* ExternalToolManager::instance() {
198
static ExternalToolManager manager;
203
void ExternalToolManager::updateServices() {
204
d->mServices.clear();
205
QDictIterator<KDesktopFile> it(d->mDesktopFiles);
206
for (; it.current(); ++it) {
207
KDesktopFile* desktopFile=it.current();
208
// If sync() is not called, KService does not read up to date content
210
KService* service=new KService(desktopFile);
211
d->mServices.append(service);
216
QDict<KDesktopFile>& ExternalToolManager::desktopFiles() const {
217
return d->mDesktopFiles;
221
void ExternalToolManager::hideDesktopFile(KDesktopFile* desktopFile) {
222
QFileInfo fi(desktopFile->fileName());
223
QString name=QString("%1.desktop").arg( fi.baseName(true) );
224
d->mDesktopFiles.take(name);
226
if (desktopFile->isReadOnly()) {
228
desktopFile=new KDesktopFile(d->mUserToolDir + "/" + name, false);
230
desktopFile->writeEntry("Hidden", true);
236
KDesktopFile* ExternalToolManager::editSystemDesktopFile(const KDesktopFile* desktopFile) {
237
Q_ASSERT(desktopFile);
238
QFileInfo fi(desktopFile->fileName());
240
QString name=fi.baseName(true);
241
d->mDesktopFiles.remove(QString("%1.desktop").arg(name));
243
return createUserDesktopFile(name);
247
KDesktopFile* ExternalToolManager::createUserDesktopFile(const QString& name) {
248
Q_ASSERT(!name.isEmpty());
249
KDesktopFile* desktopFile=new KDesktopFile(
250
d->mUserToolDir + "/" + name + ".desktop", false);
251
d->mDesktopFiles.insert(QString("%1.desktop").arg(name), desktopFile);
257
ExternalToolContext* ExternalToolManager::createContext(
258
QObject* parent, const KFileItemList* items)
261
QStringList mimeTypes;
263
// Create our URL list and a list of the different mime types present in
265
QPtrListIterator<KFileItem> it(*items);
266
for (; it.current(); ++it) {
267
urls.append(it.current()->url());
268
QString mimeType=it.current()->mimetype();
269
if (!mimeTypes.contains(mimeType)) {
270
mimeTypes.append(mimeType);
274
return d->createContextInternal(parent, urls, mimeTypes);
278
ExternalToolContext* ExternalToolManager::createContext(
279
QObject* parent, const KURL& url)
282
QStringList mimeTypes;
285
QString mimeType=KMimeType::findByURL(url, 0, url.isLocalFile(), true)->name();
286
mimeTypes.append(mimeType);
288
return d->createContextInternal(parent, urls, mimeTypes);