summaryrefslogtreecommitdiffstats
path: root/kpovmodeler/pmobject.h
blob: 3f454ab5d5bc18b0559558e376bf27ec9a5b523c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
//-*-C++-*-
/*
**************************************************************************
                                 description
                             --------------------
    copyright            : (C) 2000-2003 by Andreas Zehender
    email                : [email protected]
**************************************************************************

**************************************************************************
*                                                                        *
*  This program is free software; you can redistribute it and/or modify  *
*  it under the terms of the GNU General Public License as published by  *
*  the Free Software Foundation; either version 2 of the License, or     *
*  (at your option) any later version.                                   *
*                                                                        *
**************************************************************************/


#ifndef PMOBJECT_H
#define PMOBJECT_H

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <tqvaluelist.h>
#include <tqptrlist.h>
#include <tqstring.h>
#include <tqstringlist.h>
#include <kdebug.h>
#include <tqdom.h>

#include "pmmatrix.h"
#include "pmcontrolpoint.h"
#include "pmmetaobject.h"
#include "pmdebug.h"

class PMDialogEditBase;
class PMMemento;
class PMViewStructure;
class PMXMLHelper;
class PMDeclare;
class PMObjectAction;
class PMPart;

class PMObject;
typedef TQPtrList<PMObject> PMObjectList;
typedef TQPtrListIterator<PMObject> PMObjectListIterator;

/**
 * Base class for all povray objects
 *
 * Used pattern: Composite
 *
 * All list/child functionality is disabled in this class. Objects that
 * can have children has to be inherited from @ref PMCompositeObject.
 */
class PMObject
{
   friend class PMCompositeObject;
public:
   /**
    * Creates an empty PMObject without parent.
    */
   PMObject( PMPart* part );
   /**
    * Copy constructor. All object pointers (parent, siblings) are set to 0!
    */
   PMObject( const PMObject& o );
   /**
    * Deletes the object and all children.
    */
   virtual ~PMObject( );

   /**
    * Returns a new object of that type
    */
   PMObject* newObject( ) const;
   /**
    * Returns a deep copy of the object
    */
   virtual PMObject* copy( ) const = 0;

   /**
    * Returns the meta object for the class
    */
   virtual PMMetaObject* metaObject( ) const;

   /**
    * Returns true if the object is of type t or inherits the object
    * class with type t
    */
   bool isA( const TQString& className ) const;

   /**
    * Returns the class name (not i18n'ed, without the PM prefix)
    */
   TQString type( ) const;
   /**
    * same as @ref type( )
    */
   TQString className( ) const { return type( ); }
   /**
    * Returns the class name of the object (povray name).
    * This is the name that is showed in dialogs and menus.
    */
   virtual TQString description( ) const = 0;
   /**
    * Returns the name of the object. This is the name that helps
    * the user to identify a object (like "south wall", "floor" ...)
    */
   virtual TQString name( ) const { return TQString(); }
   /**
    * Returns true if the object can have a name
    */
   virtual bool canHaveName( ) const { return false; }
   /**
    * Returns true if the object should be exported for rendering
    */
   virtual bool exportPovray( ) const { return true; }

   /**
    * Returns a pointer to the parent object.
    */
   PMObject* parent( ) const { return m_pParent; }
   /**
    * Returns a pointer to the corresponding part
    */
   PMPart* part( ) const { return m_pPart; }

   /**
    * Returns true if an object with type className can be inserted
    * as child after the object after.
    *
    * The parser uses the third parameter for top level objects. These objects
    * have to be treated as if they are inserted after the object after.
    */
   bool canInsert( const TQString& className, const PMObject* after,
                   const PMObjectList* objectsBetween = 0 ) const;
   /**
    * Returns true if the object o can be inserted as child after the object
    * after.
    *
    * The parser uses the third parameter for top level objects. These objects
    * have to be treated as if they are inserted after the object after.
    */
   bool canInsert( const PMObject* o, const PMObject* after,
                   const PMObjectList* objectsBetween = 0 ) const;
   /**
    * Returns the number of objects that can be inserted at that position
    */
   int canInsert( const PMObjectList& list, const PMObject* after ) const;
   /**
    * Returns the number of objects that can be inserted at that position
    */
   int canInsert( const TQStringList& classes, const PMObject* after ) const;

   /**
    * Returns true if an insert or remove operation of children will
    * change data inside this class
    */
   virtual bool dataChangeOnInsertRemove( ) const { return false; }

