00001 /* -*- c++ -*- (for Emacs) 00002 * 00003 * abstractelement.h 00004 * Digest 00005 * 00006 * Imported into Digest by Aidan Lane on Thu Jun 9 2005. 00007 * Modifications Copyright (c) 2005 Optimisation and Constraint Solving Group, 00008 * Monash University. All rights reserved. 00009 * 00010 * Nodal file: 00011 * 00012 * pelement.h 00013 * 00014 * Created by Aidan Lane on Wed Apr 6 2005. 00015 * Copyright (c) 2005 CEMA, Monash University. All rights reserved. 00016 * 00017 * This program is free software; you can redistribute it and/or modify 00018 * it under the terms of the GNU General Public License as published by 00019 * the Free Software Foundation; either version 2 of the License, or 00020 * (at your option) any later version. 00021 * 00022 * This program is distributed in the hope that it will be useful, 00023 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00025 * GNU General Public License for more details. 00026 * 00027 * You should have received a copy of the GNU General Public License 00028 * along with this program; if not, write to the Free Software 00029 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00030 */ 00031 00032 // See ElementDoc.cpp for why AbstractElement needs to be a derivative of QObject (we need deleteLater()) - among other reasons 00033 00034 #ifndef ABSTRACTELEMENT_H 00035 #define ABSTRACTELEMENT_H 00036 00037 00038 #include <QObject> 00039 #include "domaccessiblestate.h" 00040 00041 #include <QHash> 00042 #include <QReadLocker> 00043 #include <QReadWriteLock> 00044 00045 #include "elementevents.h" 00046 00047 class QByteArray; 00048 00049 class ElementDoc; 00050 class AbstractController; 00051 00052 00058 class AbstractElement : public QObject, public DomAccessibleState { 00059 00060 Q_OBJECT 00061 00062 public: 00063 virtual ~AbstractElement(); 00064 00065 // The following are pure-virtual, as to force sub-classes to implement them 00066 virtual int type() const = 0; // returns int, not Type, as to aid extensibility 00067 virtual const QByteArray& key() const = 0; 00068 virtual const QString& title() const = 0; 00069 00070 quint32 instanceId() const { return m_instanceId; } 00071 00072 ElementDoc* doc() const; 00073 AbstractController* controller() const; 00074 00075 QHash<int, AbstractElementAttribute*> attributes() const; 00076 AbstractElementAttribute* attribute( int type ) const; 00077 template<class T> inline T* attribute() const; 00078 QVariant attributeData( int type ) const; 00079 00080 virtual const QSet<int>& requiredAttributes() const; 00081 virtual const QSet<int>& additionalAttributes() const; 00082 00083 virtual QDomElement domElement( QDomDocument& doc ) const; 00084 virtual void initFromDomElement( const QDomElement& e, InitModeFlags modeFlags ); 00085 00086 00087 protected: 00088 AbstractElement( quint32 instanceId, ElementDoc* abstractDoc ); 00089 AbstractElement( ElementDoc* abstractDoc ); 00090 00091 void addMissingRequiredAttributes(); 00092 bool trySetAttributeData( int type, const QVariant& data ); 00093 00095 virtual AbstractElementAttribute* createAttribute( int type ) = 0; 00096 virtual AbstractElementAttribute* createAttribute( const QByteArray& key ) = 0; 00097 virtual int attributeKeyToType( const QByteArray& key ) = 0; 00098 00099 inline virtual void customEvent( QEvent* e ) { 00100 MEvent* me = dynamic_cast<MEvent*>(e); // slow :-( 00101 if ( me != 0 ) dispatchEvent(me); 00102 } 00103 virtual void dispatchEvent( MEvent* ); 00104 00105 virtual void attributeAddPtrEvent( MEAttributeAddPtrEvent* ); 00106 virtual void attributeRemovePtrEvent( MEAttributeRemovePtrEvent* ); 00107 00108 00109 private: 00110 // You may get the following variables with domElement() and set them with 00111 // initFromDOMElement(). 00112 quint32 m_instanceId; 00113 QHash<int, AbstractElementAttribute*> m_attributes; // type -> instance 00114 mutable QReadWriteLock m_attributesLock; 00115 00116 // The following variables are for temporary use only. 00117 ElementDoc* m_doc; 00118 }; 00119 00120 00129 template<class T> 00130 T* AbstractElement::attribute() const { 00131 // Note: the static cast should be fairly safe, given that we specify an enum'd type 00132 QReadLocker locker( &m_attributesLock ); 00133 return static_cast<T*>( m_attributes.value(T::classType()) ); 00134 } 00135 00136 00137 #endif // ! ABSTRACTELEMENT_H
1.5.2