summaryrefslogtreecommitdiffstats
path: root/tdeio/tdeio/kurifilter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tdeio/tdeio/kurifilter.cpp')
-rw-r--r--tdeio/tdeio/kurifilter.cpp451
1 files changed, 451 insertions, 0 deletions
diff --git a/tdeio/tdeio/kurifilter.cpp b/tdeio/tdeio/kurifilter.cpp
new file mode 100644
index 000000000..5c50f4fa9
--- /dev/null
+++ b/tdeio/tdeio/kurifilter.cpp
@@ -0,0 +1,451 @@
+/* This file is part of the KDE libraries
+ * Copyright (C) 2000 Yves Arrouye <yves@realnames.com>
+ * Copyright (C) 2000 Dawit Alemayehu <adawit at kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ **/
+
+#include <config.h>
+
+#include <kdebug.h>
+#include <kiconloader.h>
+#include <ktrader.h>
+#include <kmimetype.h>
+#include <klibloader.h>
+#include <kstaticdeleter.h>
+#include <tdeparts/componentfactory.h>
+
+#ifdef HAVE_ELFICON
+#include <tqimage.h>
+#include "tdelficon.h"
+#endif // HAVE_ELFICON
+
+#include "kurifilter.h"
+
+template class TQPtrList<KURIFilterPlugin>;
+
+KURIFilterPlugin::KURIFilterPlugin( TQObject *parent, const char *name, double pri )
+ :TQObject( parent, name )
+{
+ m_strName = TQString::fromLatin1( name );
+ m_dblPriority = pri;
+}
+
+void KURIFilterPlugin::setFilteredURI( KURIFilterData& data, const KURL& uri ) const
+{
+ if ( data.uri() != uri )
+ {
+ data.m_pURI = uri;
+ data.m_bChanged = true;
+ }
+}
+
+class KURIFilterDataPrivate
+{
+public:
+ KURIFilterDataPrivate() {};
+ TQString abs_path;
+ TQString args;
+ TQString typedString;
+};
+
+KURIFilterData::KURIFilterData( const KURIFilterData& data )
+{
+ m_iType = data.m_iType;
+ m_pURI = data.m_pURI;
+ m_strErrMsg = data.m_strErrMsg;
+ m_strIconName = data.m_strIconName;
+ m_bChanged = data.m_bChanged;
+ m_bCheckForExecutables = data.m_bCheckForExecutables;
+ d = new KURIFilterDataPrivate;
+ d->abs_path = data.absolutePath();
+ d->typedString = data.typedString();
+ d->args = data.argsAndOptions();
+}
+
+KURIFilterData::~KURIFilterData()
+{
+ delete d;
+ d = 0;
+}
+
+void KURIFilterData::init( const KURL& url )
+{
+ m_iType = KURIFilterData::UNKNOWN;
+ m_pURI = url;
+ m_strErrMsg = TQString::null;
+ m_strIconName = TQString::null;
+ m_bCheckForExecutables = true;
+ m_bChanged = true;
+ d = new KURIFilterDataPrivate;
+ d->typedString = url.url();
+}
+
+void KURIFilterData::init( const TQString& url )
+{
+ m_iType = KURIFilterData::UNKNOWN;
+ m_pURI = url;
+ m_strErrMsg = TQString::null;
+ m_strIconName = TQString::null;
+ m_bCheckForExecutables = true;
+ m_bChanged = true;
+ d = new KURIFilterDataPrivate;
+ d->typedString = url;
+}
+
+void KURIFilterData::reinit(const KURL &url)
+{
+ delete d;
+ init(url);
+}
+
+void KURIFilterData::reinit(const TQString &url)
+{
+ delete d;
+ init(url);
+}
+
+TQString KURIFilterData::typedString() const
+{
+ return d->typedString;
+}
+
+void KURIFilterData::setCheckForExecutables( bool check )
+{
+ m_bCheckForExecutables = check;
+}
+
+bool KURIFilterData::hasArgsAndOptions() const
+{
+ return !d->args.isEmpty();
+}
+
+bool KURIFilterData::hasAbsolutePath() const
+{
+ return !d->abs_path.isEmpty();
+}
+
+bool KURIFilterData::setAbsolutePath( const TQString& absPath )
+{
+ // Since a malformed URL could possibly be a relative
+ // URL we tag it as a possible local resource...
+ if( (!m_pURI.isValid() || m_pURI.isLocalFile()) )
+ {
+ d->abs_path = absPath;
+ return true;
+ }
+ return false;
+}
+
+TQString KURIFilterData::absolutePath() const
+{
+ return d->abs_path;
+}
+
+TQString KURIFilterData::argsAndOptions() const
+{
+ return d->args;
+}
+
+TQString KURIFilterData::iconName()
+{
+ if( m_bChanged )
+ {
+ m_customIconPixmap = TQPixmap();
+ switch ( m_iType )
+ {
+ case KURIFilterData::LOCAL_FILE:
+ case KURIFilterData::LOCAL_DIR:
+ case KURIFilterData::NET_PROTOCOL:
+ {
+ m_strIconName = KMimeType::iconForURL( m_pURI );
+ break;
+ }
+ case KURIFilterData::EXECUTABLE:
+ {
+ TQString exeName = m_pURI.url();
+ exeName = exeName.mid( exeName.findRev( '/' ) + 1 ); // strip path if given
+ KService::Ptr service = KService::serviceByDesktopName( exeName );
+#ifndef HAVE_ELFICON
+ // Try to find an icon with the same name as the binary (useful for non-tde apps)
+ // FIXME: We should only do this if the binary is in the system path somewhere,
+ // otherwise TDE could end up showing system icons for user binaries
+ if (service && service->icon() != TQString::fromLatin1( "unknown" )) {
+ m_strIconName = service->icon();
+ }
+ else if ( !TDEGlobal::iconLoader()->loadIcon( exeName, KIcon::NoGroup, 16, KIcon::DefaultState, 0, true ).isNull() ) {
+ m_strIconName = exeName;
+ }
+ else {
+ // use default
+ m_strIconName = TQString::fromLatin1("exec");
+ }
+#else // HAVE_ELFICON
+ // Try to find an icon with the same name as the binary (useful for non-tde apps)
+ // FIXME: We should only do this if the binary is in the system path somewhere,
+ // otherwise TDE could end up showing system icons for user binaries
+ if (service && service->icon() != TQString::fromLatin1( "unknown" )) {
+ m_strIconName = service->icon();
+ }
+ else if ( !TDEGlobal::iconLoader()->loadIcon( exeName, KIcon::NoGroup, 16, KIcon::DefaultState, 0, true ).isNull() ) {
+ m_strIconName = exeName;
+ }
+ else {
+ // use default
+ m_strIconName = TQString::fromLatin1("exec");
+ }
+ // Try to load from elf file (if supported)
+ // Check for an embedded icon
+ unsigned int icon_size;
+ libr_icon *icon = NULL;
+ libr_file *handle = NULL;
+ libr_access_t access = LIBR_READ;
+ char libr_can_continue = 1;
+
+ if((handle = libr_open(const_cast<char*>(m_pURI.path().ascii()), access)) == NULL)
+ {
+ kdWarning() << "failed to open file" << m_pURI.path() << endl;
+ libr_can_continue = 0;
+ }
+
+ if (libr_can_continue == 1) {
+ icon_size = 32; // FIXME: Is this a reasonable size request for all possible usages of kurifilter?
+ icon = libr_icon_geticon_bysize(handle, icon_size);
+
+ if (libr_can_continue == 1) {
+ // See if the embedded icon name matches any icon file names already on the system
+ // If it does, use the system icon instead of the embedded one
+ int iconresnamefound = 0;
+ iconentry *entry = NULL;
+ iconlist icons;
+ if(!get_iconlist(handle, &icons))
+ {
+ // Failed to obtain a list of ELF icons
+ kdWarning() << "failed to obtain ELF icon: " << libr_errmsg() << endl;
+
+ // See if there is a system icon we can use
+ TQString sysIconName = elf_get_resource(handle, ".metadata_sysicon");
+ if (!sysIconName.isEmpty()) {
+ if (TDEGlobal::iconLoader()->iconPath(sysIconName.ascii(), 0, true) != "") {
+ m_strIconName = sysIconName;
+ }
+ }
+
+ libr_close(handle);
+ libr_can_continue = 0;
+ }
+ else {
+ while((entry = get_nexticon(&icons, entry)) != NULL)
+ {
+ if(icon == NULL)
+ {
+ // Try loading this icon as fallback
+ icon = libr_icon_geticon_byname(handle, entry->name);
+ }
+ if (TDEGlobal::iconLoader()->iconPath(entry->name, 0, true) != "") {
+ iconresnamefound = 1;
+ m_strIconName = entry->name;
+ break;
+ }
+ }
+ }
+
+ if (libr_can_continue == 1) {
+ if ((iconresnamefound == 0) && (icon)) {
+ // Extract the embedded icon
+ size_t icon_data_length;
+ char* icondata = libr_icon_malloc(icon, &icon_data_length);
+ m_customIconPixmap.loadFromData(static_cast<uchar*>(static_cast<void*>(icondata)), icon_data_length); // EVIL CAST
+ if (icon_size != 0) {
+ TQImage ip = m_customIconPixmap.convertToImage();
+ ip = ip.smoothScale(icon_size, icon_size);
+ m_customIconPixmap.convertFromImage(ip);
+ }
+ free(icondata);
+ libr_icon_close(icon);
+ }
+
+ libr_close(handle);
+ }
+ }
+ }
+#endif // HAVE_ELFICON
+ break;
+ }
+ case KURIFilterData::HELP:
+ {
+ m_strIconName = TQString::fromLatin1("khelpcenter");
+ break;
+ }
+ case KURIFilterData::SHELL:
+ {
+ m_strIconName = TQString::fromLatin1("konsole");
+ break;
+ }
+ case KURIFilterData::ERROR:
+ case KURIFilterData::BLOCKED:
+ {
+ m_strIconName = TQString::fromLatin1("error");
+ break;
+ }
+ default:
+ m_strIconName = TQString::null;
+ break;
+ }
+ m_bChanged = false;
+ }
+ return m_strIconName;
+}
+
+TQPixmap KURIFilterData::customIconPixmap()
+{
+ return m_customIconPixmap;
+}
+
+//******************************************** KURIFilterPlugin **********************************************
+void KURIFilterPlugin::setArguments( KURIFilterData& data, const TQString& args ) const
+{
+ data.d->args = args;
+}
+
+//******************************************** KURIFilter **********************************************
+KURIFilter *KURIFilter::s_self;
+static KStaticDeleter<KURIFilter> kurifiltersd;
+
+KURIFilter *KURIFilter::self()
+{
+ if (!s_self)
+ s_self = kurifiltersd.setObject(s_self, new KURIFilter);
+ return s_self;
+}
+
+KURIFilter::KURIFilter()
+{
+ m_lstPlugins.setAutoDelete(true);
+ loadPlugins();
+}
+
+KURIFilter::~KURIFilter()
+{
+}
+
+bool KURIFilter::filterURI( KURIFilterData& data, const TQStringList& filters )
+{
+ bool filtered = false;
+ KURIFilterPluginList use_plugins;
+
+ // If we have a filter list, only include the once
+ // explicitly specified by it. Otherwise, use all available filters...
+ if( filters.isEmpty() )
+ use_plugins = m_lstPlugins; // Use everything that is loaded...
+ else
+ {
+ //kdDebug() << "Named plugins requested..." << endl;
+ for( TQStringList::ConstIterator lst = filters.begin(); lst != filters.end(); ++lst )
+ {
+ TQPtrListIterator<KURIFilterPlugin> it( m_lstPlugins );
+ for( ; it.current() ; ++it )
+ {
+ if( (*lst) == it.current()->name() )
+ {
+ //kdDebug() << "Will use filter plugin named: " << it.current()->name() << endl;
+ use_plugins.append( it.current() );
+ break; // We already found it ; so lets test the next named filter...
+ }
+ }
+ }
+ }
+
+ TQPtrListIterator<KURIFilterPlugin> it( use_plugins );
+ //kdDebug() << "Using " << use_plugins.count() << " out of the "
+ // << m_lstPlugins.count() << " available plugins" << endl;
+ for (; it.current() && !filtered; ++it)
+ {
+ //kdDebug() << "Using a filter plugin named: " << it.current()->name() << endl;
+ filtered |= it.current()->filterURI( data );
+ }
+ return filtered;
+}
+
+bool KURIFilter::filterURI( KURL& uri, const TQStringList& filters )
+{
+ KURIFilterData data = uri;
+ bool filtered = filterURI( data, filters );
+ if( filtered ) uri = data.uri();
+ return filtered;
+}
+
+bool KURIFilter::filterURI( TQString& uri, const TQStringList& filters )
+{
+ KURIFilterData data = uri;
+ bool filtered = filterURI( data, filters );
+ if( filtered ) uri = data.uri().url();
+ return filtered;
+
+}
+
+KURL KURIFilter::filteredURI( const KURL &uri, const TQStringList& filters )
+{
+ KURIFilterData data = uri;
+ filterURI( data, filters );
+ return data.uri();
+}
+
+TQString KURIFilter::filteredURI( const TQString &uri, const TQStringList& filters )
+{
+ KURIFilterData data = uri;
+ filterURI( data, filters );
+ return data.uri().url();
+}
+
+TQPtrListIterator<KURIFilterPlugin> KURIFilter::pluginsIterator() const
+{
+ return TQPtrListIterator<KURIFilterPlugin>(m_lstPlugins);
+}
+
+TQStringList KURIFilter::pluginNames() const
+{
+ TQStringList list;
+ for(TQPtrListIterator<KURIFilterPlugin> i = pluginsIterator(); *i; ++i)
+ list.append((*i)->name());
+ return list;
+}
+
+void KURIFilter::loadPlugins()
+{
+ KTrader::OfferList offers = KTrader::self()->query( "KURIFilter/Plugin" );
+
+ KTrader::OfferList::ConstIterator it = offers.begin();
+ KTrader::OfferList::ConstIterator end = offers.end();
+
+ for (; it != end; ++it )
+ {
+ KURIFilterPlugin *plugin = KParts::ComponentFactory::createInstanceFromService<KURIFilterPlugin>( *it, 0, (*it)->desktopEntryName().latin1() );
+ if ( plugin )
+ m_lstPlugins.append( plugin );
+ }
+
+ // NOTE: Plugin priority is now determined by
+ // the entry in the .desktop files...
+ // TODO: Config dialog to differentiate "system"
+ // plugins from "user-defined" ones...
+ // m_lstPlugins.sort();
+}
+
+void KURIFilterPlugin::virtual_hook( int, void* )
+{ /*BASE::virtual_hook( id, data );*/ }
+
+#include "kurifilter.moc"