kmail

bodypartformatterfactory.cpp
1 /*
2  bodypartformatterfactory.cpp
3 
4  This file is part of KMail, the KDE mail client.
5  Copyright (c) 2004 Marc Mutz <mutz@kde.org>,
6  Ingo Kloecker <kloecker@kde.org>
7 
8  KMail is free software; you can redistribute it and/or modify it
9  under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.
12 
13  KMail is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 
22  In addition, as a special exception, the copyright holders give
23  permission to link the code of this program with any edition of
24  the TQt library by Trolltech AS, Norway (or with modified versions
25  of TQt that use the same license as TQt), and distribute linked
26  combinations including the two. You must obey the GNU General
27  Public License in all respects for all of the code used other than
28  TQt. If you modify this file, you may extend this exception to
29  your version of the file, but you are not obligated to do so. If
30  you do not wish to do so, delete this exception statement from
31  your version.
32 */
33 
34 #include "bodypartformatterfactory.h"
35 #include "bodypartformatterfactory_p.h"
36 using namespace KMail::BodyPartFormatterFactoryPrivate;
37 
38 #include "interfaces/bodypartformatter.h"
39 #include "urlhandlermanager.h"
40 
41 // libtdepim
42 #include <libtdepim/pluginloader.h>
43 
44 // KDE
45 #include <kdebug.h>
46 
47 // TQt
48 #include <tqstring.h>
49 #include <tqcstring.h>
50 #include <tqstringlist.h>
51 
52 #include <assert.h>
53 
54 namespace {
55 
56  KPIM_DEFINE_PLUGIN_LOADER( BodyPartFormatterPluginLoader,
58  "create_bodypart_formatter_plugin",
59  "kmail/plugins/bodypartformatter/*.desktop" )
60 
61 }
62 
63 KMail::BodyPartFormatterFactory * KMail::BodyPartFormatterFactory::mSelf = 0;
64 
65 const KMail::BodyPartFormatterFactory * KMail::BodyPartFormatterFactory::instance() {
66  if ( !mSelf )
67  mSelf = new BodyPartFormatterFactory();
68  return mSelf;
69 }
70 
71 KMail::BodyPartFormatterFactory::BodyPartFormatterFactory() {
72  mSelf = this;
73 }
74 
75 KMail::BodyPartFormatterFactory::~BodyPartFormatterFactory() {
76  mSelf = 0;
77 }
78 
79 static TypeRegistry * all = 0;
80 
81 static void insertBodyPartFormatter( const char * type, const char * subtype,
82  const KMail::Interface::BodyPartFormatter * formatter ) {
83  if ( !type || !*type || !subtype || !*subtype || !formatter || !all )
84  return;
85 
86  TypeRegistry::iterator type_it = all->find( type );
87  if ( type_it == all->end() ) {
88  kdDebug( 5006 ) << "BodyPartFormatterFactory: instantiating new Subtype Registry for \""
89  << type << "\"" << endl;
90  type_it = all->insert( std::make_pair( type, SubtypeRegistry() ) ).first;
91  assert( type_it != all->end() );
92  }
93 
94  SubtypeRegistry & subtype_reg = type_it->second;
95  SubtypeRegistry::iterator subtype_it = subtype_reg.find( subtype );
96  if ( subtype_it != subtype_reg.end() ) {
97  kdDebug( 5006 ) << "BodyPartFormatterFactory: overwriting previously registered formatter for \""
98  << type << "/" << subtype << "\"" << endl;
99  subtype_reg.erase( subtype_it ); subtype_it = subtype_reg.end();
100  }
101 
102  subtype_reg.insert( std::make_pair( subtype, formatter ) );
103 }
104 
105 static void loadPlugins() {
106  const BodyPartFormatterPluginLoader * pl = BodyPartFormatterPluginLoader::instance();
107  if ( !pl ) {
108  kdWarning( 5006 ) << "BodyPartFormatterFactory: cannot instantiate plugin loader!" << endl;
109  return;
110  }
111  const TQStringList types = pl->types();
112  kdDebug( 5006 ) << "BodyPartFormatterFactory: found " << types.size() << " plugins." << endl;
113  for ( TQStringList::const_iterator it = types.begin() ; it != types.end() ; ++it ) {
114  const KMail::Interface::BodyPartFormatterPlugin * plugin = pl->createForName( *it );
115  if ( !plugin ) {
116  kdWarning( 5006 ) << "BodyPartFormatterFactory: plugin \"" << *it << "\" is not valid!" << endl;
117  continue;
118  }
119  for ( int i = 0 ; const KMail::Interface::BodyPartFormatter * bfp = plugin->bodyPartFormatter( i ) ; ++i ) {
120  const char * type = plugin->type( i );
121  if ( !type || !*type ) {
122  kdWarning( 5006 ) << "BodyPartFormatterFactory: plugin \"" << *it
123  << "\" returned empty type specification for index "
124  << i << endl;
125  break;
126  }
127  const char * subtype = plugin->subtype( i );
128  if ( !subtype || !*subtype ) {
129  kdWarning( 5006 ) << "BodyPartFormatterFactory: plugin \"" << *it
130  << "\" returned empty subtype specification for index "
131  << i << endl;
132  break;
133  }
134  insertBodyPartFormatter( type, subtype, bfp );
135  }
136  for ( int i = 0 ; const KMail::Interface::BodyPartURLHandler * handler = plugin->urlHandler( i ) ; ++i )
137  KMail::URLHandlerManager::instance()->registerHandler( handler );
138  }
139 }
140 
141 static void setup() {
142  if ( !all ) {
143  all = new TypeRegistry();
144  kmail_create_builtin_bodypart_formatters( all );
145  loadPlugins();
146  }
147 }
148 
149 
150 const KMail::Interface::BodyPartFormatter * KMail::BodyPartFormatterFactory::createFor( const char * type, const char * subtype ) const {
151  if ( !type || !*type )
152  type = "*";
153  if ( !subtype || !*subtype )
154  subtype = "*";
155 
156  setup();
157  assert( all );
158 
159  if ( all->empty() )
160  return 0;
161 
162  TypeRegistry::const_iterator type_it = all->find( type );
163  if ( type_it == all->end() )
164  type_it = all->find( "*" );
165  if ( type_it == all->end() )
166  return 0;
167 
168  const SubtypeRegistry & subtype_reg = type_it->second;
169  if ( subtype_reg.empty() )
170  return 0;
171 
172  SubtypeRegistry::const_iterator subtype_it = subtype_reg.find( subtype );
173  if ( subtype_it == subtype_reg.end() )
174  subtype_it = subtype_reg.find( "*" );
175  if ( subtype_it == subtype_reg.end() )
176  return 0;
177 
178  kdWarning( !(*subtype_it).second, 5006 )
179  << "BodyPartFormatterFactory: a null bodypart formatter sneaked in for \""
180  << type << "/" << subtype << "\"!" << endl;
181 
182  return (*subtype_it).second;
183 }
184 
185 const KMail::Interface::BodyPartFormatter * KMail::BodyPartFormatterFactory::createFor( const TQString & type, const TQString & subtype ) const {
186  return createFor( type.latin1(), subtype.latin1() );
187 }
188 
189 const KMail::Interface::BodyPartFormatter * KMail::BodyPartFormatterFactory::createFor( const TQCString & type, const TQCString & subtype ) const {
190  return createFor( type.data(), subtype.data() );
191 }
interface for BodyPartFormatter plugins
An interface to body part reader link handlers.