|
|
|
|
/*
|
|
|
|
|
Gwenview - A simple image viewer for TDE
|
|
|
|
|
Copyright 2000-2004 Aur<EFBFBD>lien G<EFBFBD>teau
|
|
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
|
modify it under the terms of the GNU General Public License
|
|
|
|
|
as published by the Free Software Foundation; either version 2
|
|
|
|
|
of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
|
|
This program 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 General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
// STL
|
|
|
|
|
#include <list>
|
|
|
|
|
|
|
|
|
|
// TQt
|
|
|
|
|
#include <tqdir.h>
|
|
|
|
|
|
|
|
|
|
// KDE
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
|
#include <kdesktopfile.h>
|
|
|
|
|
#include <tdeglobal.h>
|
|
|
|
|
#include <kservice.h>
|
|
|
|
|
#include <kstandarddirs.h>
|
|
|
|
|
#include <kurl.h>
|
|
|
|
|
|
|
|
|
|
// Local
|
|
|
|
|
#include "externaltoolcontext.h"
|
|
|
|
|
#include "externaltoolmanager.h"
|
|
|
|
|
namespace Gwenview {
|
|
|
|
|
|
|
|
|
|
#undef ENABLE_LOG
|
|
|
|
|
#undef LOG
|
|
|
|
|
//#define ENABLE_LOG
|
|
|
|
|
#ifdef ENABLE_LOG
|
|
|
|
|
#define LOG(x) kdDebug() << k_funcinfo << x << endl
|
|
|
|
|
#else
|
|
|
|
|
#define LOG(x) ;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// Helper functions for createContextInternal
|
|
|
|
|
inline bool mimeTypeMatches(const TQString& candidate, const TQString& reference) {
|
|
|
|
|
if (reference=="*") return true;
|
|
|
|
|
|
|
|
|
|
if (reference.right(1)=="*") {
|
|
|
|
|
return candidate.startsWith(reference.left(reference.length()-1));
|
|
|
|
|
} else {
|
|
|
|
|
return candidate==reference;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline bool isSubSetOf(const TQStringList& subSet, const TQStringList& set) {
|
|
|
|
|
// Simple implementation, might need some optimization
|
|
|
|
|
TQStringList::ConstIterator itSubSet=subSet.begin();
|
|
|
|
|
TQStringList::ConstIterator itSetBegin=set.begin();
|
|
|
|
|
TQStringList::ConstIterator itSetEnd=set.end();
|
|
|
|
|
|
|
|
|
|
for (; itSubSet!=subSet.end(); ++itSubSet) {
|
|
|
|
|
bool matchFound=false;
|
|
|
|
|
TQStringList::ConstIterator itSet=itSetBegin;
|
|
|
|
|
for (; itSet!=itSetEnd; ++itSet) {
|
|
|
|
|
if (mimeTypeMatches(*itSubSet, *itSet)) {
|
|
|
|
|
matchFound=true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!matchFound) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct ExternalToolManagerPrivate {
|
|
|
|
|
TQDict<KDesktopFile> mDesktopFiles;
|
|
|
|
|
TQPtrList<KService> mServices;
|
|
|
|
|
TQString mUserToolDir;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Helper function for createContextInternal
|
|
|
|
|
*/
|
|
|
|
|
static bool compareKServicePtrByName(const KService* s1, const KService* s2) {
|
|
|
|
|
Q_ASSERT(s1);
|
|
|
|
|
Q_ASSERT(s2);
|
|
|
|
|
return s1->name() < s2->name();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ExternalToolContext* createContextInternal(
|
|
|
|
|
TQObject* parent, const KURL::List& urls, const TQStringList& mimeTypes)
|
|
|
|
|
{
|
|
|
|
|
bool onlyOneURL=urls.size()==1;
|
|
|
|
|
|
|
|
|
|
// Only add to selectionServices the services which can handle all the
|
|
|
|
|
// different mime types present in the selection
|
|
|
|
|
//
|
|
|
|
|
// We use std::list instead of TQValueList because it's not possible to
|
|
|
|
|
// pass a sort functor to qHeapSort
|
|
|
|
|
std::list<KService*> selectionServices;
|
|
|
|
|
TQPtrListIterator<KService> it(mServices);
|
|
|
|
|
for (; it.current(); ++it) {
|
|
|
|
|
KService* service=it.current();
|
|
|
|
|
if (!onlyOneURL && !service->allowMultipleFiles()) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TQStringList serviceTypes=service->serviceTypes();
|
|
|
|
|
if (isSubSetOf(mimeTypes, serviceTypes)) {
|
|
|
|
|
selectionServices.push_back(service);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
selectionServices.sort(compareKServicePtrByName);
|
|
|
|
|
|
|
|
|
|
return new ExternalToolContext(parent, selectionServices, urls);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Helper function for ctor
|
|
|
|
|
void loadDesktopFiles(TQDict<KDesktopFile>& dict, const TQString& dirString) {
|
|
|
|
|
TQDir dir(dirString);
|
|
|
|
|
TQStringList list=dir.entryList("*.desktop");
|
|
|
|
|
TQStringList::ConstIterator it=list.begin();
|
|
|
|
|
for (; it!=list.end(); ++it) {
|
|
|
|
|
KDesktopFile* df=new KDesktopFile( dir.filePath(*it) );
|
|
|
|
|
dict.insert(*it, df);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inline TQString addSlash(const TQString& _str) {
|
|
|
|
|
TQString str(_str);
|
|
|
|
|
if (str.right(1)!="/") str.append('/');
|
|
|
|
|
return str;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ExternalToolManager::ExternalToolManager() {
|
|
|
|
|
d=new ExternalToolManagerPrivate;
|
|
|
|
|
|
|
|
|
|
// Getting dirs
|
|
|
|
|
d->mUserToolDir=TDEGlobal::dirs()->saveLocation("appdata", "tools");
|
|
|
|
|
d->mUserToolDir=addSlash(d->mUserToolDir);
|
|
|
|
|
Q_ASSERT(!d->mUserToolDir.isEmpty());
|
|
|
|
|
LOG("d->mUserToolDir:" << d->mUserToolDir);
|
|
|
|
|
|
|
|
|
|
TQStringList dirs=TDEGlobal::dirs()->findDirs("appdata", "tools");
|
|
|
|
|
LOG("dirs:" << dirs.join(","));
|
|
|
|
|
|
|
|
|
|
// Loading desktop files
|
|
|
|
|
TQDict<KDesktopFile> systemDesktopFiles;
|
|
|
|
|
TQStringList::ConstIterator it;
|
|
|
|
|
for (it=dirs.begin(); it!=dirs.end(); ++it) {
|
|
|
|
|
if (addSlash(*it)==d->mUserToolDir) {
|
|
|
|
|
LOG("skipping " << *it);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
LOG("loading system desktop files from " << *it);
|
|
|
|
|
loadDesktopFiles(systemDesktopFiles, *it);
|
|
|
|
|
}
|
|
|
|
|
TQDict<KDesktopFile> userDesktopFiles;
|
|
|
|
|
loadDesktopFiles(userDesktopFiles, d->mUserToolDir);
|
|
|
|
|
|
|
|
|
|
// Merge system and user desktop files into our KDesktopFile dictionary
|
|
|
|
|
d->mDesktopFiles=systemDesktopFiles;
|
|
|
|
|
d->mDesktopFiles.setAutoDelete(true);
|
|
|
|
|
TQDictIterator<KDesktopFile> itDict(userDesktopFiles);
|
|
|
|
|
|
|
|
|
|
for (; itDict.current(); ++itDict) {
|
|
|
|
|
TQString name=itDict.currentKey();
|
|
|
|
|
KDesktopFile* df=itDict.current();
|
|
|
|
|
if (d->mDesktopFiles.find(name)) {
|
|
|
|
|
d->mDesktopFiles.remove(name);
|
|
|
|
|
}
|
|
|
|
|
if (df->readBoolEntry("Hidden")) {
|
|
|
|
|
delete df;
|
|
|
|
|
} else {
|
|
|
|
|
d->mDesktopFiles.insert(name, df);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
d->mServices.setAutoDelete(true);
|
|
|
|
|
updateServices();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ExternalToolManager::~ExternalToolManager() {
|
|
|
|
|
delete d;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ExternalToolManager* ExternalToolManager::instance() {
|
|
|
|
|
static ExternalToolManager manager;
|
|
|
|
|
return &manager;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ExternalToolManager::updateServices() {
|
|
|
|
|
d->mServices.clear();
|
|
|
|
|
TQDictIterator<KDesktopFile> it(d->mDesktopFiles);
|
|
|
|
|
for (; it.current(); ++it) {
|
|
|
|
|
KDesktopFile* desktopFile=it.current();
|
|
|
|
|
// If sync() is not called, KService does not read up to date content
|
|
|
|
|
desktopFile->sync();
|
|
|
|
|
KService* service=new KService(desktopFile);
|
|
|
|
|
d->mServices.append(service);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TQDict<KDesktopFile>& ExternalToolManager::desktopFiles() const {
|
|
|
|
|
return d->mDesktopFiles;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ExternalToolManager::hideDesktopFile(KDesktopFile* desktopFile) {
|
|
|
|
|
TQFileInfo fi(desktopFile->fileName());
|
|
|
|
|
TQString name=TQString("%1.desktop").arg( fi.baseName(true) );
|
|
|
|
|
d->mDesktopFiles.take(name);
|
|
|
|
|
|
|
|
|
|
if (desktopFile->isReadOnly()) {
|
|
|
|
|
delete desktopFile;
|
|
|
|
|
desktopFile=new KDesktopFile(d->mUserToolDir + "/" + name, false);
|
|
|
|
|
}
|
|
|
|
|
desktopFile->writeEntry("Hidden", true);
|
|
|
|
|
desktopFile->sync();
|
|
|
|
|
delete desktopFile;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
KDesktopFile* ExternalToolManager::editSystemDesktopFile(const KDesktopFile* desktopFile) {
|
|
|
|
|
Q_ASSERT(desktopFile);
|
|
|
|
|
TQFileInfo fi(desktopFile->fileName());
|
|
|
|
|
|
|
|
|
|
TQString name=fi.baseName(true);
|
|
|
|
|
d->mDesktopFiles.remove(TQString("%1.desktop").arg(name));
|
|
|
|
|
|
|
|
|
|
return createUserDesktopFile(name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
KDesktopFile* ExternalToolManager::createUserDesktopFile(const TQString& name) {
|
|
|
|
|
Q_ASSERT(!name.isEmpty());
|
|
|
|
|
KDesktopFile* desktopFile=new KDesktopFile(
|
|
|
|
|
d->mUserToolDir + "/" + name + ".desktop", false);
|
|
|
|
|
d->mDesktopFiles.insert(TQString("%1.desktop").arg(name), desktopFile);
|
|
|
|
|
|
|
|
|
|
return desktopFile;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ExternalToolContext* ExternalToolManager::createContext(
|
|
|
|
|
TQObject* parent, const KFileItemList* items)
|
|
|
|
|
{
|
|
|
|
|
KURL::List urls;
|
|
|
|
|
TQStringList mimeTypes;
|
|
|
|
|
|
|
|
|
|
// Create our URL list and a list of the different mime types present in
|
|
|
|
|
// the selection
|
|
|
|
|
TQPtrListIterator<KFileItem> it(*items);
|
|
|
|
|
for (; it.current(); ++it) {
|
|
|
|
|
urls.append(it.current()->url());
|
|
|
|
|
TQString mimeType=it.current()->mimetype();
|
|
|
|
|
if (!mimeTypes.contains(mimeType)) {
|
|
|
|
|
mimeTypes.append(mimeType);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return d->createContextInternal(parent, urls, mimeTypes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ExternalToolContext* ExternalToolManager::createContext(
|
|
|
|
|
TQObject* parent, const KURL& url)
|
|
|
|
|
{
|
|
|
|
|
KURL::List urls;
|
|
|
|
|
TQStringList mimeTypes;
|
|
|
|
|
|
|
|
|
|
urls.append(url);
|
|
|
|
|
TQString mimeType=KMimeType::findByURL(url, 0, url.isLocalFile(), true)->name();
|
|
|
|
|
mimeTypes.append(mimeType);
|
|
|
|
|
|
|
|
|
|
return d->createContextInternal(parent, urls, mimeTypes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace
|