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
20 #include "object_constructor.h"
21 #include "guiaction.h"
22 #include "object_hierarchy.h"
23 #include "../kig/kig_part.h"
28 #include <kmessagebox.h>
30 #include <qtextstream.h>
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
;
49 GUIActionList::~GUIActionList()
51 for ( avectype::iterator i
= mactions
.begin(); i
!= mactions
.end(); ++i
)
55 GUIActionList::GUIActionList()
59 void GUIActionList::regDoc( KigPart
* d
)
64 void GUIActionList::unregDoc( KigPart
* 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
)
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
)
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
);
120 ObjectConstructorList::ObjectConstructorList()
124 ObjectConstructorList::~ObjectConstructorList()
126 for ( vectype::iterator i
= mctors
.begin(); i
!= mctors
.end(); ++i
)
130 ObjectConstructorList
* ObjectConstructorList::instance()
132 static ObjectConstructorList s
;
136 ObjectConstructorList::vectype
ObjectConstructorList::ctorsThatWantArgs(
137 const std::vector
<ObjectCalcer
*>& os
, const KigDocument
& d
,
138 const KigWidget
& w
, bool co
) const
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
) )
150 void ObjectConstructorList::remove( ObjectConstructor
* a
)
152 vect_remove( mctors
, 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
)
184 GUIAction
* a
= m
->action
;
185 actions
.push_back( a
);
186 ObjectConstructor
* c
= m
->ctor
;
187 ctors
.push_back( c
);
191 GUIActionList::instance()->remove( actions
);
192 for ( uint i
= 0; i
< ctors
.size(); ++i
)
193 ObjectConstructorList::instance()->remove( ctors
[i
] );
196 MacroList
* MacroList::instance()
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
),
228 GUIActionList::instance()->remove( a
);
229 ObjectConstructorList::instance()->remove( c
);
232 const MacroList::vectype
& MacroList::macros() const
241 bool MacroList::save( Macro
* m
, const QString
& f
)
243 std::vector
<Macro
*> ms
;
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" );
263 QDomElement nameelem
= doc
.createElement( "Name" );
264 nameelem
.appendChild( doc
.createTextNode( ctor
->descriptiveName() ) );
265 macroelem
.appendChild( nameelem
);
268 QDomElement descelem
= doc
.createElement( "Description" );
269 descelem
.appendChild( doc
.createTextNode( ctor
->description() ) );
270 macroelem
.appendChild( descelem
);
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
);
282 QDomElement hierelem
= doc
.createElement( "Construction" );
283 ctor
->hierarchy().serialize( hierelem
, doc
);
284 macroelem
.appendChild( hierelem
);
286 docelem
.appendChild( macroelem
);
289 doc
.appendChild( docelem
);
292 if ( ! file
.open( IO_WriteOnly
) )
294 QTextStream
stream( &file
);
295 stream
<< doc
.toCString();
299 bool MacroList::load( const QString
& f
, std::vector
<Macro
*>& ret
, const KigPart
& kdoc
)
302 if ( ! file
.open( IO_ReadOnly
) )
304 KMessageBox::sorry( 0, i18n( "Could not open macro file '%1'" ).arg( f
) );
307 QDomDocument
doc( "KigMacroFile" );
308 if ( !doc
.setContent( &file
) )
310 KMessageBox::sorry( 0, i18n( "Could not open macro file '%1'" ).arg( f
) );
314 QDomElement main
= doc
.documentElement();
316 if ( main
.tagName() == "KigMacroFile" )
317 return loadNew( main
, ret
, kdoc
);
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" ) );
331 bool MacroList::loadNew( const QDomElement
& docelem
, std::vector
<Macro
*>& ret
, const KigPart
& )
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 );
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;
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();
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
);
379 GUIAction
* act
= new ConstructibleAction( ctor
, actionname
);
380 Macro
* macro
= new Macro( act
, ctor
);
381 ret
.push_back( macro
);
386 const ObjectConstructorList::vectype
& ObjectConstructorList::constructors() const