diff options
Diffstat (limited to 'tdeio/tdeio/kurifilter.cpp')
-rw-r--r-- | tdeio/tdeio/kurifilter.cpp | 451 |
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" |