File indexing completed on 2024-05-12 15:26:37
0001 /*************************************************************************** 0002 File : AbstractAspect.h 0003 Project : LabPlot 0004 -------------------------------------------------------------------- 0005 Copyright : (C) 2007-2009 by Tilman Benkert (thzs@gmx.net) 0006 Copyright : (C) 2007-2010 by Knut Franke (knut.franke@gmx.de) 0007 Copyright : (C) 2011-2015 by Alexander Semke (alexander.semke@web.de) 0008 Description : Base class for all objects in a Project. 0009 0010 ***************************************************************************/ 0011 0012 /*************************************************************************** 0013 * * 0014 * This program is free software; you can redistribute it and/or modify * 0015 * it under the terms of the GNU General Public License as published by * 0016 * the Free Software Foundation; either version 2 of the License, or * 0017 * (at your option) any later version. * 0018 * * 0019 * This program is distributed in the hope that it will be useful, * 0020 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0021 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0022 * GNU General Public License for more details. * 0023 * * 0024 * You should have received a copy of the GNU General Public License * 0025 * along with this program; if not, write to the Free Software * 0026 * Foundation, Inc., 51 Franklin Street, Fifth Floor, * 0027 * Boston, MA 02110-1301 USA * 0028 * * 0029 ***************************************************************************/ 0030 #ifndef ABSTRACT_ASPECT_H 0031 #define ABSTRACT_ASPECT_H 0032 0033 #include <QObject> 0034 #include <QVector> 0035 0036 class AbstractAspectPrivate; 0037 class Folder; 0038 class Project; 0039 class XmlStreamReader; 0040 0041 class QDateTime; 0042 class QIcon; 0043 class QMenu; 0044 class QUndoCommand; 0045 class QUndoStack; 0046 class QXmlStreamWriter; 0047 0048 /// Information about class inheritance 0049 /// enum values are chosen such that @verbatim inherits(base)@endverbatim 0050 /// returns true iff the class inherits from @verbatim base@endverbatim. 0051 /// 0052 /// AspectType is used in GuiObserver to select the correct dock widget. 0053 enum class AspectType : quint64 { 0054 AbstractAspect = 0, 0055 0056 // classes without inheriters 0057 AbstractFilter = 0x0100001, 0058 DatapickerCurve = 0x0100002, 0059 DatapickerPoint = 0x0100004, 0060 0061 WorksheetElement = 0x0200000, 0062 Axis = 0x0210001, 0063 CartesianPlotLegend = 0x0210002, 0064 CustomPoint = 0x0210004, 0065 Histogram = 0x0210008, 0066 PlotArea = 0x0210010, 0067 TextLabel = 0x0210020, 0068 Image = 0x0210030, 0069 ReferenceLine = 0x0210040, 0070 WorksheetElementContainer = 0x0220000, 0071 AbstractPlot = 0x0221000, 0072 CartesianPlot = 0x0221001, 0073 WorksheetElementGroup = 0x0222000, 0074 XYCurve = 0x0240000, 0075 XYEquationCurve = 0x0240001, 0076 XYAnalysisCurve = 0x0280000, 0077 XYConvolution = 0x0280001, 0078 XYCorrelationCurve = 0x0280002, 0079 XYDataReductionCurve = 0x0280004, 0080 XYDifferentiationCurve = 0x0280008, 0081 XYFitCurve = 0x0280010, 0082 XYFourierFilterCurve = 0x0280020, 0083 XYFourierTransformCurve = 0x0280040, 0084 XYInterpolationCurve = 0x0280080, 0085 XYIntegrationCurve = 0x0280100, 0086 XYSmoothCurve = 0x0280200, 0087 0088 AbstractPart = 0x0400000, 0089 AbstractDataSource = 0x0410000, 0090 Matrix = 0x0411000, 0091 Spreadsheet = 0x0412000, 0092 LiveDataSource = 0x0412001, 0093 MQTTTopic = 0x0412002, 0094 CantorWorksheet = 0x0420001, 0095 Datapicker = 0x0420002, 0096 DatapickerImage = 0x0420004, 0097 Note = 0x0420008, 0098 Workbook = 0x0420010, 0099 Worksheet = 0x0420020, 0100 0101 AbstractColumn = 0x1000000, 0102 Column = 0x1000001, 0103 SimpleFilterColumn = 0x1000002, 0104 ColumnStringIO = 0x1000004, 0105 0106 Folder = 0x2000000, 0107 Project = 0x2000001, 0108 MQTTClient = 0x2000002, 0109 MQTTSubscription = 0x2000004, 0110 }; 0111 0112 class AbstractAspect : public QObject { 0113 Q_OBJECT 0114 0115 public: 0116 enum class ChildIndexFlag { 0117 IncludeHidden = 0x01, 0118 Recursive = 0x02, 0119 Compress = 0x04 0120 }; 0121 0122 Q_DECLARE_FLAGS(ChildIndexFlags, ChildIndexFlag) 0123 0124 friend class AspectChildAddCmd; 0125 friend class AspectChildRemoveCmd; 0126 friend class AbstractAspectPrivate; 0127 0128 AbstractAspect(const QString& name, AspectType type); 0129 ~AbstractAspect() override; 0130 0131 QString name() const; 0132 QString comment() const; 0133 void setCreationTime(const QDateTime&); 0134 QDateTime creationTime() const; 0135 virtual Project* project(); 0136 virtual QString path() const; 0137 void setHidden(bool); 0138 bool hidden() const; 0139 void setSelected(bool); 0140 void setIsLoading(bool); 0141 bool isLoading() const; 0142 virtual QIcon icon() const; 0143 virtual QMenu* createContextMenu(); 0144 0145 AspectType type() const; 0146 bool inherits(AspectType type) const; 0147 0148 //functions related to the handling of the tree-like project structure 0149 AbstractAspect* parentAspect() const; 0150 AbstractAspect* parent(AspectType type) const; 0151 void setParentAspect(AbstractAspect*); 0152 Folder* folder(); 0153 bool isDescendantOf(AbstractAspect* other); 0154 void addChild(AbstractAspect*); 0155 void addChildFast(AbstractAspect*); 0156 virtual void finalizeAdd() {}; 0157 QVector<AbstractAspect*> children(AspectType type, ChildIndexFlags flags = {}) const; 0158 void insertChildBefore(AbstractAspect* child, AbstractAspect* before); 0159 void insertChildBeforeFast(AbstractAspect* child, AbstractAspect* before); 0160 void reparent(AbstractAspect* newParent, int newIndex = -1); 0161 void removeChild(AbstractAspect*); 0162 void removeAllChildren(); 0163 virtual QVector<AbstractAspect*> dependsOn() const; 0164 0165 virtual bool isDraggable() const; 0166 virtual QVector<AspectType> dropableOn() const; 0167 virtual void processDropEvent(const QVector<quintptr>&) {}; 0168 0169 template <class T> T* ancestor() const { 0170 AbstractAspect* parent = parentAspect(); 0171 while (parent) { 0172 T* ancestorAspect = dynamic_cast<T*>(parent); 0173 if (ancestorAspect) 0174 return ancestorAspect; 0175 parent = parent->parentAspect(); 0176 } 0177 return nullptr; 0178 } 0179 0180 template <class T> QVector<T*> children(ChildIndexFlags flags = {}) const { 0181 QVector<T*> result; 0182 for (auto* child: children()) { 0183 if (flags & ChildIndexFlag::IncludeHidden || !child->hidden()) { 0184 T* i = dynamic_cast<T*>(child); 0185 if (i) 0186 result << i; 0187 0188 if (child && flags & ChildIndexFlag::Recursive) 0189 result << child->template children<T>(flags); 0190 } 0191 } 0192 return result; 0193 } 0194 0195 template <class T> T* child(int index, ChildIndexFlags flags = {}) const { 0196 int i = 0; 0197 for (auto* child: children()) { 0198 T* c = dynamic_cast<T*>(child); 0199 if (c && (flags & ChildIndexFlag::IncludeHidden || !child->hidden()) && index == i++) 0200 return c; 0201 } 0202 return nullptr; 0203 } 0204 0205 template <class T> T* child(const QString& name) const { 0206 for (auto* child: children()) { 0207 T* c = dynamic_cast<T*>(child); 0208 if (c && child->name() == name) 0209 return c; 0210 } 0211 return nullptr; 0212 } 0213 0214 template <class T> int childCount(ChildIndexFlags flags = {}) const { 0215 int result = 0; 0216 for (auto* child: children()) { 0217 T* i = dynamic_cast<T*>(child); 0218 if (i && (flags & ChildIndexFlag::IncludeHidden || !child->hidden())) 0219 result++; 0220 } 0221 return result; 0222 } 0223 0224 template <class T> int indexOfChild(const AbstractAspect* child, ChildIndexFlags flags = {}) const { 0225 int index = 0; 0226 for (auto* c: children()) { 0227 if (child == c) return index; 0228 T* i = dynamic_cast<T*>(c); 0229 if (i && (flags & ChildIndexFlag::IncludeHidden || !c->hidden())) 0230 index++; 0231 } 0232 return -1; 0233 } 0234 0235 //undo/redo related functions 0236 void setUndoAware(bool); 0237 virtual QUndoStack* undoStack() const; 0238 void exec(QUndoCommand*); 0239 void exec(QUndoCommand* command, const char* preChangeSignal, const char* postChangeSignal, 0240 QGenericArgument val0 = QGenericArgument(), QGenericArgument val1 = QGenericArgument(), 0241 QGenericArgument val2 = QGenericArgument(), QGenericArgument val3 = QGenericArgument()); 0242 void beginMacro(const QString& text); 0243 void endMacro(); 0244 0245 //save/load 0246 virtual void save(QXmlStreamWriter*) const = 0; 0247 virtual bool load(XmlStreamReader*, bool preview) = 0; 0248 0249 protected: 0250 void info(const QString& text) { emit statusInfo(text); } 0251 0252 //serialization/deserialization 0253 bool readBasicAttributes(XmlStreamReader*); 0254 void writeBasicAttributes(QXmlStreamWriter*) const; 0255 void writeCommentElement(QXmlStreamWriter*) const; 0256 bool readCommentElement(XmlStreamReader*); 0257 0258 const AspectType m_type; 0259 0260 private: 0261 AbstractAspectPrivate* d; 0262 0263 QString uniqueNameFor(const QString&) const; 0264 const QVector<AbstractAspect*>& children() const; 0265 void connectChild(AbstractAspect*); 0266 0267 public slots: 0268 bool setName(const QString&, bool autoUnique = true); 0269 void setComment(const QString&); 0270 void remove(); 0271 0272 protected slots: 0273 virtual void childSelected(const AbstractAspect*); 0274 virtual void childDeselected(const AbstractAspect*); 0275 0276 signals: 0277 void aspectDescriptionAboutToChange(const AbstractAspect*); 0278 void aspectDescriptionChanged(const AbstractAspect*); 0279 void aspectAboutToBeAdded(const AbstractAspect* parent, const AbstractAspect* before, const AbstractAspect* child); 0280 void aspectAdded(const AbstractAspect*); 0281 void aspectAboutToBeRemoved(const AbstractAspect*); 0282 void aspectRemoved(const AbstractAspect* parent, const AbstractAspect* before, const AbstractAspect* child); 0283 void aspectHiddenAboutToChange(const AbstractAspect*); 0284 void aspectHiddenChanged(const AbstractAspect*); 0285 void statusInfo(const QString&); 0286 void renameRequested(); 0287 0288 //selection/deselection in model (project explorer) 0289 void selected(const AbstractAspect*); 0290 void deselected(const AbstractAspect*); 0291 0292 //selection/deselection in view 0293 void childAspectSelectedInView(const AbstractAspect*); 0294 void childAspectDeselectedInView(const AbstractAspect*); 0295 }; 0296 0297 Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractAspect::ChildIndexFlags) 0298 0299 #endif // ifndef ABSTRACT_ASPECT_H