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., 51 Franklin Street, Fifth Floor, Boston, MA
20
#include "object_constructor.h"
21
#include "guiaction.h"
22
#include "object_hierarchy.h"
23
#include "../kig/kig_part.h"
26
#include <kmessagebox.h>
28
#include <qtextstream.h>
36
void vect_remove( std::vector<T>& v, const T& t )
38
typename std::vector<T>::iterator new_end = std::remove( v.begin(), v.end(), t );
39
v.erase( new_end, v.end() );
42
GUIActionList* GUIActionList::instance()
44
static GUIActionList l;
48
GUIActionList::~GUIActionList()
50
for ( avectype::iterator i = mactions.begin(); i != mactions.end(); ++i )
54
GUIActionList::GUIActionList()
58
void GUIActionList::regDoc( KigPart* d )
63
void GUIActionList::unregDoc( KigPart* d )
68
void GUIActionList::add( const std::vector<GUIAction*>& a )
70
copy( a.begin(), a.end(), inserter( mactions, mactions.begin() ) );
71
for ( dvectype::iterator i = mdocs.begin(); i != mdocs.end(); ++i )
73
KigPart::GUIUpdateToken t = (*i)->startGUIActionUpdate();
74
for ( uint j = 0; j < a.size(); ++j )
75
(*i)->actionAdded( a[j], t );
76
(*i)->endGUIActionUpdate( t );
80
void GUIActionList::add( GUIAction* a )
83
for ( dvectype::iterator i = mdocs.begin(); i != mdocs.end(); ++i )
85
KigPart::GUIUpdateToken t = (*i)->startGUIActionUpdate();
86
(*i)->actionAdded( a, t );
87
(*i)->endGUIActionUpdate( t );
91
void GUIActionList::remove( const std::vector<GUIAction*>& a )
93
for ( uint i = 0; i < a.size(); ++i )
95
mactions.erase( a[i] );
97
for ( dvectype::iterator i = mdocs.begin(); i != mdocs.end(); ++i )
99
KigPart::GUIUpdateToken t = (*i)->startGUIActionUpdate();
100
for ( uint j = 0; j < a.size(); ++j )
101
(*i)->actionRemoved( a[j], t );
102
(*i)->endGUIActionUpdate( t );
104
delete_all( a.begin(), a.end() );
107
void GUIActionList::remove( GUIAction* a )
110
for ( dvectype::iterator i = mdocs.begin(); i != mdocs.end(); ++i )
112
KigPart::GUIUpdateToken t = (*i)->startGUIActionUpdate();
113
(*i)->actionRemoved( a, t );
114
(*i)->endGUIActionUpdate( t );
119
ObjectConstructorList::ObjectConstructorList()
123
ObjectConstructorList::~ObjectConstructorList()
125
for ( vectype::iterator i = mctors.begin(); i != mctors.end(); ++i )
129
ObjectConstructorList* ObjectConstructorList::instance()
131
static ObjectConstructorList s;
135
ObjectConstructorList::vectype ObjectConstructorList::ctorsThatWantArgs(
136
const std::vector<ObjectCalcer*>& os, const KigDocument& d,
137
const KigWidget& w, bool co ) const
140
for ( vectype::const_iterator i = mctors.begin(); i != mctors.end(); ++i )
142
int r = (*i)->wantArgs( os, d, w );
143
if ( r == ArgsParser::Complete || ( !co && r == ArgsParser::Valid ) )
149
void ObjectConstructorList::remove( ObjectConstructor* a )
151
vect_remove( mctors, a );
155
void ObjectConstructorList::add( ObjectConstructor* a )
157
mctors.push_back( a );
160
Macro::Macro( GUIAction* a, MacroConstructor* c )
161
: action( a ), ctor( c )
165
bool operator==( const Macro& l, const Macro& r )
167
return ( l.action->descriptiveName() == r.action->descriptiveName() ) &&
168
( l.action->description() == r.action->description() ) &&
169
( l.action->iconFileName() == r.action->iconFileName() );
172
MacroList::MacroList()
176
MacroList::~MacroList()
178
std::vector<GUIAction*> actions;
179
std::vector<ObjectConstructor*> ctors;
180
for ( vectype::iterator i = mdata.begin(); i != mdata.end(); ++i )
183
GUIAction* a = m->action;
184
actions.push_back( a );
185
ObjectConstructor* c = m->ctor;
186
ctors.push_back( c );
190
GUIActionList::instance()->remove( actions );
191
for ( uint i = 0; i < ctors.size(); ++i )
192
ObjectConstructorList::instance()->remove( ctors[i] );
195
MacroList* MacroList::instance()
201
void MacroList::add( const std::vector<Macro*>& ms )
203
copy( ms.begin(), ms.end(), back_inserter( mdata ) );
204
std::vector<GUIAction*> acts;
205
for ( uint i = 0; i < ms.size(); ++i )
207
ObjectConstructorList::instance()->add( ms[i]->ctor );
208
acts.push_back( ms[i]->action );
210
GUIActionList::instance()->add( acts );
213
void MacroList::add( Macro* m )
215
mdata.push_back( m );
216
ObjectConstructorList::instance()->add( m->ctor );
217
GUIActionList::instance()->add( m->action );
220
void MacroList::remove( Macro* m )
222
GUIAction* a = m->action;
223
ObjectConstructor* c = m->ctor;
224
mdata.erase( std::remove( mdata.begin(), mdata.end(), m ),
227
GUIActionList::instance()->remove( a );
228
ObjectConstructorList::instance()->remove( c );
231
const MacroList::vectype& MacroList::macros() const
240
bool MacroList::save( Macro* m, const QString& f )
242
std::vector<Macro*> ms;
244
return save( ms, f );
247
bool MacroList::save( const std::vector<Macro*>& ms, const QString& f )
249
QDomDocument doc( "KigMacroFile" );
251
QDomElement docelem = doc.createElement( "KigMacroFile" );
252
docelem.setAttribute( "Version", KIGVERSION );
253
docelem.setAttribute( "Number", static_cast<uint>( ms.size() ) );
255
for ( uint i = 0; i < ms.size(); ++i )
257
MacroConstructor* ctor = ms[i]->ctor;
259
QDomElement macroelem = doc.createElement( "Macro" );
262
QDomElement nameelem = doc.createElement( "Name" );
263
nameelem.appendChild( doc.createTextNode( ctor->descriptiveName() ) );
264
macroelem.appendChild( nameelem );
267
QDomElement descelem = doc.createElement( "Description" );
268
descelem.appendChild( doc.createTextNode( ctor->description() ) );
269
macroelem.appendChild( descelem );
272
QByteArray icon = ctor->iconFileName( true );
273
if ( !icon.isNull() )
275
QDomElement descelem = doc.createElement( "IconFileName" );
276
descelem.appendChild( doc.createTextNode( icon ) );
277
macroelem.appendChild( descelem );
281
QDomElement hierelem = doc.createElement( "Construction" );
282
ctor->hierarchy().serialize( hierelem, doc );
283
macroelem.appendChild( hierelem );
285
docelem.appendChild( macroelem );
288
doc.appendChild( docelem );
291
if ( ! file.open( QIODevice::WriteOnly ) )
293
QTextStream stream( &file );
294
stream << doc.toByteArray();
298
bool MacroList::load( const QString& f, std::vector<Macro*>& ret, const KigPart& kdoc )
301
if ( ! file.open( QIODevice::ReadOnly ) )
303
KMessageBox::sorry( 0, i18n( "Could not open macro file '%1'", f ) );
306
QDomDocument doc( "KigMacroFile" );
307
if ( !doc.setContent( &file ) )
309
KMessageBox::sorry( 0, i18n( "Could not open macro file '%1'", f ) );
313
QDomElement main = doc.documentElement();
315
if ( main.tagName() == "KigMacroFile" )
316
return loadNew( main, ret, kdoc );
319
KMessageBox::detailedSorry(
320
0, i18n( "Kig cannot open the macro file \"%1\".", f ),
321
i18n( "This file was created by a very old Kig version (pre-0.4). "
322
"Support for this format has been removed from recent Kig versions. "
323
"You can try to import this macro using a previous Kig version "
324
"(0.4 to 0.6) and then export it again in the new format." ),
325
i18n( "Not Supported" ) );
330
bool MacroList::loadNew( const QDomElement& docelem, std::vector<Macro*>& ret, const KigPart& )
334
// int number = docelem.attribute( "Number" ).toInt( &sok );
335
if ( ! sok ) return false;
337
QString version = docelem.attribute( "Version" );
338
// QRegExp re( "(\\d+)\\.(\\d+)\\.(\\d+)" );
339
// re.match( version );
341
// int major = re.cap( 1 ).toInt( &sok );
342
// int minor = re.cap( 2 ).toInt( &sok );
343
// int mminor = re.cap( 3 ).toInt( &sok );
344
// if ( ! sok ) return false;
346
int unnamedindex = 1;
349
for ( QDomElement macroelem = docelem.firstChild().toElement();
350
! macroelem.isNull(); macroelem = macroelem.nextSibling().toElement() )
352
QString name, description;
353
ObjectHierarchy* hierarchy = 0;
354
QByteArray actionname;
355
QByteArray iconfile( "system-run" );
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().toLatin1();
368
else if ( dataelem.tagName() == "IconFileName" )
369
iconfile = dataelem.text().toLatin1();
373
// if the macro has no name, we give it a bogus name...
374
bool name_i18ned = false;
375
if ( name.isEmpty() )
377
name = i18n( "Unnamed Macro #%1", unnamedindex++ );
380
MacroConstructor* ctor =
381
new MacroConstructor( *hierarchy, name_i18ned ? name : i18n( name.toUtf8() ),
382
description.isEmpty() ? QString() : i18n( description.toUtf8() ),
385
GUIAction* act = new ConstructibleAction( ctor, actionname );
386
Macro* macro = new Macro( act, ctor );
387
ret.push_back( macro );
392
const ObjectConstructorList::vectype& ObjectConstructorList::constructors() const