moved kdeaccessibility kdeaddons kdeadmin kdeartwork kdebindings kdeedu kdegames...
[kdeedu.git] / kig / misc / lists.cc
blob753b5794448409ad1c1feb05907e869640190fce
1 // Copyright (C) 2003 Dominique Devriese <devriese@kde.org>
3 // This program is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU General Public License
5 // as published by the Free Software Foundation; either version 2
6 // of the License, or (at your option) any later version.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
16 // 02111-1307, USA.
18 #include "lists.h"
20 #include "object_constructor.h"
21 #include "guiaction.h"
22 #include "object_hierarchy.h"
23 #include "../kig/kig_part.h"
25 #include "config.h"
27 #include <klocale.h>
28 #include <kmessagebox.h>
29 #include <qfile.h>
30 #include <qtextstream.h>
31 #include <qdom.h>
32 #include <qregexp.h>
33 #include <algorithm>
34 using namespace std;
36 template<typename T>
37 void vect_remove( std::vector<T>& v, const T& t )
39 typename std::vector<T>::iterator new_end = std::remove( v.begin(), v.end(), t );
40 v.erase( new_end, v.end() );
43 GUIActionList* GUIActionList::instance()
45 static GUIActionList l;
46 return &l;
49 GUIActionList::~GUIActionList()
51 for ( avectype::iterator i = mactions.begin(); i != mactions.end(); ++i )
52 delete *i;
55 GUIActionList::GUIActionList()
59 void GUIActionList::regDoc( KigPart* d )
61 mdocs.insert( d );
64 void GUIActionList::unregDoc( KigPart* d )
66 mdocs.erase( d );
69 void GUIActionList::add( const std::vector<GUIAction*>& a )
71 copy( a.begin(), a.end(), inserter( mactions, mactions.begin() ) );
72 for ( dvectype::iterator i = mdocs.begin(); i != mdocs.end(); ++i )
74 KigPart::GUIUpdateToken t = (*i)->startGUIActionUpdate();
75 for ( uint j = 0; j < a.size(); ++j )
76 (*i)->actionAdded( a[j], t );
77 (*i)->endGUIActionUpdate( t );
81 void GUIActionList::add( GUIAction* a )
83 mactions.insert( a );
84 for ( dvectype::iterator i = mdocs.begin(); i != mdocs.end(); ++i )
86 KigPart::GUIUpdateToken t = (*i)->startGUIActionUpdate();
87 (*i)->actionAdded( a, t );
88 (*i)->endGUIActionUpdate( t );
92 void GUIActionList::remove( const std::vector<GUIAction*>& a )
94 for ( uint i = 0; i < a.size(); ++i )
96 mactions.erase( a[i] );
98 for ( dvectype::iterator i = mdocs.begin(); i != mdocs.end(); ++i )
100 KigPart::GUIUpdateToken t = (*i)->startGUIActionUpdate();
101 for ( uint j = 0; j < a.size(); ++j )
102 (*i)->actionRemoved( a[j], t );
103 (*i)->endGUIActionUpdate( t );
105 delete_all( a.begin(), a.end() );
108 void GUIActionList::remove( GUIAction* a )
110 mactions.erase( a );
111 for ( dvectype::iterator i = mdocs.begin(); i != mdocs.end(); ++i )
113 KigPart::GUIUpdateToken t = (*i)->startGUIActionUpdate();
114 (*i)->actionRemoved( a, t );
115 (*i)->endGUIActionUpdate( t );
117 delete a;
120 ObjectConstructorList::ObjectConstructorList()
124 ObjectConstructorList::~ObjectConstructorList()
126 for ( vectype::iterator i = mctors.begin(); i != mctors.end(); ++i )
127 delete *i;
130 ObjectConstructorList* ObjectConstructorList::instance()
132 static ObjectConstructorList s;
133 return &s;
136 ObjectConstructorList::vectype ObjectConstructorList::ctorsThatWantArgs(
137 const std::vector<ObjectCalcer*>& os, const KigDocument& d,
138 const KigWidget& w, bool co ) const
140 vectype ret;
141 for ( vectype::const_iterator i = mctors.begin(); i != mctors.end(); ++i )
143 int r = (*i)->wantArgs( os, d, w );
144 if ( r == ArgsParser::Complete || ( !co && r == ArgsParser::Valid ) )
145 ret.push_back( *i );
147 return ret;
150 void ObjectConstructorList::remove( ObjectConstructor* a )
152 vect_remove( mctors, a );
153 delete a;
156 void ObjectConstructorList::add( ObjectConstructor* a )
158 mctors.push_back( a );
161 Macro::Macro( GUIAction* a, MacroConstructor* c )
162 : action( a ), ctor( c )
166 bool operator==( const Macro& l, const Macro& r )
168 return ( l.action->descriptiveName() == r.action->descriptiveName() ) &&
169 ( l.action->description() == r.action->description() ) &&
170 ( l.action->iconFileName() == r.action->iconFileName() );
173 MacroList::MacroList()
177 MacroList::~MacroList()
179 std::vector<GUIAction*> actions;
180 std::vector<ObjectConstructor*> ctors;
181 for ( vectype::iterator i = mdata.begin(); i != mdata.end(); ++i )
183 Macro* m = *i;
184 GUIAction* a = m->action;
185 actions.push_back( a );
186 ObjectConstructor* c = m->ctor;
187 ctors.push_back( c );
188 delete m;
190 mdata.clear();
191 GUIActionList::instance()->remove( actions );
192 for ( uint i = 0; i < ctors.size(); ++i )
193 ObjectConstructorList::instance()->remove( ctors[i] );
196 MacroList* MacroList::instance()
198 static MacroList t;
199 return &t;
202 void MacroList::add( const std::vector<Macro*>& ms )
204 copy( ms.begin(), ms.end(), back_inserter( mdata ) );
205 std::vector<GUIAction*> acts;
206 for ( uint i = 0; i < ms.size(); ++i )
208 ObjectConstructorList::instance()->add( ms[i]->ctor );
209 acts.push_back( ms[i]->action );
211 GUIActionList::instance()->add( acts );
214 void MacroList::add( Macro* m )
216 mdata.push_back( m );
217 ObjectConstructorList::instance()->add( m->ctor );
218 GUIActionList::instance()->add( m->action );
221 void MacroList::remove( Macro* m )
223 GUIAction* a = m->action;
224 ObjectConstructor* c = m->ctor;
225 mdata.erase( std::remove( mdata.begin(), mdata.end(), m ),
226 mdata.end() );
227 delete m;
228 GUIActionList::instance()->remove( a );
229 ObjectConstructorList::instance()->remove( c );
232 const MacroList::vectype& MacroList::macros() const
234 return mdata;
237 Macro::~Macro()
241 bool MacroList::save( Macro* m, const QString& f )
243 std::vector<Macro*> ms;
244 ms.push_back( m );
245 return save( ms, f );
248 bool MacroList::save( const std::vector<Macro*>& ms, const QString& f )
250 QDomDocument doc( "KigMacroFile" );
252 QDomElement docelem = doc.createElement( "KigMacroFile" );
253 docelem.setAttribute( "Version", KIGVERSION );
254 docelem.setAttribute( "Number", ms.size() );
256 for ( uint i = 0; i < ms.size(); ++i )
258 MacroConstructor* ctor = ms[i]->ctor;
260 QDomElement macroelem = doc.createElement( "Macro" );
262 // name
263 QDomElement nameelem = doc.createElement( "Name" );
264 nameelem.appendChild( doc.createTextNode( ctor->descriptiveName() ) );
265 macroelem.appendChild( nameelem );
267 // desc
268 QDomElement descelem = doc.createElement( "Description" );
269 descelem.appendChild( doc.createTextNode( ctor->description() ) );
270 macroelem.appendChild( descelem );
272 // icon
273 QCString icon = ctor->iconFileName( true );
274 if ( !icon.isNull() )
276 QDomElement descelem = doc.createElement( "IconFileName" );
277 descelem.appendChild( doc.createTextNode( icon ) );
278 macroelem.appendChild( descelem );
281 // data
282 QDomElement hierelem = doc.createElement( "Construction" );
283 ctor->hierarchy().serialize( hierelem, doc );
284 macroelem.appendChild( hierelem );
286 docelem.appendChild( macroelem );
289 doc.appendChild( docelem );
291 QFile file( f );
292 if ( ! file.open( IO_WriteOnly ) )
293 return false;
294 QTextStream stream( &file );
295 stream << doc.toCString();
296 return true;
299 bool MacroList::load( const QString& f, std::vector<Macro*>& ret, const KigPart& kdoc )
301 QFile file( f );
302 if ( ! file.open( IO_ReadOnly ) )
304 KMessageBox::sorry( 0, i18n( "Could not open macro file '%1'" ).arg( f ) );
305 return false;
307 QDomDocument doc( "KigMacroFile" );
308 if ( !doc.setContent( &file ) )
310 KMessageBox::sorry( 0, i18n( "Could not open macro file '%1'" ).arg( f ) );
311 return false;
313 file.close();
314 QDomElement main = doc.documentElement();
316 if ( main.tagName() == "KigMacroFile" )
317 return loadNew( main, ret, kdoc );
318 else
320 KMessageBox::detailedSorry(
321 0, i18n( "Kig cannot open the macro file \"%1\"." ).arg( f ),
322 i18n( "This file was created by a very old Kig version (pre-0.4). "
323 "Support for this format has been removed from recent Kig versions. "
324 "You can try to import this macro using a previous Kig version "
325 "(0.4 to 0.6) and then export it again in the new format." ),
326 i18n( "Not Supported" ) );
327 return false;
331 bool MacroList::loadNew( const QDomElement& docelem, std::vector<Macro*>& ret, const KigPart& )
333 bool sok = true;
334 // unused..
335 // int number = docelem.attribute( "Number" ).toInt( &sok );
336 if ( ! sok ) return false;
338 QString version = docelem.attribute( "Version" );
339 // QRegExp re( "(\\d+)\\.(\\d+)\\.(\\d+)" );
340 // re.match( version );
341 // unused..
342 // int major = re.cap( 1 ).toInt( &sok );
343 // int minor = re.cap( 2 ).toInt( &sok );
344 // int mminor = re.cap( 3 ).toInt( &sok );
345 // if ( ! sok ) return false;
347 int unnamedindex = 1;
348 QString tmp;
350 for ( QDomElement macroelem = docelem.firstChild().toElement();
351 ! macroelem.isNull(); macroelem = macroelem.nextSibling().toElement() )
353 QString name, description;
354 ObjectHierarchy* hierarchy = 0;
355 QCString actionname, iconfile;
356 if ( macroelem.tagName() != "Macro" ) continue; // forward compat ?
357 for ( QDomElement dataelem = macroelem.firstChild().toElement();
358 ! dataelem.isNull(); dataelem = dataelem.nextSibling().toElement() )
360 if ( dataelem.tagName() == "Name" )
361 name = dataelem.text();
362 else if ( dataelem.tagName() == "Description" )
363 description = dataelem.text();
364 else if ( dataelem.tagName() == "Construction" )
365 hierarchy = ObjectHierarchy::buildSafeObjectHierarchy( dataelem, tmp );
366 else if ( dataelem.tagName() == "ActionName" )
367 actionname = dataelem.text().latin1();
368 else if ( dataelem.tagName() == "IconFileName" )
369 iconfile = dataelem.text().latin1();
370 else continue;
372 assert( hierarchy );
373 // if the macro has no name, we give it a bogus name...
374 if ( name.isEmpty() )
375 name = i18n( "Unnamed Macro #%1" ).arg( unnamedindex++ );
376 MacroConstructor* ctor =
377 new MacroConstructor( *hierarchy, i18n( name.latin1() ), i18n( description.latin1() ), iconfile );
378 delete hierarchy;
379 GUIAction* act = new ConstructibleAction( ctor, actionname );
380 Macro* macro = new Macro( act, ctor );
381 ret.push_back( macro );
383 return true;
386 const ObjectConstructorList::vectype& ObjectConstructorList::constructors() const
388 return mctors;