   /**
    * Returns a pointer to the first child. Null for this class
    */
   virtual PMObject* firstChild( ) const { return 0; }
   /**
    * Returns a pointer to the last child. Null for this class
    */
   virtual PMObject* lastChild( ) const { return 0; }
   /**
    * Returns a pointer to the child object at position index,
    * or null if the index is out of range.
    */
   virtual PMObject* childAt( uint ) const { return 0; }
   /**
    * Returns the next sibling of that item
    */
   PMObject* nextSibling( ) const { return m_pNextSibling; }
   /**
    * Returns the previous sibling of that item
    */
   PMObject* prevSibling( ) const { return m_pPrevSibling; }

   /**
    * Returns true if the object contains the child object o
    */
   virtual bool containsChild( PMObject* ) const { return false; }
   /**
    * Returns the index of the child or -1 if not found
    */
   virtual int findChild( PMObject* ) { return -1; }
   /**
    * Inserts the object as child at index index.
    * If i is -1, the object is appended.
    * Returns true if successful
    */
   virtual bool insertChild( PMObject*, int )
   {
      kdError( PMArea ) << "Tried to insert object into a non composite object" << "\n";
      return false;
   }
   /**
    * Inserts the object as child after the child object after
    */
   virtual bool insertChildAfter( PMObject* object, PMObject* after );
   /**
    * Inserts the object as child before the child object before
    */
   virtual bool insertChildBefore( PMObject* object, PMObject* before );
   /**
    * Appends the object as last child. Returns true if successful
    */
   virtual bool appendChild( PMObject* )
   {
      kdError( PMArea ) << "Tried to insert object into a non composite object" << "\n";
      return false;
   }
   /**
    * Returns the number of children. 0 in this class
    */
   virtual int countChildren( ) const { return 0; }
   /**
    * Removes a child object. Does not delete it!
    * Returns true if successful
    */
   virtual bool takeChild( PMObject* );
   /**
    * Removes a child object at index i. Does not delete it!
    * Returns true if successful
    */
   virtual bool takeChild( uint );

   /**
    * Called when a child was removed. For classes that have to be informed
    * when children are removed
    */
   virtual void childRemoved( PMObject* ) { };
   /**
    * Called when a child was added. For classes that have to be informed
    * when children are added
    */
   virtual void childAdded( PMObject* ) { };

   /**
    * Returns true if the object needs auxiliary files.
    */
   virtual bool needsAuxiliaryFiles( ) const { return false; }
   /**
    * Returns a list of auxiliary files
    */
   virtual TQStringList auxiliaryFiles( ) const { return TQStringList( ); }

   /**
    * Returns true if the object has a (povray) transformation matrix.
    * True for transformation objects.
    */
   virtual bool hasTransformationMatrix( ) const { return false; }
   /**
    * Returns the (povray) transformation of the object, if it has one,
    * otherwise an identity matrix
    */
   virtual PMMatrix transformationMatrix( ) const
   {
      kdError( PMArea ) << "This object has no transformation matrix" << "\n";
      return PMMatrix::identity( );
   }
   /**
    * Returns the matrix, the object is transformed with
    */
   PMMatrix transformedWith( ) const;

   /**
    * Returns the view structure ( see @ref PMViewStructure ) of the object
    * or 0, if it has none.
    *
    * The view structure will be created or updated if necessary.
    */
   virtual PMViewStructure* viewStructure( ) { return 0; }

   /**
    * Creates the control points and appends them to the list.
    *
    * The caller becomes the owner of the control points and has
    * to delete them.
    *
    * Control points are the interface between the graphical views and the
    * PMObject for graphical changes.
    */
   virtual void controlPoints( PMControlPointList& ) { }
   /**
    * Tells the object that the control points have changed
    */
   virtual void controlPointsChanged( PMControlPointList& ) { }
   /**
    * Tells the object that the control points have changed
    *
    * The object can add objects to the second parameter, if
    * additional objects were changed during the graphical change,
    * not only this object.
    *
    * If you leave the list empty, only this object was changed.
    * If you add children or other objects to the list, add this object
    * to the list, too, if it was changed!
    *
    * IMPORTANT: When you change additional objects, make sure that
    * a memento is created for these objects (@ref mementoCreated,
    * @ref createMemento) before changing data.
    *
    * Calls @ref controlPointsChanged by default.
    */
   virtual void controlPointsChangedList( PMControlPointList& list,
                                          PMObjectList& /*changedObjects*/ )
   {
      controlPointsChanged( list );
   }
   /**
    * Returns true if multiple control points can be selected
    */
   virtual bool multipleSelectControlPoints( ) const { return false; }

   /**
    * Each object can add actions to the context menu of the @ref PMGLView.
    *
    * Each time the user opens the context menu, this function is called.
    * Add all supported actions to this list and call the base class.
    *
    * The default implementation adds no action.
    *
    * @see PMObjectAction
    */
   virtual void addObjectActions( const PMControlPointList&,
                                  TQPtrList<PMObjectAction>& ) { }

