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"
36using 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
54namespace {
55
56 KPIM_DEFINE_PLUGIN_LOADER( BodyPartFormatterPluginLoader,
58 "create_bodypart_formatter_plugin",
59 "kmail/plugins/bodypartformatter/*.desktop" )
60
61}
62
63KMail::BodyPartFormatterFactory * KMail::BodyPartFormatterFactory::mSelf = 0;
64
65const KMail::BodyPartFormatterFactory * KMail::BodyPartFormatterFactory::instance() {
66 if ( !mSelf )
67 mSelf = new BodyPartFormatterFactory();
68 return mSelf;
69}
70
71KMail::BodyPartFormatterFactory::BodyPartFormatterFactory() {
72 mSelf = this;
73}
74
75KMail::BodyPartFormatterFactory::~BodyPartFormatterFactory() {
76 mSelf = 0;
77}
78
79static TypeRegistry * all = 0;
80
81static 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
105static 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
141static void setup() {
142 if ( !all ) {
143 all = new TypeRegistry();
144 kmail_create_builtin_bodypart_formatters( all );
145 loadPlugins();
146 }
147}
148
149
150const 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
185const KMail::Interface::BodyPartFormatter * KMail::BodyPartFormatterFactory::createFor( const TQString & type, const TQString & subtype ) const {
186 return createFor( type.latin1(), subtype.latin1() );
187}
188
189const 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.