karbon

karbon_part.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2001, 2002, 2003 The Karbon Developers
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18*/
19
20
21#include <tqdom.h>
22#include <tqfileinfo.h>
23#include <tqpainter.h>
24#include <tqpaintdevicemetrics.h>
25
26#include <tdeconfig.h>
27#include <kdebug.h>
28#include <tdelocale.h>
29#include <tdetempfile.h>
30#include <KoTemplateChooseDia.h>
31#include <KoStoreDevice.h>
32#include <KoOasisStyles.h>
33#include <KoOasisLoadingContext.h>
34#include <KoXmlWriter.h>
35#include <KoXmlNS.h>
36#include <KoDom.h>
37#include <KoOasisSettings.h>
38#include <KoMainWindow.h>
39
40#include "karbon_factory.h"
41#include "karbon_part.h"
42#include "karbon_part_iface.h"
43#include "karbon_view.h"
44#include "vcommand.h"
45#include "vglobal.h"
46#include "vpainter.h"
47#include "vpainterfactory.h"
48#include "vselection.h"
49#include "vcanvas.h"
50#include "vlayer.h"
51#include "vdocumentdocker.h"
52#include "vtoolcontroller.h"
53#include "KoApplication.h"
54#include "vtool.h"
55#include "commands/vtransformcmd.h"
56
57// Make sure an appropriate DTD is available in www/koffice/DTD if changing this value
58// static const char * CURRENT_DTD_VERSION = "1.2";
59
60KarbonPart::KarbonPart( TQWidget* parentWidget, const char* widgetName,
61 TQObject* parent, const char* name, bool singleViewMode )
62 : KoDocument( parentWidget, widgetName, parent, name, singleViewMode )
63{
64 setInstance( KarbonFactory::instance(), false );
65 setTemplateType( "karbon_template" );
66 m_bShowStatusBar = true;
67 dcop = 0L;
68
69 m_commandHistory = new VCommandHistory( this );
70 connect( m_commandHistory, TQ_SIGNAL( documentRestored() ), this, TQ_SLOT( slotDocumentRestored() ) );
71 connect( m_commandHistory, TQ_SIGNAL( commandExecuted( VCommand * ) ), this, TQ_SLOT( slotCommandExecuted( VCommand * ) ) );
72
73 initConfig();
74
75 m_merge = false;
76
77 m_maxRecentFiles = 10;
78
79 //if( name )
80 dcopObject();
81
82 // set as default paper
83 m_pageLayout.format = KoPageFormat::defaultFormat();
84 m_pageLayout.orientation = PG_PORTRAIT;
85 m_pageLayout.ptWidth = MM_TO_POINT( KoPageFormat::width( m_pageLayout.format, m_pageLayout.orientation ) );
86 m_pageLayout.ptHeight = MM_TO_POINT( KoPageFormat::height( m_pageLayout.format, m_pageLayout.orientation ) );
87 m_doc.setWidth( m_pageLayout.ptWidth );
88 m_doc.setHeight( m_pageLayout.ptHeight );
89 // enable selection drawing
90 m_doc.selection()->showHandle();
91 m_doc.selection()->setSelectObjects();
92 m_doc.selection()->setState( VObject::selected );
93 m_doc.selection()->selectNodes();
94}
95
96KarbonPart::~KarbonPart()
97{
98 // delete the command-history:
99 delete m_commandHistory;
100 delete dcop;
101}
102
103DCOPObject* KarbonPart::dcopObject()
104{
105 if( !dcop )
106 dcop = new KarbonPartIface( this );
107
108 return dcop;
109}
110
111void
112KarbonPart::setPageLayout( KoPageLayout& layout, KoUnit::Unit _unit )
113{
114 m_pageLayout = layout;
115 m_doc.setUnit( _unit );
116 m_doc.setWidth( m_pageLayout.ptWidth );
117 m_doc.setHeight( m_pageLayout.ptHeight );
118}
119
120bool
121KarbonPart::initDoc(InitDocFlags flags, TQWidget* parentWidget)
122{
123 if (flags==KoDocument::InitDocEmpty)
124 {
125 return true;
126 }
127 TQString file;
128 KoTemplateChooseDia::ReturnType result;
129
130 KoTemplateChooseDia::DialogType dlgtype;
131 if (flags != KoDocument::InitDocFileNew)
132 dlgtype = KoTemplateChooseDia::Everything;
133 else
134 dlgtype = KoTemplateChooseDia::OnlyTemplates;
135
136 result = KoTemplateChooseDia::choose( KarbonFactory::instance(), file, dlgtype, "karbon_template", parentWidget );
137
138 if( result == KoTemplateChooseDia::Template )
139 {
140 resetURL();
141 bool ok = loadNativeFormat( file );
142 if ( !ok )
143 showLoadingErrorDialog();
144 setEmpty();
145 return ok;
146 }
147 else if( result == KoTemplateChooseDia::Empty )
148 {
149 return true;
150 }
151 else if( result == KoTemplateChooseDia::File )
152 {
153 KURL url( file );
154 return openURL( url );
155 }
156
157 return false;
158}
159
160KoView*
161KarbonPart::createViewInstance( TQWidget* parent, const char* name )
162{
163 KarbonView *result = new KarbonView( this, parent, name );
164 return result;
165}
166
167void
168KarbonPart::removeView( KoView *view )
169{
170 kdDebug(38000) << "KarbonPart::removeView" << endl;
171 KoDocument::removeView( view );
172}
173
174double getAttribute(TQDomElement &element, const char *attributeName, double defaultValue)
175{
176 TQString value;
177 if ( ( value = element.attribute( attributeName ) ) != TQString() )
178 return value.toDouble();
179 else
180 return defaultValue;
181}
182
183int getAttribute(TQDomElement &element, const char *attributeName, int defaultValue)
184{
185 TQString value;
186 if ( ( value = element.attribute( attributeName ) ) != TQString() )
187 return value.toInt();
188 else
189 return defaultValue;
190}
191
192bool
193KarbonPart::loadXML( TQIODevice*, const TQDomDocument& document )
194{
195 bool success = false;
196
197 TQDomElement doc = document.documentElement();
198
199 if( m_merge )
200 {
201 m_doc.loadDocumentContent( doc );
202 return true;
203 }
204
205 success = m_doc.loadXML( doc );
206
207 //m_pageLayout = KoPageLayout::standardLayout();
208
209 // <PAPER>
210 TQDomElement paper = doc.namedItem( "PAPER" ).toElement();
211 if ( !paper.isNull() )
212 {
213 m_pageLayout.format = static_cast<KoFormat>( getAttribute( paper, "format", 0 ) );
214 m_pageLayout.orientation = static_cast<KoOrientation>( getAttribute( paper, "orientation", 0 ) );
215
216 if( m_pageLayout.format == PG_CUSTOM )
217 {
218 m_pageLayout.ptWidth = m_doc.width();
219 m_pageLayout.ptHeight = m_doc.height();
220 }
221 else
222 {
223 m_pageLayout.ptWidth = getAttribute( paper, "width", 0.0 );
224 m_pageLayout.ptHeight = getAttribute( paper, "height", 0.0 );
225 }
226 }
227 else
228 {
229 m_pageLayout.ptWidth = getAttribute( doc, "width", 595.277);
230 m_pageLayout.ptHeight = getAttribute( doc, "height", 841.891 );
231 }
232
233 kdDebug() << " ptWidth=" << m_pageLayout.ptWidth << endl;
234 kdDebug() << " ptHeight=" << m_pageLayout.ptHeight << endl;
235 TQDomElement borders = paper.namedItem( "PAPERBORDERS" ).toElement();
236 if( !borders.isNull() )
237 {
238 if( borders.hasAttribute( "ptLeft" ) )
239 m_pageLayout.ptLeft = borders.attribute( "ptLeft" ).toDouble();
240 if( borders.hasAttribute( "ptTop" ) )
241 m_pageLayout.ptTop = borders.attribute( "ptTop" ).toDouble();
242 if( borders.hasAttribute( "ptRight" ) )
243 m_pageLayout.ptRight = borders.attribute( "ptRight" ).toDouble();
244 if( borders.hasAttribute( "ptBottom" ) )
245 m_pageLayout.ptBottom = borders.attribute( "ptBottom" ).toDouble();
246 }
247
248 setUnit( m_doc.unit() );
249
250 return success;
251}
252
253TQDomDocument
255{
256 TQDomDocument doc = m_doc.saveXML();
257 TQDomElement me = doc.documentElement();
258 TQDomElement paper = doc.createElement( "PAPER" );
259 me.appendChild( paper );
260 paper.setAttribute( "format", static_cast<int>( m_pageLayout.format ) );
261 paper.setAttribute( "pages", pageCount() );
262 paper.setAttribute( "width", m_pageLayout.ptWidth );
263 paper.setAttribute( "height", m_pageLayout.ptHeight );
264 paper.setAttribute( "orientation", static_cast<int>( m_pageLayout.orientation ) );
265
266 TQDomElement paperBorders = doc.createElement( "PAPERBORDERS" );
267 paperBorders.setAttribute( "ptLeft", m_pageLayout.ptLeft );
268 paperBorders.setAttribute( "ptTop", m_pageLayout.ptTop );
269 paperBorders.setAttribute( "ptRight", m_pageLayout.ptRight );
270 paperBorders.setAttribute( "ptBottom", m_pageLayout.ptBottom );
271 paper.appendChild(paperBorders);
272
273 return doc;
274}
275
276bool
277KarbonPart::loadOasis( const TQDomDocument &doc, KoOasisStyles &styles, const TQDomDocument &settings, KoStore *store )
278{
279 kdDebug(38000) << "Start loading OASIS document..." << doc.toString() << endl;
280
281 TQDomElement contents = doc.documentElement();
282 kdDebug(38000) << "Start loading OASIS document..." << contents.text() << endl;
283 kdDebug(38000) << "Start loading OASIS contents..." << contents.lastChild().localName() << endl;
284 kdDebug(38000) << "Start loading OASIS contents..." << contents.lastChild().namespaceURI() << endl;
285 kdDebug(38000) << "Start loading OASIS contents..." << contents.lastChild().isElement() << endl;
286 TQDomElement body( KoDom::namedItemNS( contents, KoXmlNS::office, "body" ) );
287 kdDebug(38000) << "Start loading OASIS document..." << body.text() << endl;
288 if( body.isNull() )
289 {
290 kdDebug(38000) << "No office:body found!" << endl;
291 setErrorMessage( i18n( "Invalid OASIS document. No office:body tag found." ) );
292 return false;
293 }
294
295 body = KoDom::namedItemNS( body, KoXmlNS::office, "drawing");
296 if(body.isNull())
297 {
298 kdDebug(38000) << "No office:drawing found!" << endl;
299 setErrorMessage( i18n( "Invalid OASIS document. No office:drawing tag found." ) );
300 return false;
301 }
302
303 TQDomElement page( KoDom::namedItemNS( body, KoXmlNS::draw, "page" ) );
304 if(page.isNull())
305 {
306 kdDebug(38000) << "No office:drawing found!" << endl;
307 setErrorMessage( i18n( "Invalid OASIS document. No draw:page tag found." ) );
308 return false;
309 }
310
311 TQString masterPageName = "Standard"; // use default layout as fallback
312 TQDomElement *master = styles.masterPages()[ masterPageName ];
313 if ( !master ) //last test...
314 master = styles.masterPages()[ "Default" ];
315 // last resort, use the first found master page style
316 if ( ! master )
317 {
318 TQDictIterator<TQDomElement> it( styles.masterPages() );
319 master = it.current();
320 }
321 Q_ASSERT( master );
322 const TQDomElement *style = master ? styles.findStyle( master->attributeNS( KoXmlNS::style, "page-layout-name", TQString() ) ) : 0;
323 if( style )
324 {
325 m_pageLayout.loadOasis( *style );
326 m_doc.setWidth( m_pageLayout.ptWidth );
327 m_doc.setHeight( m_pageLayout.ptHeight );
328 }
329 else
330 return false;
331
332 KoOasisLoadingContext context( this, styles, store );
333 m_doc.loadOasis( page, context );
334 // do y-mirroring here
335 TQWMatrix mat;
336 mat.scale( 1, -1 );
337 mat.translate( 0, -m_doc.height() );
338 VTransformCmd trafo( 0L, mat );
339 trafo.visit( m_doc );
340
341 loadOasisSettings( settings );
342
343 return true;
344}
345
346void
347KarbonPart::loadOasisSettings( const TQDomDocument&settingsDoc )
348{
349 if ( settingsDoc.isNull() )
350 return ; // not an error if some file doesn't have settings.xml
351 KoOasisSettings settings( settingsDoc );
352 KoOasisSettings::Items viewSettings = settings.itemSet( "view-settings" );
353 if ( !viewSettings.isNull() )
354 {
355 setUnit(KoUnit::unit(viewSettings.parseConfigItemString("unit")));
356 // FIXME: add other config here.
357 }
358}
359
360
361bool
362KarbonPart::saveOasis( KoStore *store, KoXmlWriter *manifestWriter )
363{
364 if( !store->open( "content.xml" ) )
365 return false;
366
367 KoStoreDevice storeDev( store );
368 KoXmlWriter* docWriter = createOasisXmlWriter( &storeDev, "office:document-content" );
369 KoGenStyles mainStyles;
370
371 KoGenStyle pageLayout = m_pageLayout.saveOasis();
372 TQString layoutName = mainStyles.lookup( pageLayout, "PL" );
373 KoGenStyle masterPage( KoGenStyle::STYLE_MASTER );
374 masterPage.addAttribute( "style:page-layout-name", layoutName );
375 mainStyles.lookup( masterPage, "Default", KoGenStyles::DontForceNumbering );
376
377 KTempFile contentTmpFile;
378 contentTmpFile.setAutoDelete( true );
379 TQFile* tmpFile = contentTmpFile.file();
380 KoXmlWriter contentTmpWriter( tmpFile, 1 );
381
382 contentTmpWriter.startElement( "office:body" );
383 contentTmpWriter.startElement( "office:drawing" );
384
385 m_doc.saveOasis( store, &contentTmpWriter, mainStyles ); // Save contents
386
387 contentTmpWriter.endElement(); // office:drawing
388 contentTmpWriter.endElement(); // office:body
389
390 docWriter->startElement( "office:automatic-styles" );
391
392 TQValueList<KoGenStyles::NamedStyle> styles = mainStyles.styles( VDocument::STYLE_GRAPHICAUTO );
393 TQValueList<KoGenStyles::NamedStyle>::const_iterator it = styles.begin();
394 for( ; it != styles.end() ; ++it )
395 (*it).style->writeStyle( docWriter, mainStyles, "style:style", (*it).name , "style:graphic-properties" );
396
397 docWriter->endElement(); // office:automatic-styles
398
399 // And now we can copy over the contents from the tempfile to the real one
400 tmpFile->close();
401 docWriter->addCompleteElement( tmpFile );
402 contentTmpFile.close();
403
404 docWriter->endElement(); // Root element
405 docWriter->endDocument();
406 delete docWriter;
407
408 if( !store->close() )
409 return false;
410
411 manifestWriter->addManifestEntry( "content.xml", "text/xml" );
412
413 if( !store->open( "styles.xml" ) )
414 return false;
415
416 KoXmlWriter* styleWriter = createOasisXmlWriter( &storeDev, "office:document-styles" );
417
418 styleWriter->startElement( "office:styles" );
419
420 styles = mainStyles.styles( VDocument::STYLE_LINEAR_GRADIENT );
421 it = styles.begin();
422 for( ; it != styles.end() ; ++it )
423 (*it).style->writeStyle( styleWriter, mainStyles, "svg:linearGradient", (*it).name, 0, true, true /*add draw:name*/);
424
425 styles = mainStyles.styles( VDocument::STYLE_RADIAL_GRADIENT );
426 it = styles.begin();
427 for( ; it != styles.end() ; ++it )
428 (*it).style->writeStyle( styleWriter, mainStyles, "svg:radialGradient", (*it).name, 0, true, true /*add draw:name*/);
429
430 styleWriter->endElement(); // office:styles
431
432 styleWriter->startElement( "office:automatic-styles" );
433
434 TQValueList<KoGenStyles::NamedStyle> styleList = mainStyles.styles( KoGenStyle::STYLE_PAGELAYOUT );
435 it = styleList.begin();
436
437 for( ; it != styleList.end(); ++it )
438 (*it).style->writeStyle( styleWriter, mainStyles, "style:page-layout", (*it).name, "style:page-layout-properties" );
439
440 styleWriter->endElement(); // office:automatic-styles
441
442 styles = mainStyles.styles( KoGenStyle::STYLE_MASTER );
443 it = styles.begin();
444 styleWriter->startElement("office:master-styles");
445
446 for( ; it != styles.end(); ++it)
447 (*it).style->writeStyle( styleWriter, mainStyles, "style:master-page", (*it).name, "");
448
449 styleWriter->endElement(); // office:master-styles
450
451 styleWriter->endElement(); // Root element
452 styleWriter->endDocument();
453 delete styleWriter;
454
455 if( !store->close() )
456 return false;
457
458 manifestWriter->addManifestEntry( "styles.xml", "text/xml" );
459
460
461 if(!store->open("settings.xml"))
462 return false;
463
464
465 KoXmlWriter& settingsWriter = *createOasisXmlWriter(&storeDev, "office:document-settings");
466 settingsWriter.startElement("office:settings");
467 settingsWriter.startElement("config:config-item-set");
468 settingsWriter.addAttribute("config:name", "view-settings");
469
470 KoUnit::saveOasis(&settingsWriter, unit());
471 saveOasisSettings( settingsWriter );
472
473 settingsWriter.endElement(); // config:config-item-set
474 settingsWriter.endElement(); // office:settings
475 settingsWriter.endElement(); // Root element
476 settingsWriter.endDocument();
477 delete &settingsWriter;
478
479
480 if(!store->close())
481 return false;
482
483 manifestWriter->addManifestEntry("settings.xml", "text/xml");
484
485 setModified( false );
486 return true;
487}
488
489void
490KarbonPart::saveOasisSettings( KoXmlWriter &/*settingsWriter*/ )
491{
492 //todo
493}
494
495void
497{
498 // don't repaint here explicitly. some commands might want to insert many
499 // objects.
500 m_doc.append( object );
501 setModified( true );
502}
503
504void
505KarbonPart::addCommand( VCommand* cmd, bool repaint )
506{
507 m_commandHistory->addCommand( cmd );
508 setModified( true );
509
510 if( repaint )
512}
513
514void
515KarbonPart::slotDocumentRestored()
516{
517 setModified( false );
518}
519
520void
521KarbonPart::slotCommandExecuted( VCommand *command )
522{
523 setModified( true );
524}
525
526void
527KarbonPart::clearHistory()
528{
529 m_commandHistory->clear();
530}
531
532void
534{
535 TQPtrListIterator<KoView> itr( views() );
536
537 for( ; itr.current() ; ++itr )
538 static_cast<KarbonView*>( itr.current() )->canvasWidget()->repaintAll( repaint );
539}
540
541void
542KarbonPart::repaintAllViews( const KoRect &rect )
543{
544 TQPtrListIterator<KoView> itr( views() );
545
546 for( ; itr.current() ; ++itr )
547 static_cast<KarbonView*>( itr.current() )->canvasWidget()->repaintAll( rect );
548}
549
550void
551KarbonPart::paintContent( TQPainter& painter, const TQRect& rect,
552 bool /*transparent*/, double /*zoomX*/, double /*zoomY*/ )
553{
554 kdDebug(38000) << "**** part->paintContent()" << endl;
555
556 KoRect r = KoRect::fromTQRect( rect );
557 double zoomFactorX = double( r.width() ) / double( document().width() );
558 double zoomFactorY = double( r.height() ) / double( document().height() );
559 double zoomFactor = kMin( zoomFactorX, zoomFactorY );
560
561 painter.eraseRect( rect );
562 VPainterFactory *painterFactory = new VPainterFactory;
563 //TQPaintDeviceMetrics metrics( painter.device() );
564 painterFactory->setPainter( painter.device(), rect.width(), rect.height() );
565 VPainter *p = painterFactory->painter();
566 //VPainter *p = new VKoPainter( painter.device() );
567 p->begin();
568 p->setZoomFactor( zoomFactor );
569 kdDebug(38000) << "painter.worldMatrix().dx() : " << painter.worldMatrix().dx() << endl;
570 kdDebug(38000) << "painter.worldMatrix().dy() : " << painter.worldMatrix().dy() << endl;
571 kdDebug(38000) << "rect.x() : "<< rect.x() << endl;
572 kdDebug(38000) << "rect.y() : "<< rect.y() << endl;
573 kdDebug(38000) << "rect.width() : "<< rect.width() << endl;
574 kdDebug(38000) << "rect.height() : "<< rect.height() << endl;
575 r = document().boundingBox();
576 TQWMatrix mat = painter.worldMatrix();
577 mat.scale( 1, -1 );
578 mat.translate( 0, -r.height() * zoomFactor );
579 p->setWorldMatrix( mat );
580
581 m_doc.selection()->clear();
582 TQPtrListIterator<VLayer> itr( m_doc.layers() );
583
584 for( ; itr.current(); ++itr )
585 {
586 itr.current()->draw( p, &r );
587 }
588
589 p->end();
590 delete painterFactory;
591}
592
593void
594KarbonPart::setShowStatusBar( bool b )
595{
596 m_bShowStatusBar = b;
597}
598
599void
601{
602 TQPtrListIterator<KoView> itr( views() );
603
604 for( ; itr.current(); ++itr )
605 {
606 static_cast<KarbonView*>( itr.current() )->reorganizeGUI();
607 }
608}
609
610void
611KarbonPart::setUndoRedoLimit( int undos )
612{
613 m_commandHistory->setUndoLimit( undos );
614 m_commandHistory->setRedoLimit( undos );
615}
616
617void
618KarbonPart::initConfig()
619{
620 TDEConfig* config = KarbonPart::instance()->config();
621
622 if( config->hasGroup( "Interface" ) )
623 {
624 config->setGroup( "Interface" );
625 setAutoSave( config->readNumEntry( "AutoSave", defaultAutoSave() / 60 ) * 60 );
626 m_maxRecentFiles = config->readNumEntry( "NbRecentFile", 10 );
627 setShowStatusBar( config->readBoolEntry( "ShowStatusBar" , true ) );
628 setBackupFile( config->readNumEntry( "BackupFile", true ) );
629 m_doc.saveAsPath( config->readBoolEntry( "SaveAsPath", true ) );
630 }
631 int undos = 30;
632 if( config->hasGroup( "Misc" ) )
633 {
634 config->setGroup( "Misc" );
635 undos = config->readNumEntry( "UndoRedo", -1 );
636 TQString defaultUnit = "cm";
637
638 if( TDEGlobal::locale()->measureSystem() == TDELocale::Imperial )
639 defaultUnit = "in";
640
641 setUnit( KoUnit::unit( config->readEntry( "Units", defaultUnit ) ) );
642 m_doc.setUnit( unit() );
643 }
644 if( undos != -1 )
645 setUndoRedoLimit( undos );
646}
647
648bool
649KarbonPart::mergeNativeFormat( const TQString &file )
650{
651 m_merge = true;
652 bool result = loadNativeFormat( file );
653 if ( !result )
654 showLoadingErrorDialog();
655 m_merge = false;
656 return result;
657}
658
659void
660KarbonPart::addShell( KoMainWindow *shell )
661{
662 connect( shell, TQ_SIGNAL( documentSaved() ), m_commandHistory, TQ_SLOT( documentSaved() ) );
663 KoDocument::addShell( shell );
664}
665
666
667void
668KarbonPart::slotUnitChanged( KoUnit::Unit /*unit*/ )
669{
670#if 0
671 // VDocument has its own storage of the unit...
672 m_doc.setUnit( unit );
673 if( m_toolController->activeTool() )
674 m_toolController->activeTool()->refreshUnit();
675#endif
676}
677
678#include "karbon_part.moc"
679
virtual bool initDoc(InitDocFlags flags, TQWidget *parentWidget=0)
standard koDocument inherited methods
void repaintAllViews(bool repaint=true)
repaint all views attached to this koDocument
void reorganizeGUI()
update attached view(s) on the current doc settings at this time only the status bar is handled
void addCommand(VCommand *cmd, bool repaint=false)
insert a command into the undo/redo-history:
virtual TQDomDocument saveXML()
file-> save and file-> save as call this method
void insertObject(VObject *object)
insert a new vobject
virtual bool loadXML(TQIODevice *, const TQDomDocument &document)
file-> open calls this method
Manages a set of commands.
Definition vcommand.h:144
void setUndoLimit(unsigned int limit)
Sets a new undo limit.
Definition vcommand.cpp:99
void setRedoLimit(unsigned int limit)
Sets a new redo limit.
Definition vcommand.cpp:106
The base class for all karbon commands.
Definition vcommand.h:42
The base class for all karbon objects.
Definition vobject.h:50
@ selected
visible, active and can be manipulated by tools
Definition vobject.h:61