   /**
    * This member is called when the user selects an object action
    * in the context menu.
    *
    * The arguments are the selected action, the list of control points,
    * the 3D (!) positions of the control points (screen-x, screen-y and depth)
    * in the active opengl view and the 2D mouse position.
    */
   virtual void objectActionCalled( const PMObjectAction*,
                                    const PMControlPointList&,
                                    const TQPtrList<PMVector>&,
                                    const PMVector& ) { };

   /**
    * Saves the object as kpovmodeler xml code.
    */
   TQDomElement serialize( TQDomDocument& doc ) const;
   /**
    * Adds the objects attributes and child objects to the element
    */
   virtual void serialize( TQDomElement& e, TQDomDocument& doc ) const = 0;
   /**
    * Reads the attributes from the TQDomElement
    */
   virtual void readAttributes( const PMXMLHelper& h );

   /**
    * Returns the list of known properties
    */
   TQStringList properties( ) const;

   /**
    * Sets a property and returns true if successful
    */
   bool setProperty( const TQString&, const PMVariant& v );
   /**
    * Returns a property
    */
   PMVariant property( const TQString& ) const;

   /**
    * Returns true if the object is selected
    */
   bool isSelected( ) { return m_selected; }
   /**
    * Sets this object to be selected if s is true and to not be selected
       if s is false
    */
   void setSelected( bool s );
   /**
    * Returns true if this item can be selected. An item cannot be selected
    * if a parent object is selected
    */
   bool isSelectable( );
   /**
    * Returns the number of selected child items. All selected items in
    * any depth are counted
    */
   virtual int selectedChildren( ) const { return 0; }
   /**
    * Deselects recursively all child objects
    */
   virtual void deselectChildren( ) { };
   /**
    * Returns true if this object is read only
    */
   bool isReadOnly( ) const;
   /**
    * Makes this object read only, if yes == true. All children will
    * be read only, too
    */
   void setReadOnly( bool yes = true ) { m_readOnly = yes; }

   /**
    * Creates a new edit widget that can display this object and
    * returns a pointer to it.
    *
    * The widget will be created as a child of parent.
    */
   virtual PMDialogEditBase* editWidget( TQWidget* parent ) const;
   /**
    * Returns the name of the pixmap that is displayed in the tree view
    * and dialog view
    */
   virtual TQString pixmap( ) const = 0;
   /**
    * Returns a pointer to the @ref PMDeclare object, that is linked to
    * that object, or 0, if this object contains no link
    */
   virtual PMDeclare* linkedObject( ) const { return 0; }

   /**
    * Tells the object to create a memento object.
    *
    * By default a simple @ref PMMemento will be created.
    * If the memento doesn't provide enough functionality, subclass the memento
    * and reimplement this function.
    *
    * NOTE: The new memento has to inherit the memento used in the base class!
    *
    * If a memento was created, the object saves all changes its
    * state. The memento is then used for undo/redo.
    *
    * First call this function, change attributes and then take the mementos
    * with @ref takeMemento
    *
    * If you want to restore the old state, call @ref restoreMemento with
    * the memento.
    */
   virtual void createMemento( );
   /**
    * Returns true if a memento was created
    */
   bool mementoCreated( ) const { return m_pMemento != 0; }
   /**
    * Takes the memento. The caller is responsible to delete the memento
    */
   PMMemento* takeMemento( );
   /**
    * Restores the state s
    */
   virtual void restoreMemento( PMMemento* s );

   /**
    * This function is called before the part is unloaded.
    *
    * Delete static pointer variables to clean up the memory.
    *
    * This method can be called multiple times when there are subclasses.
    * Set the pointer to 0 after deleting an object!
    */
   virtual void cleanUp( ) const;

protected:
   /**
    * Adds num to the number of selected objects in this object and all
    * parent objects. num can be negative.
    */
   virtual void adjustSelectedChildren( int /*num*/ ) { };
   /**
    * The memento where the old status of the object should be stored
    */
   PMMemento* m_pMemento;
private:
   /**
    * Pointer to the parent object. 0 if the object has no parent.
    */
   PMObject* m_pParent;
   /**
    * Pointer to the prev sibling. 0 if the object has no prev sibling.
    */
   PMObject* m_pPrevSibling;
   /**
    * Pointer to the next sibling. 0 if the object has no next sibling.
    */
   PMObject* m_pNextSibling;
   /**
    * true if this object is selected
    */
   bool m_selected;
   /**
    * true if this object is read only. All children will be read only, too
    */
   bool m_readOnly;
   /**
    * The meta object
    */
   static PMMetaObject* s_pMetaObject;
   /**
    * The corresponding part
    */
   PMPart* m_pPart;
};

#endif