kmail

bodypartformatterfactory.cpp

Go to the documentation of this file.
00001 /*  -*- mode: C++; c-file-style: "gnu" -*-
00002     bodypartformatterfactory.cpp
00003 
00004     This file is part of KMail, the KDE mail client.
00005     Copyright (c) 2004 Marc Mutz <mutz@kde.org>,
00006                        Ingo Kloecker <kloecker@kde.org>
00007 
00008     KMail is free software; you can redistribute it and/or modify it
00009     under the terms of the GNU General Public License as published by
00010     the Free Software Foundation; either version 2 of the License, or
00011     (at your option) any later version.
00012 
00013     KMail is distributed in the hope that it will be useful, but
00014     WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016     General Public License for more details.
00017 
00018     You should have received a copy of the GNU General Public License
00019     along with this program; if not, write to the Free Software
00020     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00021 
00022     In addition, as a special exception, the copyright holders give
00023     permission to link the code of this program with any edition of
00024     the Qt library by Trolltech AS, Norway (or with modified versions
00025     of Qt that use the same license as Qt), and distribute linked
00026     combinations including the two.  You must obey the GNU General
00027     Public License in all respects for all of the code used other than
00028     Qt.  If you modify this file, you may extend this exception to
00029     your version of the file, but you are not obligated to do so.  If
00030     you do not wish to do so, delete this exception statement from
00031     your version.
00032 */
00033 
00034 #include "bodypartformatterfactory.h"
00035 #include "bodypartformatterfactory_p.h"
00036 using namespace KMail::BodyPartFormatterFactoryPrivate;
00037 
00038 #include "interfaces/bodypartformatter.h"
00039 #include "urlhandlermanager.h"
00040 
00041 // libkdepim
00042 #include <libkdepim/pluginloader.h>
00043 
00044 // KDE
00045 #include <kdebug.h>
00046 
00047 // Qt
00048 #include <qstring.h>
00049 #include <qcstring.h>
00050 #include <qstringlist.h>
00051 
00052 #include <assert.h>
00053 
00054 namespace {
00055 
00056   KPIM_DEFINE_PLUGIN_LOADER( BodyPartFormatterPluginLoader,
00057                  KMail::Interface::BodyPartFormatterPlugin,
00058                  "create_bodypart_formatter_plugin",
00059                  "kmail/plugins/bodypartformatter/*.desktop" )
00060 
00061 }
00062 
00063 KMail::BodyPartFormatterFactory * KMail::BodyPartFormatterFactory::mSelf = 0;
00064 
00065 const KMail::BodyPartFormatterFactory * KMail::BodyPartFormatterFactory::instance() {
00066   if ( !mSelf )
00067     mSelf = new BodyPartFormatterFactory();
00068   return mSelf;
00069 }
00070 
00071 KMail::BodyPartFormatterFactory::BodyPartFormatterFactory() {
00072   mSelf = this;
00073 }
00074 
00075 KMail::BodyPartFormatterFactory::~BodyPartFormatterFactory() {
00076   mSelf = 0;
00077 }
00078 
00079 static TypeRegistry * all = 0;
00080 
00081 static void insertBodyPartFormatter( const char * type, const char * subtype,
00082                      const KMail::Interface::BodyPartFormatter * formatter ) {
00083   if ( !type || !*type || !subtype || !*subtype || !formatter || !all )
00084     return;
00085 
00086   TypeRegistry::iterator type_it = all->find( type );
00087   if ( type_it == all->end() ) {
00088     kdDebug( 5006 ) << "BodyPartFormatterFactory: instantiating new Subtype Registry for \""
00089             << type << "\"" << endl;
00090     type_it = all->insert( std::make_pair( type, SubtypeRegistry() ) ).first;
00091     assert( type_it != all->end() );
00092   }
00093 
00094   SubtypeRegistry & subtype_reg = type_it->second;
00095   SubtypeRegistry::iterator subtype_it = subtype_reg.find( subtype );
00096   if ( subtype_it != subtype_reg.end() ) {
00097     kdDebug( 5006 ) << "BodyPartFormatterFactory: overwriting previously registered formatter for \""
00098             << type << "/" << subtype << "\"" << endl;
00099     subtype_reg.erase( subtype_it ); subtype_it = subtype_reg.end();
00100   }
00101 
00102   subtype_reg.insert( std::make_pair( subtype, formatter ) );
00103 }
00104 
00105 static void loadPlugins() {
00106   const BodyPartFormatterPluginLoader * pl = BodyPartFormatterPluginLoader::instance();
00107   if ( !pl ) {
00108     kdWarning( 5006 ) << "BodyPartFormatterFactory: cannot instantiate plugin loader!" << endl;
00109     return;
00110   }
00111   const QStringList types = pl->types();
00112   kdDebug( 5006 ) << "BodyPartFormatterFactory: found " << types.size() << " plugins." << endl;
00113   for ( QStringList::const_iterator it = types.begin() ; it != types.end() ; ++it ) {
00114     const KMail::Interface::BodyPartFormatterPlugin * plugin = pl->createForName( *it );
00115     if ( !plugin ) {
00116       kdWarning( 5006 ) << "BodyPartFormatterFactory: plugin \"" << *it << "\" is not valid!" << endl;
00117       continue;
00118     }
00119     for ( int i = 0 ; const KMail::Interface::BodyPartFormatter * bfp = plugin->bodyPartFormatter( i ) ; ++i ) {
00120       const char * type = plugin->type( i );
00121       if ( !type || !*type ) {
00122     kdWarning( 5006 ) << "BodyPartFormatterFactory: plugin \"" << *it
00123               << "\" returned empty type specification for index "
00124               << i << endl;
00125     break;
00126       }
00127       const char * subtype = plugin->subtype( i );
00128       if ( !subtype || !*subtype ) {
00129     kdWarning( 5006 ) << "BodyPartFormatterFactory: plugin \"" << *it
00130               << "\" returned empty subtype specification for index "
00131               << i << endl;
00132     break;
00133       }
00134       insertBodyPartFormatter( type, subtype, bfp );
00135     }
00136     for ( int i = 0 ; const KMail::Interface::BodyPartURLHandler * handler = plugin->urlHandler( i ) ; ++i )
00137       KMail::URLHandlerManager::instance()->registerHandler( handler );
00138   }
00139 }
00140 
00141 static void setup() {
00142   if ( !all ) {
00143     all = new TypeRegistry();
00144     kmail_create_builtin_bodypart_formatters( all );
00145     loadPlugins();
00146   }
00147 }
00148 
00149 
00150 const KMail::Interface::BodyPartFormatter * KMail::BodyPartFormatterFactory::createFor( const char * type, const char * subtype ) const {
00151   if ( !type || !*type )
00152     type = "*";
00153   if ( !subtype || !*subtype )
00154     subtype = "*";
00155 
00156   setup();
00157   assert( all );
00158 
00159   if ( all->empty() )
00160     return 0;
00161 
00162   TypeRegistry::const_iterator type_it = all->find( type );
00163   if ( type_it == all->end() )
00164     type_it = all->find( "*" );
00165   if ( type_it == all->end() )
00166     return 0;
00167 
00168   const SubtypeRegistry & subtype_reg = type_it->second;
00169   if ( subtype_reg.empty() )
00170     return 0;
00171 
00172   SubtypeRegistry::const_iterator subtype_it = subtype_reg.find( subtype );
00173   if ( subtype_it == subtype_reg.end() )
00174     subtype_it = subtype_reg.find( "*" );
00175   if ( subtype_it == subtype_reg.end() )
00176     return 0;
00177 
00178   kdWarning( !(*subtype_it).second, 5006 )
00179     << "BodyPartFormatterFactory: a null bodypart formatter sneaked in for \""
00180     << type << "/" << subtype << "\"!" << endl;
00181 
00182   return (*subtype_it).second;
00183 }
00184 
00185 const KMail::Interface::BodyPartFormatter * KMail::BodyPartFormatterFactory::createFor( const QString & type, const QString & subtype ) const {
00186   return createFor( type.latin1(), subtype.latin1() );
00187 }
00188 
00189 const KMail::Interface::BodyPartFormatter * KMail::BodyPartFormatterFactory::createFor( const QCString & type, const QCString & subtype ) const {
00190   return createFor( type.data(), subtype.data() );
00191 }