1 /*
2     SPDX-License-Identifier: GPL-2.0-or-later
3     SPDX-FileCopyrightText: 2002-2021 Umbrello UML Modeller Authors <umbrello-devel@kde.org>
4 */
5 
6 #ifndef UMLDOC_H
7 #define UMLDOC_H
8 
9 // app includes
10 #include "basictypes.h"
11 #include "optionstate.h"
12 #include "umlobject.h"
13 #include "umlobjectlist.h"
14 #include "umlassociationlist.h"
15 #include "umlclassifierlist.h"
16 #include "umlentitylist.h"
17 #include "umlviewlist.h"
18 #include "umlstereotypelist.h"
19 #include "umlpackagelist.h"
20 
21 // kde includes
22 #if QT_VERSION < 0x050000
23 #include <kurl.h>
24 #endif
25 
26 // qt includes
27 #if QT_VERSION >= 0x050000
28 #include <QUrl>
29 #endif
30 #include <QMap>
31 
32 // system includes
33 #include <typeinfo>
34 
35 #define ENC_UNKNOWN 0
36 #define ENC_UNICODE 1
37 #define ENC_WINDOWS 2
38 #define ENC_OLD_ENC 3
39 
40 // forward declarations
41 class QDomNode;
42 class QDomElement;
43 class QPrinter;
44 
45 class IDChangeLog;
46 class DiagramsModel;
47 class ObjectsModel;
48 class StereotypesModel;
49 class UMLPackage;
50 class UMLFolder;
51 class DiagramPrintPage;
52 
53 /**
54  * UMLDoc provides a document object for a document-view model.
55  *
56  * The UMLDoc class provides a document object that can be used
57  * in conjunction with the classes UMLApp and UMLView to create
58  * a document-view model for standard KDE applications based on
59  * KApplication and KMainWindow. Thereby, the document object
60  * is created by the UMLApp instance and contains the document
61  * structure with the according methods for manipulation of the
62  * document data by UMLView objects. Also, UMLDoc contains the
63  * methods for serialization of the document data from and to
64  * files.
65  *
66  * @author Paul Hensgen   <phensgen@techie.com>
67  * Bugs and comments to umbrello-devel@kde.org or https://bugs.kde.org
68  */
69 class UMLDoc : public QObject
70 {
71     Q_OBJECT
72 public:
73 
74     UMLDoc();
75     ~UMLDoc();
76 
77     void init();
78 
79     void addView(UMLView *view);
80     void removeView(UMLView *view, bool enforceOneView = true);
81     void setMainViewID(Uml::ID::Type viewID);
82     void changeCurrentView(Uml::ID::Type id);
83     void activateAllViews();
84     void removeAllViews();
85     void removeAllObjects();
86 
87     void setModified(bool modified = true);
88     bool isModified() const;
89     bool saveModified();
90 
91     bool newDocument();
92     void closeDocument();
93 #if QT_VERSION >= 0x050000
94     bool openDocument(const QUrl& url, const char *format = 0);
95     bool saveDocument(const QUrl& url, const char *format = 0);
96     const QUrl& url() const;
97     void setUrl(const QUrl& url);
98 #else
99     bool openDocument(const KUrl& url, const char *format = 0);
100     bool saveDocument(const KUrl& url, const char *format = 0);
101     const KUrl& url() const;
102     void setUrl(const KUrl& url);
103 #endif
104     void setUrlUntitled();
105 
106     void setupSignals();
107 
108     bool isUnique(const QString &name) const;
109     bool isUnique(const QString &name, UMLPackage *package) const;
110 
111     UMLAssociation* createUMLAssociation(UMLObject *a, UMLObject *b, Uml::AssociationType::Enum type);
112 
113     void addAssociation(UMLAssociation *assoc);
114     void removeAssociation(UMLAssociation *assoc, bool doSetModified = true);
115     UMLAssociation * findAssociation(Uml::AssociationType::Enum assocType,
116                                      const UMLObject *roleAObj,
117                                      const UMLObject *roleBObj,
118                                      bool *swap = 0) const;
119 
120     QString createDiagramName(Uml::DiagramType::Enum type, bool askForName = true);
121     UMLView* createDiagram(UMLFolder *folder,
122                            Uml::DiagramType::Enum type,
123                            const QString& name,
124                            Uml::ID::Type id = Uml::ID::None);
125 
126     void removeDiagram(Uml::ID::Type id);
127     void removeDiagramCmd(Uml::ID::Type id);
128     void renameDiagram(Uml::ID::Type id);
129 
130     void removeUMLObject(UMLObject* umlobject, bool deleteObject = false);
131     void renameUMLObject(UMLObject *o);
132     void renameChildUMLObject(UMLObject *o);
133 
134     UMLObject* findObjectById(Uml::ID::Type id);
135 
136     UMLObject* findUMLObject(const QString &name,
137                              UMLObject::ObjectType type = UMLObject::ot_UMLObject,
138                              UMLObject *currentObj = 0);
139 
140     UMLObject* findUMLObjectRaw(Uml::ModelType::Enum,
141                                 const QString &name,
142                                 UMLObject::ObjectType type = UMLObject::ot_UMLObject);
143 
144     UMLObject* findUMLObjectRaw(UMLFolder *folder,
145                                 const QString &name,
146                                 UMLObject::ObjectType type = UMLObject::ot_UMLObject);
147 
148     UMLObject* findUMLObjectRecursive(Uml::ModelType::Enum,
149                                       const QString &name,
150                                       UMLObject::ObjectType type = UMLObject::ot_UMLObject);
151 
152     UMLObject* findUMLObjectRecursive(UMLFolder *folder,
153                                       const QString &name,
154                                       UMLObject::ObjectType type = UMLObject::ot_UMLObject);
155 
156     UMLClassifier * findUMLClassifier(const QString &name);
157 
158     UMLView * findView(Uml::ID::Type id) const;
159     UMLView * findView(Uml::DiagramType::Enum type, const QString &name,
160                        bool searchAllScopes = false) const;
161 
162     void setName(const QString& name);
163     QString name() const;
164 
165     void setResolution(qreal resolution);
166     qreal resolution() const;
167     qreal dpiScale() const;
168 
169     Uml::ID::Type modelID() const;
170 
171     static bool tagEq (const QString& tag, const QString& pattern);
172 
173     virtual void saveToXMI1(QIODevice& file);
174 
175     short encoding(QIODevice & file);
176 
177     virtual bool loadFromXMI1(QIODevice& file, short encode = ENC_UNKNOWN);
178 
179     bool validateXMI1Header(QDomNode& headerNode);
180 
181     bool loadUMLObjectsFromXMI1(QDomElement & element);
182     void loadExtensionsFromXMI1(QDomNode & node);
183     bool loadDiagramsFromXMI1(QDomNode & node);
184 
185     void signalDiagramRenamed(UMLView * view);
186     void signalUMLObjectCreated(UMLObject * o);
187 
188     UMLClassifierList concepts(bool includeNested = true) const;
189     UMLClassifierList classesAndInterfaces(bool includeNested = true) const;
190     UMLEntityList entities(bool includeNested = true) const;
191     UMLFolder * datatypeFolder() const;
192     UMLClassifierList datatypes(bool includeInactive = false) const;
193     UMLAssociationList associations() const;
194     UMLPackageList packages(bool includeNested = true, Uml::ModelType::Enum model = Uml::ModelType::Logical) const;
195 
196     void print(QPrinter * pPrinter, DiagramPrintPage * selectPage);
197 
198     UMLViewList viewIterator() const;
199     UMLViewList views(Uml::DiagramType::Enum type = Uml::DiagramType::Undefined) const;
200 
201     bool assignNewIDs(UMLObject* obj);
202 
203     bool addUMLObject(UMLObject * object);
204     bool addUMLView(UMLView * pView);
205 
206     UMLFolder *rootFolder(Uml::ModelType::Enum mt) const;
207     Uml::ModelType::Enum rootFolderType(UMLObject *obj) const;
208 
209     UMLFolder *currentRoot() const;
210     void setCurrentRoot(Uml::ModelType::Enum rootType);
211 
212     virtual IDChangeLog* changeLog() const;
213 
214     void beginPaste();
215     void endPaste();
216 
217     Uml::ID::Type assignNewID(Uml::ID::Type oldID);
218 
219     void setDocumentation(const QString &doc);
220     QString documentation() const;
221 
222     void settingsChanged(Settings::OptionState &optionState);
223 
224     QString uniqueViewName(const Uml::DiagramType::Enum type) const;
225 
226     bool loading() const;
227     void setLoading(bool state = true);
228 
229     bool importing() const;
230     void setImporting(bool state = true);
231 
232     bool closing() const;
233 
234     void addDefaultDatatypes();
235     void createDatatype(const QString &name);
236     void removeDatatype(const QString &name);
237 
238     UMLStereotype *createStereotype(const QString &name);
239     UMLStereotype *findStereotype(const QString &name) const;
240     UMLStereotype *findOrCreateStereotype(const QString &name);
241     UMLStereotype *findStereotypeById(Uml::ID::Type id) const;
242     void addStereotype(UMLStereotype *s);
243     void removeStereotype(UMLStereotype *s);
244     void addDefaultStereotypes();
245     const UMLStereotypeList& stereotypes() const;
246 
247     void writeToStatusBar(const QString &text);
248 
249     void resolveTypes();
250     bool loadDiagrams1();
251     void addDiagramToLoad(UMLFolder *folder, QDomNode node);
252 
253     DiagramsModel *diagramsModel() const;
254     StereotypesModel *stereotypesModel() const;
255     ObjectsModel *objectsModel() const;
256 
257     void setLoadingError(const QString &text);
258 
259 private:
260     void initSaveTimer();
261     void createDatatypeFolder();
262 
263     class Private;
264     Private *m_d;
265 
266     /**
267      * Array of predefined root folders.
268      */
269     UMLFolder *m_root[Uml::ModelType::N_MODELTYPES];
270 
271     /**
272      * Predefined root folder for datatypes, contained in
273      * m_root[Uml::mt_Logical]
274      */
275     UMLFolder *m_datatypeRoot;
276 
277     /**
278      * The UMLDoc is the sole owner of all stereotypes.
279      * UMLStereotype instances are reference counted.
280      * When a UMLStereotype is no longer referenced anywhere,
281      * its refcount drops to zero. It is then removed from the
282      * m_stereoList and it is physically deleted.
283      */
284     UMLStereotypeList m_stereoList;
285 
286     QString m_Name; ///< name of this model as stored in the <UML:Model> tag
287     Uml::ID::Type m_modelID; ///< xmi.id of this model in the <UML:Model>
288     int m_count;   ///< auxiliary counter for the progress bar
289     bool m_modified;
290 #if QT_VERSION >= 0x050000
291     QUrl m_doc_url;
292 #else
293     KUrl m_doc_url;
294 #endif
295     /**
296      * Contains all the UMLObject id changes of paste session.
297      */
298     IDChangeLog* m_pChangeLog;
299 
300     /**
301      * true if the we're loading a new document
302      */
303     bool m_bLoading;
304 
305     /**
306      * true if the we're importing
307      */
308     bool m_importing;
309 
310     /**
311      * Documentation for the project.
312      */
313     QString m_Doc;
314 
315     /**
316      * Used for autosave
317      */
318     QTimer * m_pAutoSaveTimer;
319 
320     /**
321      * Auxiliary to <docsettings> processing
322      */
323     Uml::ID::Type m_nViewID;
324 
325     /**
326      * True when type resolution pass has been executed.
327      */
328     bool m_bTypesAreResolved;
329 
330     /**
331      * Auxiliary variable for currentRoot():
332      * m_pCurrentRoot is only used if UMLApp::app()->currentView()
333      * returns 0.
334      */
335     UMLFolder * m_pCurrentRoot;
336 
337     /**
338      * True while closeDocument() is executing.
339      */
340     bool m_bClosing;
341 
342     DiagramsModel *m_diagramsModel;
343     ObjectsModel *m_objectsModel;
344     StereotypesModel *m_stereotypesModel;
345 
346     /**
347      * Holds widgets coordinates resolution.
348      * Unit is dpi.
349      */
350     qreal m_resolution;
351 
352     /**
353      * Holds diagram xml nodes on loading
354      */
355     typedef QMap<UMLFolder*, QList<QDomNode>> DiagramsMap;
356     DiagramsMap m_diagramsToLoad;
357 
358 public slots:
359     void slotRemoveUMLObject(UMLObject*o);
360     void slotAutoSave();
361     void slotDiagramPopupMenu(QWidget* umlview, const QPoint& point);
362 
363 signals:
364     void sigDiagramCreated(Uml::ID::Type id);
365     void sigDiagramRemoved(Uml::ID::Type id);
366     void sigDiagramRenamed(Uml::ID::Type t);
367     void sigDiagramChanged(Uml::DiagramType::Enum);
368 
369     void sigObjectCreated(UMLObject *);
370     void sigObjectRemoved(UMLObject *);
371 
372     /**
373      * Reset the status bar.
374      */
375     void sigResetStatusbarProgress();
376 
377     /**
378      * Set the total range of the progressbar.
379      *
380      * @param totalSteps Total range of the progressbar (0..totalSteps)
381      */
382     void sigSetStatusbarProgressSteps(int totalSteps);
383 
384     /**
385      * Set the progress position of the progressbar.
386      *
387      * @param stepPosition   The step position to set.
388      */
389     void sigSetStatusbarProgress(int stepPosition);
390 
391     /**
392      * Write text to the status bar.
393      */
394     void sigWriteToStatusBar(const QString &text);
395 
396     /**
397      * The diagram being displayed has changed.
398      * UMLApp uses this to keep its menu items state up to date.
399      */
400     void sigCurrentViewChanged();
401 
402 };
403 
404 #endif // UMLDOC_H
405