1 /*
2     SPDX-License-Identifier: GPL-2.0-or-later
3     SPDX-FileCopyrightText: 2004-2021 Umbrello UML Modeller Authors <umbrello-devel@kde.org>
4 */
5 
6 // own header
7 #include "model_utils.h"
8 
9 // app includes
10 #include "floatingtextwidget.h"
11 #include "debug_utils.h"
12 #include "umlobject.h"
13 #include "umlpackagelist.h"
14 #include "uniqueconstraint.h"
15 #include "package.h"
16 #include "folder.h"
17 #include "classifier.h"
18 #include "enum.h"
19 #include "instance.h"
20 #include "entity.h"
21 #include "template.h"
22 #include "operation.h"
23 #include "attribute.h"
24 #include "association.h"
25 #include "umlrole.h"
26 #include "umldoc.h"
27 #include "uml.h"
28 #include "umllistview.h"
29 #include "umllistviewitem.h"
30 #include "umlscene.h"
31 #include "umlview.h"
32 #include "codegenerator.h"
33 
34 // kde includes
35 #include <KLocalizedString>
36 
37 // qt includes
38 #include <QRegExp>
39 #include <QStringList>
40 
41 namespace Model_Utils {
42 
43 /**
44  * Determines whether the given widget type is cloneable.
45  *
46  * @param type  The input WidgetType.
47  * @return      True if the given type is cloneable.
48  */
isCloneable(WidgetBase::WidgetType type)49 bool isCloneable(WidgetBase::WidgetType type)
50 {
51     switch (type) {
52     case WidgetBase::wt_Actor:
53     case WidgetBase::wt_UseCase:
54     case WidgetBase::wt_Class:
55     case WidgetBase::wt_Interface:
56     case WidgetBase::wt_Enum:
57     case WidgetBase::wt_Datatype:
58     case WidgetBase::wt_Package:
59     case WidgetBase::wt_Component:
60     case WidgetBase::wt_Port:
61     case WidgetBase::wt_Node:
62     case WidgetBase::wt_Artifact:
63     case WidgetBase::wt_Instance:
64     case WidgetBase::wt_Entity:
65         return true;
66     default:
67         return false;
68     }
69 }
70 
71 /**
72  * Seek the given id in the given list of objects.
73  * Each list element may itself contain other objects
74  * and the search is done recursively.
75  *
76  * @param id       The unique ID to seek.
77  * @param inList   The UMLObjectList in which to search.
78  * @return Pointer to the UMLObject that matches the ID (NULL if none matches).
79  */
findObjectInList(Uml::ID::Type id,const UMLObjectList & inList)80 UMLObject* findObjectInList(Uml::ID::Type id, const UMLObjectList& inList)
81 {
82     for (UMLObjectListIt oit(inList); oit.hasNext();) {
83         UMLObject *obj = oit.next();
84         uIgnoreZeroPointer(obj);
85         if (obj->id() == id)
86             return obj;
87         UMLObject *o;
88         UMLObject::ObjectType t = obj->baseType();
89         switch (t) {
90         case UMLObject::ot_Folder:
91         case UMLObject::ot_Package:
92         case UMLObject::ot_Component:
93             o = obj->asUMLPackage()->findObjectById(id);
94             if (o)
95                 return o;
96             break;
97         case UMLObject::ot_Interface:
98         case UMLObject::ot_Class:
99         case UMLObject::ot_Enum:
100             o = obj->asUMLClassifier()->findChildObjectById(id);
101             if (o == nullptr &&
102                     (t == UMLObject::ot_Interface || t == UMLObject::ot_Class))
103                 o = obj->asUMLPackage()->findObjectById(id);
104             if (o)
105                 return o;
106             break;
107         case UMLObject::ot_Instance:
108             o = obj->asUMLInstance()->findChildObjectById(id);
109             if (o)
110                 return o;
111             break;
112         case UMLObject::ot_Entity:
113             o = obj->asUMLEntity()->findChildObjectById(id);
114             if (o)
115                 return o;
116             o = obj->asUMLPackage()->findObjectById(id);
117             if (o)
118                 return o;
119             break;
120         case UMLObject::ot_Association:
121             {
122                 UMLAssociation *assoc = obj->asUMLAssociation();
123                 UMLRole *rA = assoc->getUMLRole(Uml::RoleType::A);
124                 if (rA->id() == id)
125                     return rA;
126                 UMLRole *rB = assoc->getUMLRole(Uml::RoleType::B);
127                 if (rB->id() == id)
128                     return rB;
129             }
130             break;
131         default:
132             break;
133         }
134     }
135     return 0;
136 }
137 
138 /**
139  * Find the UML object of the given type and name in the passed-in list.
140  *
141  * @param inList        List in which to seek the object.
142  * @param inName        Name of the object to find.
143  * @param type          ObjectType of the object to find (optional.)
144  *                      When the given type is ot_UMLObject the type is
145  *                      disregarded, i.e. the given name is the only
146  *                      search criterion.
147  * @param currentObj    Object relative to which to search (optional.)
148  *                      If given then the enclosing scope(s) of this
149  *                      object are searched before the global scope.
150  * @return      Pointer to the UMLObject found, or NULL if not found.
151  */
findUMLObject(const UMLObjectList & inList,const QString & inName,UMLObject::ObjectType type,UMLObject * currentObj)152 UMLObject* findUMLObject(const UMLObjectList& inList,
153                          const QString& inName,
154                          UMLObject::ObjectType type /* = ot_UMLObject */,
155                          UMLObject *currentObj /* = 0 */)
156 {
157     const bool caseSensitive = UMLApp::app()->activeLanguageIsCaseSensitive();
158     QString name = inName;
159     const bool atGlobalScope = name.startsWith(QLatin1String("::"));
160     if (atGlobalScope) {
161         name = name.mid(2);
162         currentObj = 0;
163     }
164     QStringList components;
165 #ifdef TRY_BUGFIX_120682
166     // If we have a pointer or a reference in cpp we need to remove
167     // the asterisks and ampersands in order to find the appropriate object
168     if (UMLApp::app()->getActiveLanguage() == Uml::pl_Cpp) {
169         if (name.endsWith(QLatin1Char('*')))
170             name.remove(QLatin1Char('*'));
171         else if (name.contains(QLatin1Char('&')))
172             name.remove(QLatin1Char('&'));
173     }
174 #endif
175     QString scopeSeparator = UMLApp::app()->activeLanguageScopeSeparator();
176     if (name.contains(scopeSeparator))
177         components = name.split(scopeSeparator);
178     QString nameWithoutFirstPrefix;
179     if (components.size() > 1) {
180         name = components.front();
181         components.pop_front();
182         nameWithoutFirstPrefix = components.join(scopeSeparator);
183     }
184     if (currentObj) {
185         UMLPackage *pkg = 0;
186         if (currentObj->asUMLClassifierListItem()) {
187             currentObj = currentObj->umlParent();
188         }
189         pkg = currentObj->asUMLPackage();
190         if (pkg == 0 || pkg->baseType() == UMLObject::ot_Association)
191             pkg = currentObj->umlPackage();
192         // Remember packages that we've seen - for avoiding cycles.
193         UMLPackageList seenPkgs;
194         for (; pkg; pkg = currentObj->umlPackage()) {
195             if (nameWithoutFirstPrefix.isEmpty()
196                 && (type == UMLObject::ot_UMLObject ||
197                     type == UMLObject::ot_Folder ||
198                     type == UMLObject::ot_Package || type == pkg->baseType())) {
199                 if (caseSensitive) {
200                     if (pkg->name() == name)
201                         return pkg;
202                 } else if (pkg->name().toLower() == name.toLower()) {
203                     return pkg;
204                 }
205             }
206             if (seenPkgs.indexOf(pkg) != -1) {
207                 uError() << "findUMLObject(" << name << "): "
208                     << "breaking out of cycle involving "
209                     << pkg->name();
210                 break;
211             }
212             seenPkgs.append(pkg);
213 
214             // exclude non package type
215             // pg->asUMLPackage() fails for unknown reason
216             // see https://bugs.kde.org/show_bug.cgi?id=341709
217             UMLObject::ObjectType foundType = pkg->baseType();
218             if (foundType != UMLObject::ot_Package &&
219                 foundType != UMLObject::ot_Folder &&
220                 foundType != UMLObject::ot_Class &&
221                 foundType != UMLObject::ot_Interface &&
222                 foundType != UMLObject::ot_Component) {
223                 continue;
224             }
225             UMLObjectList objectsInCurrentScope = pkg->containedObjects();
226             for (UMLObjectListIt oit(objectsInCurrentScope); oit.hasNext();) {
227                 UMLObject *obj = oit.next();
228                 uIgnoreZeroPointer(obj);
229                 if (caseSensitive) {
230                     if (obj->name() != name)
231                         continue;
232                 } else if (obj->name().toLower() != name.toLower()) {
233                     continue;
234                 }
235                 UMLObject::ObjectType foundType = obj->baseType();
236                 if (nameWithoutFirstPrefix.isEmpty()) {
237                     if (type != UMLObject::ot_UMLObject && type != foundType) {
238                         uDebug() << "type mismatch for "
239                             << name << " (seeking type: "
240                             << UMLObject::toString(type) << ", found type: "
241                             << UMLObject::toString(foundType) << ")";
242                         // Class, Interface, and Datatype are all Classifiers
243                         // and are considered equivalent.
244                         // The caller must be prepared to handle possible mismatches.
245                         if ((type == UMLObject::ot_Class ||
246                              type == UMLObject::ot_Interface ||
247                              type == UMLObject::ot_Datatype) &&
248                             (foundType == UMLObject::ot_Class ||
249                              foundType == UMLObject::ot_Interface ||
250                              foundType == UMLObject::ot_Datatype)) {
251                             return obj;
252                         }
253                         // Code import may set <<class-or-package>> stereotype
254                         if ((type == UMLObject::ot_Package || type == UMLObject::ot_Class)
255                             && obj->stereotype() == QLatin1String("class-or-package")) {
256                             return obj;
257                         }
258                         continue;
259                     }
260                     return obj;
261                 }
262                 if (foundType != UMLObject::ot_Package &&
263                     foundType != UMLObject::ot_Folder &&
264                     foundType != UMLObject::ot_Class &&
265                     foundType != UMLObject::ot_Interface &&
266                     foundType != UMLObject::ot_Component) {
267                     uDebug() << "found " << UMLObject::toString(foundType) << name
268                              << " is not a package (?)";
269                     continue;
270                 }
271                 UMLPackage *pkg = obj->asUMLPackage();
272                 return findUMLObject(pkg->containedObjects(),
273                                       nameWithoutFirstPrefix, type);
274             }
275             currentObj = pkg;
276         }
277     }
278     for (UMLObjectListIt oit(inList); oit.hasNext();) {
279         UMLObject *obj = oit.next();
280         uIgnoreZeroPointer(obj);
281         if (caseSensitive) {
282             if (obj->name() != name)
283                 continue;
284         } else if (obj->name().toLower() != name.toLower()) {
285             continue;
286         }
287         UMLObject::ObjectType foundType = obj->baseType();
288         if (nameWithoutFirstPrefix.isEmpty()) {
289             if (type != UMLObject::ot_UMLObject && type != foundType) {
290                 // Code import may set <<class-or-package>> stereotype
291                 if ((type == UMLObject::ot_Package || type == UMLObject::ot_Class)
292                     && obj->stereotype() == QLatin1String("class-or-package")) {
293                     return obj;
294                 }
295                 uDebug() << "type mismatch for "
296                     << name << " (seeking type: "
297                     << UMLObject::toString(type) << ", found type: "
298                     << UMLObject::toString(foundType) << ")";
299                 continue;
300             }
301             return obj;
302         }
303         if (foundType != UMLObject::ot_Package &&
304             foundType != UMLObject::ot_Folder &&
305             foundType != UMLObject::ot_Class &&
306             foundType != UMLObject::ot_Interface &&
307             foundType != UMLObject::ot_Component) {
308             uDebug() << "found " << name << "(" << UMLObject::toString(foundType) << ")"
309                      << " is not a package (?)";
310             continue;
311         }
312         UMLPackage *pkg = obj->asUMLPackage();
313         return findUMLObject(pkg->containedObjects(),
314                               nameWithoutFirstPrefix, type);
315     }
316     return 0;
317 }
318 
319 /**
320  * Find the UML object of the given type and name in the passed-in list.
321  * This method searches for the raw name.
322  *
323  * @param inList        List in which to seek the object.
324  * @param name          Name of the object to find.
325  * @param type          ObjectType of the object to find (optional.)
326  *                      When the given type is ot_UMLObject the type is
327  *                      disregarded, i.e. the given name is the only
328  *                      search criterion.
329  * @param currentObj    Object relative to which to search (optional.)
330  *                      If given then the enclosing scope(s) of this
331  *                      object are searched before the global scope.
332  * @return      Pointer to the UMLObject found, or NULL if not found.
333  */
findUMLObjectRaw(const UMLObjectList & inList,const QString & name,UMLObject::ObjectType type,UMLObject * currentObj)334 UMLObject* findUMLObjectRaw(const UMLObjectList& inList,
335                             const QString& name,
336                             UMLObject::ObjectType type /* = ot_UMLObject */,
337                             UMLObject *currentObj /*= 0*/)
338 {
339     Q_UNUSED(currentObj);
340     for (UMLObjectListIt oit(inList); oit.hasNext();) {
341         UMLObject *obj = oit.next();
342         if (obj->name() == name && type == obj->baseType())
343             return obj;
344     }
345     return 0;
346 }
347 
348 /**
349  * Find the UML object of the given type and name in the passed-in list.
350  * This method searches for the raw name.
351  *
352  * @param inList        List in which to seek the object.
353  * @param name          Name of the object to find.
354  * @param type          ObjectType of the object to find (optional.)
355  *                      When the given type is ot_UMLObject the type is
356  *                      disregarded, i.e. the given name is the only
357  *                      search criterion.
358  * @return      Pointer to the UMLObject found, or NULL if not found.
359  */
findUMLObjectRecursive(const UMLObjectList & inList,const QString & name,UMLObject::ObjectType type)360 UMLObject* findUMLObjectRecursive(const UMLObjectList& inList,
361                                   const QString& name,
362                                   UMLObject::ObjectType type /* = ot_UMLObject */)
363 {
364     foreach(UMLObject *obj, inList) {
365         if (obj->name() == name && type == obj->baseType())
366             return obj;
367         UMLPackage *pkg = obj->asUMLPackage();
368         if (pkg && pkg->containedObjects().size() > 0) {
369             UMLObject *o = findUMLObjectRecursive(pkg->containedObjects(), name, type);
370             if (o)
371                 return o;
372         }
373     }
374     return 0;
375 }
376 
377 /**
378  * Get the root folder of the given UMLObject.
379  */
rootPackage(UMLObject * obj)380 UMLPackage* rootPackage(UMLObject* obj)
381 {
382     if (obj == 0)
383         return 0;
384     UMLPackage* root = obj->umlPackage();
385     if (root == 0) {
386         root = obj->asUMLPackage();
387     } else {
388         while (root->umlPackage() != 0) {
389             root = root->umlPackage();
390         }
391     }
392     return root;
393 }
394 
395 /**
396  * Add the given list of views to the tree view.
397  * @param viewList   the list of views to add
398  */
treeViewAddViews(const UMLViewList & viewList)399 void treeViewAddViews(const UMLViewList& viewList)
400 {
401     UMLListView* tree = UMLApp::app()->listView();
402     foreach (UMLView* v,  viewList) {
403         if (tree->findItem(v->umlScene()->ID()) != 0) {
404             continue;
405         }
406         tree->createDiagramItem(v);
407     }
408 }
409 
410 /**
411  * Change an icon of an object in the tree view.
412  * @param object   the object in the treeViewAddViews
413  * @param to       the new icon type for the given object
414  */
treeViewChangeIcon(UMLObject * object,Icon_Utils::IconType to)415 void treeViewChangeIcon(UMLObject* object, Icon_Utils::IconType to)
416 {
417     UMLListView* tree = UMLApp::app()->listView();
418     tree->changeIconOf(object, to);
419 }
420 
421 /**
422  * Set the given object to the current item in the tree view.
423  * @param object   the object which will be the current item
424  */
treeViewSetCurrentItem(UMLObject * object)425 void treeViewSetCurrentItem(UMLObject* object)
426 {
427     UMLListView* tree = UMLApp::app()->listView();
428     UMLListViewItem* item = tree->findUMLObject(object);
429     tree->setCurrentItem(item);
430 }
431 
432 /**
433  * Move an object to a new container in the tree view.
434  * @param container   the new container for the object
435  * @param object      the to be moved object
436  */
treeViewMoveObjectTo(UMLObject * container,UMLObject * object)437 void treeViewMoveObjectTo(UMLObject* container, UMLObject* object)
438 {
439     UMLListView *listView = UMLApp::app()->listView();
440     UMLListViewItem *newParent = listView->findUMLObject(container);
441     listView->moveObject(object->id(),
442                    Model_Utils::convert_OT_LVT(object),
443                    newParent);
444 }
445 
446 /**
447  * Return the current UMLObject from the tree view.
448  * @return   the UML object of the current item
449  */
treeViewGetCurrentObject()450 UMLObject* treeViewGetCurrentObject()
451 {
452     UMLListView *listView = UMLApp::app()->listView();
453     UMLListViewItem *current = static_cast<UMLListViewItem*>(listView->currentItem());
454     return current->umlObject();
455 }
456 
457 /**
458  * Return the UMLPackage if the current item
459  * in the tree view is a package. Return the
460  * closest package in the tree view or NULL otherwise
461  *
462  * @return   the package or NULL
463  */
treeViewGetPackageFromCurrent()464 UMLPackage* treeViewGetPackageFromCurrent()
465 {
466     UMLListView *listView = UMLApp::app()->listView();
467     UMLListViewItem *parentItem = (UMLListViewItem*)listView->currentItem();
468     while (parentItem) {
469         UMLListViewItem::ListViewType lvt = parentItem->type();
470         if (Model_Utils::typeIsContainer(lvt)) {
471             UMLObject *o = parentItem->umlObject();
472             return o->asUMLPackage();
473         }
474 
475         // selected item is not a container, try to find the
476         // container higher up in the tree view
477         parentItem = static_cast<UMLListViewItem*>(parentItem->parent());
478     }
479 
480     return 0;
481 }
482 
483 /**
484  * Build the diagram name from the tree view.
485 
486  * The function returns a relative path constructed from the folder hierarchy.
487  * @param id   the id of the diaram
488  * @return     the constructed diagram name
489  */
treeViewBuildDiagramName(Uml::ID::Type id)490 QString treeViewBuildDiagramName(Uml::ID::Type id)
491 {
492     UMLListView *listView = UMLApp::app()->listView();
493     UMLListViewItem* listViewItem = listView->findItem(id);
494 
495     if (listViewItem) {
496         QString name = listViewItem->text(0);
497         listViewItem = static_cast<UMLListViewItem*>(listViewItem->parent());
498 
499         // Relies on the tree structure of the UMLListView. There are a base "Views" folder
500         // and five children, one for each view type (Logical, use case, components, deployment
501         // and entity relationship)
502         while (listView->rootView(listViewItem->type()) == 0) {
503             name.insert(0, listViewItem->text(0) + QLatin1Char('/'));
504             listViewItem = static_cast<UMLListViewItem*>(listViewItem->parent());
505             if (listViewItem == 0)
506                 break;
507         }
508         return name;
509     }
510     else {
511         uWarning() << "diagram not found - returning empty name!";
512         return QString();
513     }
514 }
515 
516 /**
517  * Returns a name for the new object, appended with a number
518  * if the default name is taken e.g. new_actor, new_actor_1
519  * etc.
520  * @param type      The object type.
521  * @param parentPkg The package in which to compare the name.
522  * @param prefix    The prefix to use (optional)
523  *                  If no prefix is given then a type related
524  *                  prefix will be chosen internally.
525  */
uniqObjectName(UMLObject::ObjectType type,UMLPackage * parentPkg,QString prefix)526 QString uniqObjectName(UMLObject::ObjectType type, UMLPackage *parentPkg, QString prefix)
527 {
528     QString currentName = prefix;
529     if (currentName.isEmpty()) {
530         switch(type) {
531         case UMLObject::ot_Actor:               currentName = i18n("new_actor");                  break;
532         case UMLObject::ot_Artifact:            currentName = i18n("new_artifact");               break;
533         case UMLObject::ot_Association:         currentName = i18n("new_association");            break;
534         case UMLObject::ot_Attribute:           currentName = i18n("new_attribute");              break;
535         case UMLObject::ot_Category:            currentName = i18n("new_category");               break;
536         case UMLObject::ot_CheckConstraint:     currentName = i18n("new_check_constraint");       break;
537         case UMLObject::ot_Class:               currentName = i18n("new_class");                  break;
538         case UMLObject::ot_Component:           currentName = i18n("new_component");              break;
539         case UMLObject::ot_Datatype:            currentName = i18n("new_datatype");               break;
540         case UMLObject::ot_Entity:              currentName = i18n("new_entity");                 break;
541         case UMLObject::ot_EntityAttribute:     currentName = i18n("new_entity_attribute");       break;
542         case UMLObject::ot_EntityConstraint:    currentName = i18n("new_entity_constraint");      break;
543         case UMLObject::ot_Enum:                currentName = i18n("new_enum");                   break;
544         case UMLObject::ot_EnumLiteral:         currentName = i18n("new_enum_literal");           break;
545         case UMLObject::ot_Folder:              currentName = i18n("new_folder");                 break;
546         case UMLObject::ot_ForeignKeyConstraint:currentName = i18n("new_foreign_key_constraint"); break;
547         case UMLObject::ot_Instance:            currentName = i18n("new_instance");               break;
548         case UMLObject::ot_InstanceAttribute:   currentName = i18n("new_instance_attribute");     break;
549         case UMLObject::ot_Interface:           currentName = i18n("new_interface");              break;
550         case UMLObject::ot_Node:                currentName = i18n("new_node");                   break;
551         case UMLObject::ot_Operation:           currentName = i18n("new_operation");              break;
552         case UMLObject::ot_Package:             currentName = i18n("new_package");                break;
553         case UMLObject::ot_Port:                currentName = i18n("new_port");                   break;
554         case UMLObject::ot_Role:                currentName = i18n("new_role");                   break;
555         case UMLObject::ot_Stereotype:          currentName = i18n("new_stereotype");             break;
556         case UMLObject::ot_Template:            currentName = i18n("new_template");               break;
557         case UMLObject::ot_UniqueConstraint:    currentName = i18n("new_unique_constraint");      break;
558         case UMLObject::ot_UseCase:             currentName = i18n("new_use case");               break;
559         default:
560             currentName = i18n("new_object");
561             uWarning() << "model_utils::uniqObjectName unknown object type" << UMLObject::toString(type);
562         }
563     }
564     UMLDoc *doc = UMLApp::app()->document();
565     QString name = currentName;
566     for (int number = 1; !doc->isUnique(name, parentPkg); ++number)  {
567         name = currentName + QLatin1Char('_') + QString::number(number);
568     }
569     return name;
570 }
571 
572 /**
573  * Returns translated title string used by uml object related dialogs
574  * @param type uml object type
575  * @return translated title string
576  */
newTitle(UMLObject::ObjectType type)577 QString newTitle(UMLObject::ObjectType type)
578 {
579     switch(type) {
580     case UMLObject::ot_Actor:               return i18n("New actor");
581     case UMLObject::ot_Artifact:            return i18n("New artifact");
582     case UMLObject::ot_Association:         return i18n("New association");
583     case UMLObject::ot_Attribute:           return i18n("New attribute");
584     case UMLObject::ot_Category:            return i18n("New category");
585     case UMLObject::ot_CheckConstraint:     return i18n("New check constraint");
586     case UMLObject::ot_Class:               return i18n("New class");
587     case UMLObject::ot_Component:           return i18n("New component");
588     case UMLObject::ot_Datatype:            return i18n("New datatype");
589     case UMLObject::ot_Entity:              return i18n("New entity");
590     case UMLObject::ot_EntityAttribute:     return i18n("New entity attribute");
591     case UMLObject::ot_EntityConstraint:    return i18n("New entity constraint");
592     case UMLObject::ot_Enum:                return i18n("New enum");
593     case UMLObject::ot_EnumLiteral:         return i18n("New enum literal");
594     case UMLObject::ot_Folder:              return i18n("New folder");
595     case UMLObject::ot_ForeignKeyConstraint:return i18n("New foreign key constraint");
596     case UMLObject::ot_Instance:            return i18n("New instance");
597     case UMLObject::ot_InstanceAttribute:   return i18n("New instance attribute");
598     case UMLObject::ot_Interface:           return i18n("New interface");
599     case UMLObject::ot_Node:                return i18n("New node");
600     case UMLObject::ot_Operation:           return i18n("New operation");
601     case UMLObject::ot_Package:             return i18n("New package");
602     case UMLObject::ot_Port:                return i18n("New port");
603     case UMLObject::ot_Role:                return i18n("New role");
604     case UMLObject::ot_Stereotype:          return i18n("New stereotype");
605     case UMLObject::ot_Template:            return i18n("New template");
606     case UMLObject::ot_UniqueConstraint:    return i18n("New unique constraint");
607     case UMLObject::ot_UseCase:             return i18n("New use case");
608     default:
609         uWarning() << "model_utils::newTitle unknown object type" << UMLObject::toString(type);
610         return i18n("New UML object");
611     }
612 }
613 
614 /**
615  * Returns translated text string used by uml object related dialogs
616  * @param type uml object type
617  * @return translated text string
618  */
newText(UMLObject::ObjectType type)619 QString newText(UMLObject::ObjectType type)
620 {
621     switch(type) {
622     case UMLObject::ot_Actor:               return i18n("Enter the name of the new actor:");
623     case UMLObject::ot_Artifact:            return i18n("Enter the name of the new artifact:");
624     case UMLObject::ot_Association:         return i18n("Enter the name of the new association:");
625     case UMLObject::ot_Attribute:           return i18n("Enter the name of the new attribute:");
626     case UMLObject::ot_Category:            return i18n("Enter the name of the new category:");
627     case UMLObject::ot_CheckConstraint:     return i18n("Enter the name of the new check constraint:");
628     case UMLObject::ot_Class:               return i18n("Enter the name of the new class:");
629     case UMLObject::ot_Component:           return i18n("Enter the name of the new component:");
630     case UMLObject::ot_Datatype:            return i18n("Enter the name of the new datatype:");
631     case UMLObject::ot_Entity:              return i18n("Enter the name of the new entity:");
632     case UMLObject::ot_EntityAttribute:     return i18n("Enter the name of the new entity attribute:");
633     case UMLObject::ot_EntityConstraint:    return i18n("Enter the name of the new entity constraint:");
634     case UMLObject::ot_Enum:                return i18n("Enter the name of the new enum:");
635     case UMLObject::ot_EnumLiteral:         return i18n("Enter the name of the new enum literal:");
636     case UMLObject::ot_Folder:              return i18n("Enter the name of the new folder:");
637     case UMLObject::ot_ForeignKeyConstraint:return i18n("Enter the name of the new foreign key constraint:");
638     case UMLObject::ot_Instance:            return i18n("Enter the name of the new instance:");
639     case UMLObject::ot_InstanceAttribute:   return i18n("Enter the name of the new instance attribute:");
640     case UMLObject::ot_Interface:           return i18n("Enter the name of the new interface:");
641     case UMLObject::ot_Node:                return i18n("Enter the name of the new node:");
642     case UMLObject::ot_Operation:           return i18n("Enter the name of the new operation:");
643     case UMLObject::ot_Package:             return i18n("Enter the name of the new package:");
644     case UMLObject::ot_Port:                return i18n("Enter the name of the new port:");
645     case UMLObject::ot_Role:                return i18n("Enter the name of the new role:");
646     case UMLObject::ot_Stereotype:          return i18n("Enter the name of the new stereotype:");
647     case UMLObject::ot_Template:            return i18n("Enter the name of the new template:");
648     case UMLObject::ot_UniqueConstraint:    return i18n("Enter the name of the new unique constraint:");
649     case UMLObject::ot_UseCase:             return i18n("Enter the name of the new use case:");
650     default:
651         uWarning() << "model_utils::newText unknown object type" << UMLObject::toString(type);
652         return i18n("Enter the name of the new UML object");
653     }
654 }
655 
656 /**
657  * Returns translated title string used by uml object related dialogs
658  * @param type uml object type
659  * @return translated title string
660  */
renameTitle(UMLObject::ObjectType type)661 QString renameTitle(UMLObject::ObjectType type)
662 {
663     switch(type) {
664     case UMLObject::ot_Actor:               return i18n("Rename actor");
665     case UMLObject::ot_Artifact:            return i18n("Rename artifact");
666     case UMLObject::ot_Association:         return i18n("Rename association");
667     case UMLObject::ot_Attribute:           return i18n("Rename attribute");
668     case UMLObject::ot_Category:            return i18n("Rename category");
669     case UMLObject::ot_CheckConstraint:     return i18n("Rename check constraint");
670     case UMLObject::ot_Class:               return i18n("Rename class");
671     case UMLObject::ot_Component:           return i18n("Rename component");
672     case UMLObject::ot_Datatype:            return i18n("Rename datatype");
673     case UMLObject::ot_Entity:              return i18n("Rename entity");
674     case UMLObject::ot_EntityAttribute:     return i18n("Rename entity attribute");
675     case UMLObject::ot_EntityConstraint:    return i18n("Rename entity constraint");
676     case UMLObject::ot_Enum:                return i18n("Rename enum");
677     case UMLObject::ot_EnumLiteral:         return i18n("Rename enum literal");
678     case UMLObject::ot_Folder:              return i18n("Rename folder");
679     case UMLObject::ot_ForeignKeyConstraint:return i18n("Rename foreign key constraint");
680     case UMLObject::ot_Instance:            return i18n("Rename instance");
681     case UMLObject::ot_InstanceAttribute:   return i18n("Rename instance attribute");
682     case UMLObject::ot_Interface:           return i18n("Rename interface");
683     case UMLObject::ot_Node:                return i18n("Rename node");
684     case UMLObject::ot_Operation:           return i18n("Rename operation");
685     case UMLObject::ot_Package:             return i18n("Rename package");
686     case UMLObject::ot_Port:                return i18n("Rename port");
687     case UMLObject::ot_Role:                return i18n("Rename role");
688     case UMLObject::ot_Stereotype:          return i18n("Rename stereotype");
689     case UMLObject::ot_Template:            return i18n("Rename template");
690     case UMLObject::ot_UniqueConstraint:    return i18n("Rename unique constraint");
691     case UMLObject::ot_UseCase:             return i18n("Rename use case");
692     default:
693         uWarning() << "model_utils::renameTitle unknown object type" << UMLObject::toString(type);
694         return i18n("Rename UML object");
695     }
696 }
697 
698 /**
699  * Returns translated text string used by uml object related dialogs
700  * @param type uml object type
701  * @return translated text string
702  */
renameText(UMLObject::ObjectType type)703 QString renameText(UMLObject::ObjectType type)
704 {
705     switch(type) {
706     case UMLObject::ot_Actor:               return i18n("Enter the new name of the actor:");
707     case UMLObject::ot_Artifact:            return i18n("Enter the new name of the artifact:");
708     case UMLObject::ot_Association:         return i18n("Enter the new name of the association:");
709     case UMLObject::ot_Attribute:           return i18n("Enter the new name of the attribute:");
710     case UMLObject::ot_Category:            return i18n("Enter the new name of the category:");
711     case UMLObject::ot_CheckConstraint:     return i18n("Enter the new name of the check constraint:");
712     case UMLObject::ot_Class:               return i18n("Enter the new name of the class:");
713     case UMLObject::ot_Component:           return i18n("Enter the new name of the component:");
714     case UMLObject::ot_Datatype:            return i18n("Enter the new name of the datatype:");
715     case UMLObject::ot_Entity:              return i18n("Enter the new name of the entity:");
716     case UMLObject::ot_EntityAttribute:     return i18n("Enter the new name of the entity attribute:");
717     case UMLObject::ot_EntityConstraint:    return i18n("Enter the new name of the entity constraint:");
718     case UMLObject::ot_Enum:                return i18n("Enter the new name of the enum:");
719     case UMLObject::ot_EnumLiteral:         return i18n("Enter the new name of the enum literal:");
720     case UMLObject::ot_Folder:              return i18n("Enter the new name of the folder:");
721     case UMLObject::ot_ForeignKeyConstraint:return i18n("Enter the new name of the foreign key constraint:");
722     case UMLObject::ot_Instance:            return i18n("Enter the new name of the instance:");
723     case UMLObject::ot_InstanceAttribute:   return i18n("Enter the new name of the instance attribute:");
724     case UMLObject::ot_Interface:           return i18n("Enter the new name of the interface:");
725     case UMLObject::ot_Node:                return i18n("Enter the new name of the node:");
726     case UMLObject::ot_Operation:           return i18n("Enter the new name of the operation:");
727     case UMLObject::ot_Package:             return i18n("Enter the new name of the package:");
728     case UMLObject::ot_Port:                return i18n("Enter the new name of the port:");
729     case UMLObject::ot_Role:                return i18n("Enter the new name of the role:");
730     case UMLObject::ot_Stereotype:          return i18n("Enter the new name of the stereotype:");
731     case UMLObject::ot_Template:            return i18n("Enter the new name of the template:");
732     case UMLObject::ot_UniqueConstraint:    return i18n("Enter the new name of the unique constraint:");
733     case UMLObject::ot_UseCase:             return i18n("Enter the new name of the use case:");
734     default:
735         uWarning() << "model_utils::renameText unknown object type" << UMLObject::toString(type);
736         return i18n("Enter the new name of the UML object");
737     }
738 }
739 
740 /**
741  * Return the xmi.id (XMI-1) or xmi:id (XMI-2) of a QDomElement.
742  */
getXmiId(QDomElement element)743 QString getXmiId(QDomElement element)
744 {
745     QString idStr = element.attribute(QLatin1String("xmi.id"));
746     if (idStr.isEmpty())
747         idStr = element.attribute(QLatin1String("xmi:id"));
748     return idStr;
749 }
750 
751 /**
752  * Return true if the given tag is one of the common XMI
753  * attributes, such as:
754  * "name" | "visibility" | "isRoot" | "isLeaf" | "isAbstract" |
755  * "isActive" | "ownerScope"
756  */
isCommonXMI1Attribute(const QString & tag)757 bool isCommonXMI1Attribute(const QString &tag)
758 {
759     bool retval = (UMLDoc::tagEq(tag, QLatin1String("name")) ||
760                    UMLDoc::tagEq(tag, QLatin1String("visibility")) ||
761                    UMLDoc::tagEq(tag, QLatin1String("isRoot")) ||
762                    UMLDoc::tagEq(tag, QLatin1String("isLeaf")) ||
763                    UMLDoc::tagEq(tag, QLatin1String("isAbstract")) ||
764                    UMLDoc::tagEq(tag, QLatin1String("isSpecification")) ||
765                    UMLDoc::tagEq(tag, QLatin1String("isActive")) ||
766                    UMLDoc::tagEq(tag, QLatin1String("namespace")) ||
767                    UMLDoc::tagEq(tag, QLatin1String("ownerScope")) ||
768                    UMLDoc::tagEq(tag, QLatin1String("ModelElement.stereotype")) ||
769                    UMLDoc::tagEq(tag, QLatin1String("GeneralizableElement.generalization")) ||
770                    UMLDoc::tagEq(tag, QLatin1String("specialization")) ||   //NYI
771                    UMLDoc::tagEq(tag, QLatin1String("clientDependency")) || //NYI
772                    UMLDoc::tagEq(tag, QLatin1String("supplierDependency"))  //NYI
773                  );
774     return retval;
775 }
776 
777 /**
778  * Return true if the given type is common among the majority
779  * of programming languages, such as "bool" or "boolean".
780  * TODO: Make this depend on the active programming language.
781  */
isCommonDataType(QString type)782 bool isCommonDataType(QString type)
783 {
784     CodeGenerator *gen = UMLApp::app()->generator();
785     if (gen == 0)
786         return true;   // gen == NULL means we use UMLPrimitiveTypes
787     const bool caseSensitive = UMLApp::app()->activeLanguageIsCaseSensitive();
788     const QStringList dataTypes = gen->defaultDatatypes();
789     QStringList::ConstIterator end(dataTypes.end());
790     for (QStringList::ConstIterator it = dataTypes.begin(); it != end; ++it) {
791         if (caseSensitive) {
792             if (type == *it)
793                 return true;
794         } else if (type.toLower() == (*it).toLower()) {
795             return true;
796         }
797     }
798     return false;
799 }
800 
801 /**
802  * Return true if the given object type is a classifier list item type.
803  */
isClassifierListitem(UMLObject::ObjectType type)804 bool isClassifierListitem(UMLObject::ObjectType type)
805 {
806     if (type == UMLObject::ot_Attribute ||
807         type == UMLObject::ot_Operation ||
808         type == UMLObject::ot_Template ||
809         type == UMLObject::ot_EntityAttribute ||
810         type == UMLObject::ot_EnumLiteral ||
811         type == UMLObject::ot_UniqueConstraint ||
812         type == UMLObject::ot_ForeignKeyConstraint  ||
813         type == UMLObject::ot_CheckConstraint) {
814         // UMLObject::ot_InstanceAttribute needs to be handled separately
815         // because UMLInstanceAttribute is not a UMLClassifierListItem.
816         return true;
817     } else {
818         return false;
819     }
820 }
821 
822 /**
823  * Try to guess the correct container folder type of a UMLObject.
824  * Object types that can't be guessed are mapped to Uml::ModelType::Logical.
825  * NOTE: This function exists mainly for handling pre-1.5.5 files
826  *       and should not be used for new code.
827  */
guessContainer(UMLObject * o)828 Uml::ModelType::Enum guessContainer(UMLObject *o)
829 {
830     UMLObject::ObjectType ot = o->baseType();
831     if (ot == UMLObject::ot_Package && o->stereotype() == QLatin1String("subsystem"))
832         return Uml::ModelType::Component;
833     Uml::ModelType::Enum mt = Uml::ModelType::N_MODELTYPES;
834     switch (ot) {
835         case UMLObject::ot_Package:   // trouble: package can also appear in Component view
836         case UMLObject::ot_Interface:
837         case UMLObject::ot_Datatype:
838         case UMLObject::ot_Enum:
839         case UMLObject::ot_Class:
840         case UMLObject::ot_Attribute:
841         case UMLObject::ot_Operation:
842         case UMLObject::ot_EnumLiteral:
843         case UMLObject::ot_Template:
844         case UMLObject::ot_Instance:
845         case UMLObject::ot_InstanceAttribute:
846             mt = Uml::ModelType::Logical;
847             break;
848         case UMLObject::ot_Actor:
849         case UMLObject::ot_UseCase:
850             mt = Uml::ModelType::UseCase;
851             break;
852         case UMLObject::ot_Component:
853         case UMLObject::ot_Port:
854         case UMLObject::ot_Artifact:  // trouble: artifact can also appear at Deployment
855             mt = Uml::ModelType::Component;
856             break;
857         case UMLObject::ot_Node:
858             mt = Uml::ModelType::Deployment;
859             break;
860         case UMLObject::ot_Entity:
861         case UMLObject::ot_EntityAttribute:
862         case UMLObject::ot_UniqueConstraint:
863         case UMLObject::ot_ForeignKeyConstraint:
864         case UMLObject::ot_CheckConstraint:
865         case UMLObject::ot_Category:
866             mt = Uml::ModelType::EntityRelationship;
867             break;
868         case UMLObject::ot_Association:
869             {
870                 UMLAssociation *assoc = o->asUMLAssociation();
871                 UMLDoc *umldoc = UMLApp::app()->document();
872                 for (int r = Uml::RoleType::A; r <= Uml::RoleType::B; ++r) {
873                     UMLObject *roleObj = assoc->getObject(Uml::RoleType::fromInt(r));
874                     if (roleObj == 0) {
875                         // Ouch! we have been called while types are not yet resolved
876                         return Uml::ModelType::N_MODELTYPES;
877                     }
878                     UMLPackage *pkg = roleObj->umlPackage();
879                     if (pkg) {
880                         while (pkg->umlPackage()) {  // wind back to root
881                             pkg = pkg->umlPackage();
882                         }
883                         const Uml::ModelType::Enum m = umldoc->rootFolderType(pkg);
884                         if (m != Uml::ModelType::N_MODELTYPES)
885                             return m;
886                     }
887                     mt = guessContainer(roleObj);
888                     if (mt != Uml::ModelType::Logical)
889                         break;
890                 }
891             }
892             break;
893         default:
894             break;
895     }
896     return mt;
897 }
898 
899 /**
900  * Parse a direction string into the Uml::ParameterDirection::Enum.
901  *
902  * @param input  The string to parse: "in", "out", or "inout"
903  *               optionally followed by whitespace.
904  * @param result The corresponding Uml::ParameterDirection::Enum.
905  * @return       Length of the string matched, excluding the optional
906  *               whitespace.
907  */
stringToDirection(QString input,Uml::ParameterDirection::Enum & result)908 int stringToDirection(QString input, Uml::ParameterDirection::Enum & result)
909 {
910     QRegExp dirx(QLatin1String("^(in|out|inout)"));
911     int pos = dirx.indexIn(input);
912     if (pos == -1)
913         return 0;
914     const QString dirStr = dirx.capturedTexts().first();
915     int dirLen = dirStr.length();
916     if (input.length() > dirLen && !input[dirLen].isSpace())
917         return 0;       // no match after all.
918     if (dirStr == QLatin1String("out"))
919         result = Uml::ParameterDirection::Out;
920     else if (dirStr == QLatin1String("inout"))
921         result = Uml::ParameterDirection::InOut;
922     else
923         result = Uml::ParameterDirection::In;
924     return dirLen;
925 }
926 
927 /**
928  * Parses a template parameter given in UML syntax.
929  *
930  * @param t             Input text of the template parameter.
931  *                      Example:  parname : partype
932  *                      or just:  parname          (for class type)
933  * @param nmTp          NameAndType returned by this method.
934  * @param owningScope   Pointer to the owning scope of the template param.
935  * @return      Error status of the parse, PS_OK for success.
936  */
parseTemplate(QString t,NameAndType & nmTp,UMLClassifier * owningScope)937 Parse_Status parseTemplate(QString t, NameAndType& nmTp, UMLClassifier *owningScope)
938 {
939     UMLDoc *pDoc = UMLApp::app()->document();
940 
941     t = t.trimmed();
942     if (t.isEmpty())
943         return PS_Empty;
944 
945     QStringList nameAndType = t.split(QRegExp(QLatin1String("\\s*:\\s*")));
946     if (nameAndType.count() == 2) {
947         UMLObject *pType = 0;
948         if (nameAndType[1] != QLatin1String("class")) {
949             pType = pDoc->findUMLObject(nameAndType[1], UMLObject::ot_UMLObject, owningScope);
950             if (pType == 0)
951                 return PS_Unknown_ArgType;
952         }
953         nmTp = NameAndType(nameAndType[0], pType);
954     } else {
955         nmTp = NameAndType(t, 0);
956     }
957     return PS_OK;
958 }
959 
960 /**
961  * Parses an attribute given in UML syntax.
962  *
963  * @param a             Input text of the attribute in UML syntax.
964  *                      Example:  argname : argtype
965  * @param nmTp          NameAndType returned by this method.
966  * @param owningScope   Pointer to the owning scope of the attribute.
967  * @param vis           Optional pointer to visibility (return value.)
968  *                      The visibility may be given at the beginning of the
969  *                      attribute text in mnemonic form as follows:
970  *                      "+"  stands for public
971  *                      "#"  stands for protected
972  *                      "-"  stands for private
973  *                      "~"  stands for implementation level visibility
974  *
975  * @return      Error status of the parse, PS_OK for success.
976  */
parseAttribute(QString a,NameAndType & nmTp,UMLClassifier * owningScope,Uml::Visibility::Enum * vis)977 Parse_Status parseAttribute(QString a, NameAndType& nmTp, UMLClassifier *owningScope,
978                             Uml::Visibility::Enum *vis /* = 0 */)
979 {
980     UMLDoc *pDoc = UMLApp::app()->document();
981 
982     a = a.simplified();
983     if (a.isEmpty())
984         return PS_Empty;
985 
986     int colonPos = a.indexOf(QLatin1Char(':'));
987     if (colonPos < 0) {
988         nmTp = NameAndType(a, 0);
989         return PS_OK;
990     }
991     QString name = a.left(colonPos).trimmed();
992     if (vis) {
993         QRegExp mnemonicVis(QLatin1String("^([\\+\\#\\-\\~] *)"));
994         int pos = mnemonicVis.indexIn(name);
995         if (pos == -1) {
996             *vis = Uml::Visibility::Private;  // default value
997         } else {
998             QString caption = mnemonicVis.cap(1);
999             QString strVis = caption.left(1);
1000             if (strVis == QLatin1String("+"))
1001                 *vis = Uml::Visibility::Public;
1002             else if (strVis == QLatin1String("#"))
1003                 *vis = Uml::Visibility::Protected;
1004             else if (strVis == QLatin1String("-"))
1005                 *vis = Uml::Visibility::Private;
1006             else
1007                 *vis = Uml::Visibility::Implementation;
1008         }
1009         name.remove(mnemonicVis);
1010     }
1011     Uml::ParameterDirection::Enum pd = Uml::ParameterDirection::In;
1012     if (name.startsWith(QLatin1String(QLatin1String("in ")))) {
1013         pd = Uml::ParameterDirection::In;
1014         name = name.mid(3);
1015     } else if (name.startsWith(QLatin1String(QLatin1String("inout ")))) {
1016         pd = Uml::ParameterDirection::InOut;
1017         name = name.mid(6);
1018     } else if (name.startsWith(QLatin1String(QLatin1String("out ")))) {
1019         pd = Uml::ParameterDirection::Out;
1020         name = name.mid(4);
1021     }
1022     a = a.mid(colonPos + 1).trimmed();
1023     if (a.isEmpty()) {
1024         nmTp = NameAndType(name, 0, pd);
1025         return PS_OK;
1026     }
1027     QStringList typeAndInitialValue = a.split(QRegExp(QLatin1String("\\s*=\\s*")));
1028     const QString &type = typeAndInitialValue[0];
1029     UMLObject *pType = pDoc->findUMLObject(type, UMLObject::ot_UMLObject, owningScope);
1030     if (pType == 0) {
1031         nmTp = NameAndType(name, 0, pd);
1032         return PS_Unknown_ArgType;
1033     }
1034     QString initialValue;
1035     if (typeAndInitialValue.count() == 2) {
1036         initialValue = typeAndInitialValue[1];
1037     }
1038     nmTp = NameAndType(name, pType, pd, initialValue);
1039     return PS_OK;
1040 }
1041 
1042 /**
1043  * Parses an operation given in UML syntax.
1044  *
1045  * @param m             Input text of the operation in UML syntax.
1046  *                      Example of a two-argument operation returning "void":
1047  *                      methodname (arg1name : arg1type, arg2name : arg2type) : void
1048  * @param desc          OpDescriptor returned by this method.
1049  * @param owningScope   Pointer to the owning scope of the operation.
1050  * @return      Error status of the parse, PS_OK for success.
1051  */
parseOperation(QString m,OpDescriptor & desc,UMLClassifier * owningScope)1052 Parse_Status parseOperation(QString m, OpDescriptor& desc, UMLClassifier *owningScope)
1053 {
1054     UMLDoc *pDoc = UMLApp::app()->document();
1055 
1056     m = m.simplified();
1057     if (m.isEmpty())
1058         return PS_Empty;
1059     if (m.contains(QRegExp(QLatin1String("operator *()")))) {
1060         // C++ special case: two sets of parentheses
1061         desc.m_name = QLatin1String("operator()");
1062         m.remove(QRegExp(QLatin1String("operator *()")));
1063     } else {
1064         /**
1065          * The search pattern includes everything up to the opening parenthesis
1066          * because UML also permits non programming-language oriented designs
1067          * using narrative names, for example "check water temperature".
1068          */
1069         QRegExp beginningUpToOpenParenth(QLatin1String("^([^\\(]+)"));
1070         int pos = beginningUpToOpenParenth.indexIn(m);
1071         if (pos == -1)
1072             return PS_Illegal_MethodName;
1073         desc.m_name = beginningUpToOpenParenth.cap(1);
1074     }
1075     desc.m_pReturnType = 0;
1076     QRegExp pat = QRegExp(QLatin1String("\\) *:(.*)$"));
1077     int pos = pat.indexIn(m);
1078     if (pos != -1) {  // return type is optional
1079         QString retType = pat.cap(1);
1080         retType = retType.trimmed();
1081         if (retType != QLatin1String("void")) {
1082             UMLObject *pRetType = owningScope ? owningScope->findTemplate(retType) : 0;
1083             if (pRetType == 0) {
1084                 pRetType = pDoc->findUMLObject(retType, UMLObject::ot_UMLObject, owningScope);
1085                 if (pRetType == 0)
1086                     return PS_Unknown_ReturnType;
1087             }
1088             desc.m_pReturnType = pRetType;
1089         }
1090     }
1091     // Remove possible empty parentheses ()
1092     m.remove(QRegExp(QLatin1String("\\s*\\(\\s*\\)")));
1093     desc.m_args.clear();
1094     pat = QRegExp(QLatin1String("\\((.*)\\)"));
1095     pos = pat.indexIn(m);
1096     if (pos == -1)  // argument list is optional
1097         return PS_OK;
1098     QString arglist = pat.cap(1);
1099     arglist = arglist.trimmed();
1100     if (arglist.isEmpty())
1101         return PS_OK;
1102     const QStringList args = arglist.split(QRegExp(QLatin1String("\\s*, \\s*")));
1103     for (QStringList::ConstIterator lit = args.begin(); lit != args.end(); ++lit) {
1104         NameAndType nmTp;
1105         Parse_Status ps = parseAttribute(*lit, nmTp, owningScope);
1106         if (ps)
1107             return ps;
1108         desc.m_args.append(nmTp);
1109     }
1110     return PS_OK;
1111 }
1112 
1113 /**
1114  * Parses a constraint.
1115  *
1116  * @param m             Input text of the constraint
1117  *
1118  * @param name          The name returned by this method
1119  * @param owningScope   Pointer to the owning scope of the constraint
1120  * @return       Error status of the parse, PS_OK for success.
1121  */
parseConstraint(QString m,QString & name,UMLEntity * owningScope)1122 Parse_Status parseConstraint(QString m, QString& name, UMLEntity* owningScope)
1123 {
1124     Q_UNUSED(owningScope);
1125     m = m.simplified();
1126     if (m.isEmpty())
1127         return PS_Empty;
1128 
1129     int colonPos = m.indexOf(QLatin1Char(':'));
1130     if (colonPos < 0) {
1131         name = m;
1132         return PS_OK;
1133     }
1134 
1135     name = m.left(colonPos).trimmed();
1136     return PS_OK;
1137 }
1138 
1139 /**
1140  * Returns the Parse_Status as a text.
1141  */
psText(Parse_Status value)1142 QString psText(Parse_Status value)
1143 {
1144     const QString text[] = {
1145                                i18n("OK"), i18nc("parse status", "Empty"), i18n("Malformed argument"),
1146                                i18n("Unknown argument type"), i18n("Illegal method name"),
1147                                i18n("Unknown return type"), i18n("Unspecified error")
1148                            };
1149     return text[(unsigned) value];
1150 }
1151 
1152 /**
1153  * Return true if the listview type is one of the predefined root views
1154  * (root, logical, usecase, component, deployment, datatype, or entity-
1155  * relationship view.)
1156  */
typeIsRootView(UMLListViewItem::ListViewType type)1157 bool typeIsRootView(UMLListViewItem::ListViewType type)
1158 {
1159     switch (type) {
1160         case UMLListViewItem::lvt_View:
1161         case UMLListViewItem::lvt_Logical_View:
1162         case UMLListViewItem::lvt_UseCase_View:
1163         case UMLListViewItem::lvt_Component_View:
1164         case UMLListViewItem::lvt_Deployment_View:
1165         case UMLListViewItem::lvt_EntityRelationship_Model:
1166             return true;
1167             break;
1168         default:
1169             break;
1170     }
1171     return false;
1172 }
1173 
1174 /**
1175  * Return true if the listview type also has a widget representation in diagrams.
1176  */
typeIsCanvasWidget(UMLListViewItem::ListViewType type)1177 bool typeIsCanvasWidget(UMLListViewItem::ListViewType type)
1178 {
1179     switch (type) {
1180         case UMLListViewItem::lvt_Actor:
1181         case UMLListViewItem::lvt_UseCase:
1182         case UMLListViewItem::lvt_Class:
1183         case UMLListViewItem::lvt_Package:
1184         case UMLListViewItem::lvt_Logical_Folder:
1185         case UMLListViewItem::lvt_UseCase_Folder:
1186         case UMLListViewItem::lvt_Component_Folder:
1187         case UMLListViewItem::lvt_Deployment_Folder:
1188         case UMLListViewItem::lvt_EntityRelationship_Folder:
1189         case UMLListViewItem::lvt_Subsystem:
1190         case UMLListViewItem::lvt_Component:
1191         case UMLListViewItem::lvt_Port:
1192         case UMLListViewItem::lvt_Node:
1193         case UMLListViewItem::lvt_Artifact:
1194         case UMLListViewItem::lvt_Interface:
1195         case UMLListViewItem::lvt_Datatype:
1196         case UMLListViewItem::lvt_Enum:
1197         case UMLListViewItem::lvt_Instance:
1198         case UMLListViewItem::lvt_Entity:
1199         case UMLListViewItem::lvt_Category:
1200             return true;
1201             break;
1202         default:
1203             break;
1204     }
1205     return false;
1206 }
1207 
1208 /**
1209  * Return true if the listview type is a logical, usecase or component folder.
1210  */
typeIsFolder(UMLListViewItem::ListViewType type)1211 bool typeIsFolder(UMLListViewItem::ListViewType type)
1212 {
1213     if (typeIsRootView(type) ||
1214             type == UMLListViewItem::lvt_Datatype_Folder ||
1215             type == UMLListViewItem::lvt_Logical_Folder ||
1216             type == UMLListViewItem::lvt_UseCase_Folder ||
1217             type == UMLListViewItem::lvt_Component_Folder ||
1218             type == UMLListViewItem::lvt_Deployment_Folder ||
1219             type == UMLListViewItem::lvt_EntityRelationship_Folder) {
1220         return true;
1221     } else {
1222         return false;
1223     }
1224 }
1225 
1226 /**
1227  * Return true if the listview type may act as a container for other objects,
1228  * i.e. if it is a folder, package, subsystem, or component.
1229  */
typeIsContainer(UMLListViewItem::ListViewType type)1230 bool typeIsContainer(UMLListViewItem::ListViewType type)
1231 {
1232     if (typeIsFolder(type))
1233         return true;
1234     return (type == UMLListViewItem::lvt_Package ||
1235             type == UMLListViewItem::lvt_Subsystem ||
1236             type == UMLListViewItem::lvt_Component ||
1237             type == UMLListViewItem::lvt_Class ||
1238             type == UMLListViewItem::lvt_Interface);
1239 }
1240 
1241 /**
1242  * Return true if the listview type is an attribute, operation, or template.
1243  */
typeIsClassifierList(UMLListViewItem::ListViewType type)1244 bool typeIsClassifierList(UMLListViewItem::ListViewType type)
1245 {
1246     if (type == UMLListViewItem::lvt_Attribute ||
1247         type == UMLListViewItem::lvt_Operation ||
1248         type == UMLListViewItem::lvt_Template ||
1249         type == UMLListViewItem::lvt_EntityAttribute ||
1250         type == UMLListViewItem::lvt_UniqueConstraint ||
1251         type == UMLListViewItem::lvt_ForeignKeyConstraint ||
1252         type == UMLListViewItem::lvt_PrimaryKeyConstraint ||
1253         type == UMLListViewItem::lvt_CheckConstraint  ||
1254         type == UMLListViewItem::lvt_EnumLiteral) {
1255         //  UMLListViewItem::lvt_InstanceAttribute must be handled separately
1256         //  because UMLInstanceAttribute is not a UMLClassifierListItem.
1257         return true;
1258     } else {
1259         return false;
1260     }
1261 }
1262 
1263 /**
1264  * Return true if the listview type is a classifier (Class, Entity, Enum)
1265  */
typeIsClassifier(UMLListViewItem::ListViewType type)1266 bool typeIsClassifier(UMLListViewItem::ListViewType type)
1267 {
1268     if (type == UMLListViewItem::lvt_Class ||
1269          type == UMLListViewItem::lvt_Interface ||
1270          type == UMLListViewItem::lvt_Entity ||
1271          type == UMLListViewItem::lvt_Enum) {
1272         return true;
1273     }
1274     return false;
1275 }
1276 
1277 /**
1278  * Return true if the listview type is a settings entry.
1279  */
typeIsProperties(UMLListViewItem::ListViewType type)1280 bool typeIsProperties(UMLListViewItem::ListViewType type)
1281 {
1282     switch (type) {
1283     case UMLListViewItem::lvt_Properties:
1284     case UMLListViewItem::lvt_Properties_AutoLayout:
1285     case UMLListViewItem::lvt_Properties_Class:
1286     case UMLListViewItem::lvt_Properties_CodeImport:
1287     case UMLListViewItem::lvt_Properties_CodeGeneration:
1288     case UMLListViewItem::lvt_Properties_CodeViewer:
1289     case UMLListViewItem::lvt_Properties_Font:
1290     case UMLListViewItem::lvt_Properties_General:
1291     case UMLListViewItem::lvt_Properties_UserInterface:
1292         return true;
1293         break;
1294     default:
1295         break;
1296     }
1297     return false;
1298 }
1299 
1300 /**
1301  * Check if a listviewitem of type childType is allowed
1302  * as child of type parentType
1303  */
typeIsAllowedInType(UMLListViewItem::ListViewType childType,UMLListViewItem::ListViewType parentType)1304 bool typeIsAllowedInType(UMLListViewItem::ListViewType childType,
1305                          UMLListViewItem::ListViewType parentType)
1306 {
1307     switch (childType) {
1308     case UMLListViewItem::lvt_Class:
1309     case UMLListViewItem::lvt_Package:
1310     case UMLListViewItem::lvt_Interface:
1311     case UMLListViewItem::lvt_Enum:
1312     case UMLListViewItem::lvt_Instance:
1313         return parentType == UMLListViewItem::lvt_Logical_View ||
1314                parentType == UMLListViewItem::lvt_Class ||
1315                parentType == UMLListViewItem::lvt_Package ||
1316                parentType == UMLListViewItem::lvt_Logical_Folder;
1317     case UMLListViewItem::lvt_Attribute:
1318         return parentType == UMLListViewItem::lvt_Class;
1319     case UMLListViewItem::lvt_EntityAttribute:
1320         return parentType == UMLListViewItem::lvt_Entity;
1321     case UMLListViewItem::lvt_InstanceAttribute:
1322         return parentType == UMLListViewItem::lvt_Instance;
1323     case UMLListViewItem::lvt_Operation:
1324         return parentType == UMLListViewItem::lvt_Class ||
1325                parentType == UMLListViewItem::lvt_Interface;
1326     case UMLListViewItem::lvt_Datatype:
1327         return parentType == UMLListViewItem::lvt_Logical_Folder ||
1328                parentType == UMLListViewItem::lvt_Datatype_Folder ||
1329                parentType == UMLListViewItem::lvt_Class ||
1330                parentType == UMLListViewItem::lvt_Interface ||
1331                parentType == UMLListViewItem::lvt_Package;
1332     case UMLListViewItem::lvt_Class_Diagram:
1333     case UMLListViewItem::lvt_Collaboration_Diagram:
1334     case UMLListViewItem::lvt_State_Diagram:
1335     case UMLListViewItem::lvt_Activity_Diagram:
1336     case UMLListViewItem::lvt_Sequence_Diagram:
1337     case UMLListViewItem::lvt_Object_Diagram:
1338         return parentType == UMLListViewItem::lvt_Logical_Folder ||
1339                parentType == UMLListViewItem::lvt_Logical_View;
1340     case UMLListViewItem::lvt_Logical_Folder:
1341         return parentType == UMLListViewItem::lvt_Package ||
1342                parentType == UMLListViewItem::lvt_Logical_Folder ||
1343                parentType == UMLListViewItem::lvt_Logical_View;
1344     case UMLListViewItem::lvt_UseCase_Folder:
1345         return parentType == UMLListViewItem::lvt_UseCase_Folder ||
1346                parentType == UMLListViewItem::lvt_UseCase_View;
1347     case UMLListViewItem::lvt_Component_Folder:
1348         return parentType == UMLListViewItem::lvt_Component_Folder ||
1349                parentType == UMLListViewItem::lvt_Component_View;
1350     case UMLListViewItem::lvt_Deployment_Folder:
1351         return parentType == UMLListViewItem::lvt_Deployment_Folder ||
1352                parentType == UMLListViewItem::lvt_Deployment_View;
1353     case UMLListViewItem::lvt_EntityRelationship_Folder:
1354         return parentType == UMLListViewItem::lvt_EntityRelationship_Folder ||
1355                parentType == UMLListViewItem::lvt_EntityRelationship_Model;
1356     case UMLListViewItem::lvt_Actor:
1357     case UMLListViewItem::lvt_UseCase:
1358     case UMLListViewItem::lvt_UseCase_Diagram:
1359         return parentType == UMLListViewItem::lvt_UseCase_Folder ||
1360                parentType == UMLListViewItem::lvt_UseCase_View;
1361     case UMLListViewItem::lvt_Subsystem:
1362         return parentType == UMLListViewItem::lvt_Component_Folder ||
1363                parentType == UMLListViewItem::lvt_Subsystem ||
1364                parentType == UMLListViewItem::lvt_Component_View;
1365     case UMLListViewItem::lvt_Component:
1366         return parentType == UMLListViewItem::lvt_Component_Folder ||
1367                parentType == UMLListViewItem::lvt_Component ||
1368                parentType == UMLListViewItem::lvt_Subsystem ||
1369                parentType == UMLListViewItem::lvt_Component_View;
1370     case UMLListViewItem::lvt_Port:
1371         return parentType == UMLListViewItem::lvt_Component ||
1372                parentType == UMLListViewItem::lvt_Subsystem;
1373     case UMLListViewItem::lvt_Artifact:
1374     case UMLListViewItem::lvt_Component_Diagram:
1375         return parentType == UMLListViewItem::lvt_Component_Folder ||
1376                parentType == UMLListViewItem::lvt_Component_View;
1377     case UMLListViewItem::lvt_Node:
1378     case UMLListViewItem::lvt_Deployment_Diagram:
1379         return parentType == UMLListViewItem::lvt_Deployment_Folder ||
1380                parentType == UMLListViewItem::lvt_Deployment_View;
1381     case UMLListViewItem::lvt_Entity:
1382     case UMLListViewItem::lvt_EntityRelationship_Diagram:
1383     case UMLListViewItem::lvt_Category:
1384         return parentType == UMLListViewItem::lvt_EntityRelationship_Folder ||
1385                parentType == UMLListViewItem::lvt_EntityRelationship_Model;
1386     default:
1387         return false;
1388     }
1389 }
1390 
1391 /**
1392  * Return true if the listview type is a diagram.
1393  */
typeIsDiagram(UMLListViewItem::ListViewType type)1394 bool typeIsDiagram(UMLListViewItem::ListViewType type)
1395 {
1396     if (type == UMLListViewItem::lvt_Class_Diagram ||
1397             type == UMLListViewItem::lvt_Collaboration_Diagram ||
1398             type == UMLListViewItem::lvt_State_Diagram ||
1399             type == UMLListViewItem::lvt_Activity_Diagram ||
1400             type == UMLListViewItem::lvt_Sequence_Diagram ||
1401             type == UMLListViewItem::lvt_UseCase_Diagram ||
1402             type == UMLListViewItem::lvt_Component_Diagram ||
1403             type == UMLListViewItem::lvt_Deployment_Diagram ||
1404             type == UMLListViewItem::lvt_EntityRelationship_Diagram ||
1405             type == UMLListViewItem::lvt_Object_Diagram) {
1406         return true;
1407     } else {
1408         return false;
1409     }
1410 }
1411 
1412 /**
1413  * Return the Model_Type which corresponds to the given DiagramType.
1414  */
convert_DT_MT(Uml::DiagramType::Enum dt)1415 Uml::ModelType::Enum convert_DT_MT(Uml::DiagramType::Enum dt)
1416 {
1417     Uml::ModelType::Enum mt;
1418     switch (dt) {
1419         case Uml::DiagramType::UseCase:
1420             mt = Uml::ModelType::UseCase;
1421             break;
1422         case Uml::DiagramType::Collaboration:
1423         case Uml::DiagramType::Class:
1424         case Uml::DiagramType::Object:
1425         case Uml::DiagramType::Sequence:
1426         case Uml::DiagramType::State:
1427         case Uml::DiagramType::Activity:
1428             mt = Uml::ModelType::Logical;
1429             break;
1430         case Uml::DiagramType::Component:
1431             mt = Uml::ModelType::Component;
1432             break;
1433         case Uml::DiagramType::Deployment:
1434             mt = Uml::ModelType::Deployment;
1435             break;
1436         case Uml::DiagramType::EntityRelationship:
1437             mt = Uml::ModelType::EntityRelationship;
1438             break;
1439         default:
1440             uError() << "Model_Utils::convert_DT_MT: illegal input value " << dt;
1441             mt = Uml::ModelType::N_MODELTYPES;
1442             break;
1443     }
1444     return mt;
1445 }
1446 
1447 /**
1448  * Return the ListViewType which corresponds to the given Model_Type.
1449  */
convert_MT_LVT(Uml::ModelType::Enum mt)1450 UMLListViewItem::ListViewType convert_MT_LVT(Uml::ModelType::Enum mt)
1451 {
1452     UMLListViewItem::ListViewType lvt = UMLListViewItem::lvt_Unknown;
1453     switch (mt) {
1454         case Uml::ModelType::Logical:
1455             lvt = UMLListViewItem::lvt_Logical_View;
1456             break;
1457         case Uml::ModelType::UseCase:
1458             lvt = UMLListViewItem::lvt_UseCase_View;
1459             break;
1460         case Uml::ModelType::Component:
1461             lvt = UMLListViewItem::lvt_Component_View;
1462             break;
1463         case Uml::ModelType::Deployment:
1464             lvt = UMLListViewItem::lvt_Deployment_View;
1465             break;
1466         case Uml::ModelType::EntityRelationship:
1467             lvt = UMLListViewItem::lvt_EntityRelationship_Model;
1468             break;
1469         default:
1470             break;
1471     }
1472     return lvt;
1473 }
1474 
1475 /**
1476  * Return the Model_Type which corresponds to the given ListViewType.
1477  * Returns Uml::N_MODELTYPES if the list view type given does not map
1478  * to a Model_Type.
1479  */
convert_LVT_MT(UMLListViewItem::ListViewType lvt)1480 Uml::ModelType::Enum convert_LVT_MT(UMLListViewItem::ListViewType lvt)
1481 {
1482     Uml::ModelType::Enum mt = Uml::ModelType::N_MODELTYPES;
1483     switch (lvt) {
1484         case UMLListViewItem::lvt_Logical_View:
1485             mt = Uml::ModelType::Logical;
1486             break;
1487         case UMLListViewItem::lvt_UseCase_View:
1488             mt = Uml::ModelType::UseCase;
1489             break;
1490         case UMLListViewItem::lvt_Component_View:
1491             mt = Uml::ModelType::Component;
1492             break;
1493         case UMLListViewItem::lvt_Deployment_View:
1494             mt = Uml::ModelType::Deployment;
1495             break;
1496         case UMLListViewItem::lvt_EntityRelationship_Model:
1497             mt = Uml::ModelType::EntityRelationship;
1498             break;
1499         default:
1500             break;
1501     }
1502     return mt;
1503 }
1504 
1505 /**
1506  * Convert a diagram type enum to the equivalent list view type.
1507  */
convert_DT_LVT(Uml::DiagramType::Enum dt)1508 UMLListViewItem::ListViewType convert_DT_LVT(Uml::DiagramType::Enum dt)
1509 {
1510     UMLListViewItem::ListViewType type =  UMLListViewItem::lvt_Unknown;
1511     switch(dt) {
1512     case Uml::DiagramType::UseCase:
1513         type = UMLListViewItem::lvt_UseCase_Diagram;
1514         break;
1515 
1516     case Uml::DiagramType::Class:
1517         type = UMLListViewItem::lvt_Class_Diagram;
1518         break;
1519 
1520     case Uml::DiagramType::Object:
1521         type = UMLListViewItem::lvt_Object_Diagram;
1522         break;
1523 
1524     case Uml::DiagramType::Sequence:
1525         type = UMLListViewItem::lvt_Sequence_Diagram;
1526         break;
1527 
1528     case Uml::DiagramType::Collaboration:
1529         type = UMLListViewItem::lvt_Collaboration_Diagram;
1530         break;
1531 
1532     case Uml::DiagramType::State:
1533         type = UMLListViewItem::lvt_State_Diagram;
1534         break;
1535 
1536     case Uml::DiagramType::Activity:
1537         type = UMLListViewItem::lvt_Activity_Diagram;
1538         break;
1539 
1540     case Uml::DiagramType::Component:
1541         type = UMLListViewItem::lvt_Component_Diagram;
1542         break;
1543 
1544     case Uml::DiagramType::Deployment:
1545         type = UMLListViewItem::lvt_Deployment_Diagram;
1546         break;
1547 
1548     case Uml::DiagramType::EntityRelationship:
1549         type = UMLListViewItem::lvt_EntityRelationship_Diagram;
1550         break;
1551 
1552     default:
1553         uWarning() << "convert_DT_LVT() called on unknown diagram type";
1554     }
1555     return type;
1556 }
1557 
1558 /**
1559  * Convert an object's type to the equivalent list view type
1560  *
1561  * @param o  Pointer to the UMLObject whose type shall be converted
1562  *           to the equivalent ListViewType.  We cannot just
1563  *           pass in a UMLObject::ObjectType because a UMLFolder is mapped
1564  *           to different ListViewType values, depending on its
1565  *           location in one of the predefined modelviews (Logical/
1566  *           UseCase/etc.)
1567  * @return  The equivalent ListViewType.
1568  */
convert_OT_LVT(UMLObject * o)1569 UMLListViewItem::ListViewType convert_OT_LVT(UMLObject *o)
1570 {
1571     UMLObject::ObjectType ot = o->baseType();
1572     UMLListViewItem::ListViewType type =  UMLListViewItem::lvt_Unknown;
1573     switch(ot) {
1574     case UMLObject::ot_UseCase:
1575         type = UMLListViewItem::lvt_UseCase;
1576         break;
1577 
1578     case UMLObject::ot_Actor:
1579         type = UMLListViewItem::lvt_Actor;
1580         break;
1581 
1582     case UMLObject::ot_Class:
1583         type = UMLListViewItem::lvt_Class;
1584         break;
1585 
1586     case UMLObject::ot_Package:
1587         if (o->stereotype() == QLatin1String("subsystem"))
1588             type = UMLListViewItem::lvt_Subsystem;
1589         else
1590             type = UMLListViewItem::lvt_Package;
1591         break;
1592 
1593     case UMLObject::ot_Folder:
1594         {
1595             UMLDoc *umldoc = UMLApp::app()->document();
1596             UMLPackage *p = o->asUMLPackage();
1597             do {
1598                 const Uml::ModelType::Enum mt = umldoc->rootFolderType(p);
1599                 if (mt != Uml::ModelType::N_MODELTYPES) {
1600                     switch (mt) {
1601                         case Uml::ModelType::Logical:
1602                             type = UMLListViewItem::lvt_Logical_Folder;
1603                             break;
1604                         case Uml::ModelType::UseCase:
1605                             type = UMLListViewItem::lvt_UseCase_Folder;
1606                             break;
1607                         case Uml::ModelType::Component:
1608                             type = UMLListViewItem::lvt_Component_Folder;
1609                             break;
1610                         case Uml::ModelType::Deployment:
1611                             type = UMLListViewItem::lvt_Deployment_Folder;
1612                             break;
1613                         case Uml::ModelType::EntityRelationship:
1614                             type = UMLListViewItem::lvt_EntityRelationship_Folder;
1615                             break;
1616                         default:
1617                             break;
1618                     }
1619                     return type;
1620                 }
1621             } while ((p = p->umlPackage()) != 0);
1622             uError() << "convert_OT_LVT(" << o->name()
1623                 << "): internal error - object is not properly nested in folder";
1624         }
1625         break;
1626 
1627     case UMLObject::ot_Component:
1628         type = UMLListViewItem::lvt_Component;
1629         break;
1630 
1631     case UMLObject::ot_Port:
1632         type = UMLListViewItem::lvt_Port;
1633         break;
1634 
1635     case UMLObject::ot_Node:
1636         type = UMLListViewItem::lvt_Node;
1637         break;
1638 
1639     case UMLObject::ot_Artifact:
1640         type = UMLListViewItem::lvt_Artifact;
1641         break;
1642 
1643     case UMLObject::ot_Interface:
1644         type = UMLListViewItem::lvt_Interface;
1645         break;
1646 
1647     case UMLObject::ot_Datatype:
1648         type = UMLListViewItem::lvt_Datatype;
1649         break;
1650 
1651     case UMLObject::ot_Enum:
1652         type = UMLListViewItem::lvt_Enum;
1653         break;
1654 
1655     case UMLObject::ot_EnumLiteral:
1656         type = UMLListViewItem::lvt_EnumLiteral;
1657         break;
1658 
1659     case UMLObject::ot_Entity:
1660         type = UMLListViewItem::lvt_Entity;
1661         break;
1662 
1663     case UMLObject::ot_Category:
1664         type = UMLListViewItem::lvt_Category;
1665         break;
1666 
1667     case UMLObject::ot_EntityAttribute:
1668         type = UMLListViewItem::lvt_EntityAttribute;
1669         break;
1670 
1671     case UMLObject::ot_UniqueConstraint: {
1672          UMLEntity* ent = o->umlParent()->asUMLEntity();
1673          UMLUniqueConstraint* uc = o->asUMLUniqueConstraint();
1674          if (ent->isPrimaryKey(uc)) {
1675              type = UMLListViewItem::lvt_PrimaryKeyConstraint;
1676          } else {
1677              type = UMLListViewItem::lvt_UniqueConstraint;
1678          }
1679          break;
1680         }
1681 
1682     case UMLObject::ot_ForeignKeyConstraint:
1683         type = UMLListViewItem::lvt_ForeignKeyConstraint;
1684         break;
1685 
1686     case UMLObject::ot_CheckConstraint:
1687         type = UMLListViewItem::lvt_CheckConstraint;
1688         break;
1689 
1690     case UMLObject::ot_Attribute:
1691         type = UMLListViewItem::lvt_Attribute;
1692         break;
1693 
1694     case UMLObject::ot_Operation:
1695         type = UMLListViewItem::lvt_Operation;
1696         break;
1697 
1698     case UMLObject::ot_Template:
1699         type = UMLListViewItem::lvt_Template;
1700         break;
1701 
1702     case UMLObject::ot_Association:
1703         type = UMLListViewItem::lvt_Association;
1704         break;
1705 
1706     case UMLObject::ot_Instance:
1707         type = UMLListViewItem::lvt_Instance;
1708         break;
1709 
1710     case UMLObject::ot_InstanceAttribute:
1711         type = UMLListViewItem::lvt_InstanceAttribute;
1712         break;
1713 
1714     default:
1715         break;
1716     }
1717     return type;
1718 }
1719 
1720 /**
1721  * Converts a list view type enum to the equivalent object type.
1722  *
1723  * @param lvt   The ListViewType to convert.
1724  * @return  The converted ObjectType if the listview type
1725  *          has a UMLObject::ObjectType representation, else 0.
1726  */
convert_LVT_OT(UMLListViewItem::ListViewType lvt)1727 UMLObject::ObjectType convert_LVT_OT(UMLListViewItem::ListViewType lvt)
1728 {
1729     UMLObject::ObjectType ot = (UMLObject::ObjectType)0;
1730     switch (lvt) {
1731     case UMLListViewItem::lvt_UseCase:
1732         ot = UMLObject::ot_UseCase;
1733         break;
1734 
1735     case UMLListViewItem::lvt_Actor:
1736         ot = UMLObject::ot_Actor;
1737         break;
1738 
1739     case UMLListViewItem::lvt_Class:
1740         ot = UMLObject::ot_Class;
1741         break;
1742 
1743     case UMLListViewItem::lvt_Package:
1744     case UMLListViewItem::lvt_Subsystem:
1745         ot = UMLObject::ot_Package;
1746         break;
1747 
1748     case UMLListViewItem::lvt_Component:
1749         ot = UMLObject::ot_Component;
1750         break;
1751 
1752     case UMLListViewItem::lvt_Port:
1753         ot = UMLObject::ot_Port;
1754         break;
1755 
1756     case UMLListViewItem::lvt_Node:
1757         ot = UMLObject::ot_Node;
1758         break;
1759 
1760     case UMLListViewItem::lvt_Artifact:
1761         ot = UMLObject::ot_Artifact;
1762         break;
1763 
1764     case UMLListViewItem::lvt_Interface:
1765         ot = UMLObject::ot_Interface;
1766         break;
1767 
1768     case UMLListViewItem::lvt_Datatype:
1769         ot = UMLObject::ot_Datatype;
1770         break;
1771 
1772     case UMLListViewItem::lvt_Enum:
1773         ot = UMLObject::ot_Enum;
1774         break;
1775 
1776     case UMLListViewItem::lvt_Entity:
1777         ot = UMLObject::ot_Entity;
1778         break;
1779 
1780     case UMLListViewItem::lvt_Category:
1781         ot = UMLObject::ot_Category;
1782         break;
1783 
1784     case UMLListViewItem::lvt_EntityAttribute:
1785         ot = UMLObject::ot_EntityAttribute;
1786         break;
1787 
1788     case UMLListViewItem::lvt_UniqueConstraint:
1789         ot = UMLObject::ot_UniqueConstraint;
1790         break;
1791 
1792     case UMLListViewItem::lvt_PrimaryKeyConstraint:
1793         ot = UMLObject::ot_UniqueConstraint;
1794         break;
1795 
1796     case UMLListViewItem::lvt_ForeignKeyConstraint:
1797         ot = UMLObject::ot_ForeignKeyConstraint;
1798         break;
1799 
1800     case UMLListViewItem::lvt_CheckConstraint:
1801         ot = UMLObject::ot_CheckConstraint;
1802         break;
1803 
1804     case UMLListViewItem::lvt_Attribute:
1805         ot = UMLObject::ot_Attribute;
1806         break;
1807 
1808     case UMLListViewItem::lvt_Operation:
1809         ot = UMLObject::ot_Operation;
1810         break;
1811 
1812     case UMLListViewItem::lvt_Template:
1813         ot = UMLObject::ot_Template;
1814         break;
1815 
1816     case UMLListViewItem::lvt_EnumLiteral:
1817         ot = UMLObject::ot_EnumLiteral;
1818         break;
1819 
1820     case UMLListViewItem::lvt_Instance:
1821         ot = UMLObject::ot_Instance;
1822         break;
1823 
1824     case UMLListViewItem::lvt_InstanceAttribute:
1825         ot = UMLObject::ot_InstanceAttribute;
1826         break;
1827 
1828     default:
1829         if (typeIsFolder(lvt))
1830             ot = UMLObject::ot_Folder;
1831         break;
1832     }
1833     return ot;
1834 }
1835 
1836 /**
1837  * Return the IconType which corresponds to the given listview type.
1838  *
1839  * @param lvt  ListViewType to convert.
1840  * @return  The Icon_Utils::IconType corresponding to the lvt.
1841  *          Returns it_Home in case no mapping to IconType exists.
1842  */
convert_LVT_IT(UMLListViewItem::ListViewType lvt,UMLObject * o)1843 Icon_Utils::IconType convert_LVT_IT(UMLListViewItem::ListViewType lvt, UMLObject *o)
1844 {
1845     Icon_Utils::IconType icon = Icon_Utils::it_Home;
1846     switch (lvt) {
1847         case UMLListViewItem::lvt_UseCase_View:
1848         case UMLListViewItem::lvt_UseCase_Folder:
1849             icon = Icon_Utils::it_Folder_Grey;
1850             break;
1851         case UMLListViewItem::lvt_Logical_View:
1852         case UMLListViewItem::lvt_Logical_Folder:
1853             icon = Icon_Utils::it_Folder_Green;
1854             break;
1855         case UMLListViewItem::lvt_Datatype_Folder:
1856             icon = Icon_Utils::it_Folder_Orange;
1857             break;
1858         case UMLListViewItem::lvt_Component_View:
1859         case UMLListViewItem::lvt_Component_Folder:
1860             icon = Icon_Utils::it_Folder_Red;
1861             break;
1862         case UMLListViewItem::lvt_Deployment_View:
1863         case UMLListViewItem::lvt_Deployment_Folder:
1864             icon = Icon_Utils::it_Folder_Violet;
1865             break;
1866         case UMLListViewItem::lvt_EntityRelationship_Model:
1867         case UMLListViewItem::lvt_EntityRelationship_Folder:
1868             icon = Icon_Utils::it_Folder_Cyan;
1869             break;
1870         case UMLListViewItem::lvt_Actor:
1871             icon = Icon_Utils::it_Actor;
1872             break;
1873         case UMLListViewItem::lvt_Association:
1874             icon = Icon_Utils::it_Association;
1875             break;
1876         case UMLListViewItem::lvt_UseCase:
1877             icon = Icon_Utils::it_UseCase;
1878             break;
1879         case UMLListViewItem::lvt_Class:
1880             if (o && o->stereotype() == QLatin1String("class-or-package"))
1881                 icon = Icon_Utils::it_ClassOrPackage;
1882             else
1883                 icon = Icon_Utils::it_Class;
1884             break;
1885         case UMLListViewItem::lvt_Package:
1886             icon = Icon_Utils::it_Package;
1887             break;
1888         case UMLListViewItem::lvt_Subsystem:
1889             icon = Icon_Utils::it_Subsystem;
1890             break;
1891         case UMLListViewItem::lvt_Component:
1892             icon = Icon_Utils::it_Component;
1893             break;
1894         case UMLListViewItem::lvt_Port:
1895             icon = Icon_Utils::it_Port;
1896             break;
1897         case UMLListViewItem::lvt_Node:
1898             icon = Icon_Utils::it_Node;
1899             break;
1900         case UMLListViewItem::lvt_Artifact:
1901             icon = Icon_Utils::it_Artifact;
1902             break;
1903         case UMLListViewItem::lvt_Interface:
1904             icon = Icon_Utils::it_Interface;
1905             break;
1906         case UMLListViewItem::lvt_Datatype:
1907             icon = Icon_Utils::it_Datatype;
1908             break;
1909         case UMLListViewItem::lvt_Enum:
1910             icon = Icon_Utils::it_Enum;
1911             break;
1912         case UMLListViewItem::lvt_Entity:
1913             icon = Icon_Utils::it_Entity;
1914             break;
1915         case UMLListViewItem::lvt_Category:
1916             icon = Icon_Utils::it_Category;
1917             break;
1918         case UMLListViewItem::lvt_Template:
1919             icon = Icon_Utils::it_Template;
1920             break;
1921         case UMLListViewItem::lvt_Attribute:
1922             icon = Icon_Utils::it_Private_Attribute;
1923             break;
1924         case UMLListViewItem::lvt_EntityAttribute:
1925             icon = Icon_Utils::it_Private_Attribute;
1926             break;
1927         case UMLListViewItem::lvt_EnumLiteral:
1928             icon = Icon_Utils::it_Public_Attribute;
1929             break;
1930         case UMLListViewItem::lvt_Operation:
1931             icon = Icon_Utils::it_Public_Method;
1932             break;
1933         case UMLListViewItem::lvt_UniqueConstraint:
1934             icon = Icon_Utils::it_Unique_Constraint;
1935             break;
1936         case UMLListViewItem::lvt_PrimaryKeyConstraint:
1937             icon = Icon_Utils::it_PrimaryKey_Constraint;
1938             break;
1939         case UMLListViewItem::lvt_ForeignKeyConstraint:
1940             icon = Icon_Utils::it_ForeignKey_Constraint;
1941             break;
1942         case UMLListViewItem::lvt_CheckConstraint:
1943             icon = Icon_Utils::it_Check_Constraint;
1944             break;
1945         case UMLListViewItem::lvt_Class_Diagram:
1946             icon = Icon_Utils::it_Diagram_Class;
1947             break;
1948         case UMLListViewItem::lvt_Object_Diagram:
1949             icon = Icon_Utils::it_Diagram_Object;
1950             break;
1951         case UMLListViewItem::lvt_UseCase_Diagram:
1952             icon = Icon_Utils::it_Diagram_Usecase;
1953             break;
1954         case UMLListViewItem::lvt_Sequence_Diagram:
1955             icon = Icon_Utils::it_Diagram_Sequence;
1956             break;
1957         case UMLListViewItem::lvt_Collaboration_Diagram:
1958             icon = Icon_Utils::it_Diagram_Collaboration;
1959             break;
1960         case UMLListViewItem::lvt_State_Diagram:
1961             icon = Icon_Utils::it_Diagram_State;
1962             break;
1963         case UMLListViewItem::lvt_Activity_Diagram:
1964             icon = Icon_Utils::it_Diagram_Activity;
1965             break;
1966         case UMLListViewItem::lvt_Component_Diagram:
1967             icon = Icon_Utils::it_Diagram_Component;
1968             break;
1969         case UMLListViewItem::lvt_Deployment_Diagram:
1970             icon = Icon_Utils::it_Diagram_Deployment;
1971             break;
1972         case UMLListViewItem::lvt_EntityRelationship_Diagram:
1973             icon = Icon_Utils::it_Diagram_EntityRelationship;
1974             break;
1975         case UMLListViewItem::lvt_Properties:
1976             icon = Icon_Utils::it_Properties;
1977             break;
1978         case UMLListViewItem::lvt_Properties_AutoLayout:
1979             icon = Icon_Utils::it_Properties_AutoLayout;
1980             break;
1981         case UMLListViewItem::lvt_Properties_Class:
1982             icon = Icon_Utils::it_Properties_Class;
1983             break;
1984         case UMLListViewItem::lvt_Properties_CodeImport:
1985             icon = Icon_Utils::it_Properties_CodeImport;
1986             break;
1987         case UMLListViewItem::lvt_Properties_CodeGeneration:
1988             icon = Icon_Utils::it_Properties_CodeGeneration;
1989             break;
1990         case UMLListViewItem::lvt_Properties_CodeViewer:
1991             icon = Icon_Utils::it_Properties_CodeViewer;
1992             break;
1993         case UMLListViewItem::lvt_Properties_Font:
1994             icon = Icon_Utils::it_Properties_Font;
1995             break;
1996         case UMLListViewItem::lvt_Properties_General:
1997             icon = Icon_Utils::it_Properties_General;
1998             break;
1999         case UMLListViewItem::lvt_Properties_UserInterface:
2000             icon = Icon_Utils::it_Properties_UserInterface;
2001             break;
2002         case UMLListViewItem::lvt_Instance:
2003             icon = Icon_Utils::it_Instance;
2004         break;
2005         case UMLListViewItem::lvt_InstanceAttribute:
2006             icon = Icon_Utils::it_Private_Attribute;
2007         break;
2008         default:
2009             break;
2010     }
2011     return icon;
2012 }
2013 
2014 /**
2015  * Return the DiagramType which corresponds to the given listview type.
2016  *
2017  * @param lvt  ListViewType to convert.
2018  * @return  The Uml::DiagramType corresponding to the lvt.
2019  *          Returns dt_Undefined in case no mapping to DiagramType exists.
2020  */
convert_LVT_DT(UMLListViewItem::ListViewType lvt)2021 Uml::DiagramType::Enum convert_LVT_DT(UMLListViewItem::ListViewType lvt)
2022 {
2023     Uml::DiagramType::Enum dt = Uml::DiagramType::Undefined;
2024     switch (lvt) {
2025         case UMLListViewItem::lvt_Class_Diagram:
2026             dt = Uml::DiagramType::Class;
2027             break;
2028         case UMLListViewItem::lvt_UseCase_Diagram:
2029             dt = Uml::DiagramType::UseCase;
2030             break;
2031         case UMLListViewItem::lvt_Sequence_Diagram:
2032             dt = Uml::DiagramType::Sequence;
2033             break;
2034         case UMLListViewItem::lvt_Collaboration_Diagram:
2035             dt = Uml::DiagramType::Collaboration;
2036             break;
2037         case UMLListViewItem::lvt_State_Diagram:
2038             dt = Uml::DiagramType::State;
2039             break;
2040         case UMLListViewItem::lvt_Activity_Diagram:
2041             dt = Uml::DiagramType::Activity;
2042             break;
2043         case UMLListViewItem::lvt_Component_Diagram:
2044             dt = Uml::DiagramType::Component;
2045             break;
2046         case UMLListViewItem::lvt_Deployment_Diagram:
2047             dt = Uml::DiagramType::Deployment;
2048             break;
2049         case UMLListViewItem::lvt_EntityRelationship_Diagram:
2050             dt = Uml::DiagramType::EntityRelationship;
2051             break;
2052     case UMLListViewItem::lvt_Object_Diagram:
2053             dt = Uml::DiagramType::Object;
2054         break;
2055         default:
2056             break;
2057     }
2058     return dt;
2059 }
2060 
2061 /**
2062  * Converts a list view type enum to the equivalent settings dialog type.
2063  *
2064  * @param type   The ListViewType to convert.
2065  * @return  The converted settings dialog type
2066  */
convert_LVT_PT(UMLListViewItem::ListViewType type)2067 MultiPageDialogBase::PageType convert_LVT_PT(UMLListViewItem::ListViewType type)
2068 {
2069     MultiPageDialogBase::PageType pt = MultiPageDialogBase::GeneralPage;
2070     switch (type) {
2071     case UMLListViewItem::lvt_Properties:
2072         pt = MultiPageDialogBase::GeneralPage;
2073         break;
2074     case UMLListViewItem::lvt_Properties_AutoLayout:
2075         pt = MultiPageDialogBase::AutoLayoutPage;
2076         break;
2077     case UMLListViewItem::lvt_Properties_Class:
2078         pt = MultiPageDialogBase::ClassPage;
2079         break;
2080     case UMLListViewItem::lvt_Properties_CodeImport:
2081         pt = MultiPageDialogBase::CodeImportPage;
2082         break;
2083     case UMLListViewItem::lvt_Properties_CodeGeneration:
2084         pt = MultiPageDialogBase::CodeGenerationPage;
2085         break;
2086     case UMLListViewItem::lvt_Properties_CodeViewer:
2087         pt = MultiPageDialogBase::CodeViewerPage;
2088         break;
2089     case UMLListViewItem::lvt_Properties_Font:
2090         pt = MultiPageDialogBase::FontPage;
2091         break;
2092     case UMLListViewItem::lvt_Properties_General:
2093         pt = MultiPageDialogBase::GeneralPage;
2094         break;
2095     case UMLListViewItem::lvt_Properties_UserInterface:
2096         pt = MultiPageDialogBase::UserInterfacePage;
2097         break;
2098     default:
2099         break;
2100     }
2101     return pt;
2102 }
2103 
2104 /**
2105  * Return the Model_Type which corresponds to the given ObjectType.
2106  */
convert_OT_MT(UMLObject::ObjectType ot)2107 Uml::ModelType::Enum convert_OT_MT(UMLObject::ObjectType ot)
2108 {
2109     Uml::ModelType::Enum mt = Uml::ModelType::N_MODELTYPES;
2110     switch (ot) {
2111         case UMLObject::ot_Actor:
2112         case UMLObject::ot_UseCase:
2113             mt = Uml::ModelType::UseCase;
2114             break;
2115         case UMLObject::ot_Component:
2116         case UMLObject::ot_Port:
2117         case UMLObject::ot_Artifact:
2118         case UMLObject::ot_SubSystem:
2119             mt = Uml::ModelType::Component;
2120             break;
2121         case UMLObject::ot_Node:
2122             mt = Uml::ModelType::Deployment;
2123             break;
2124         case UMLObject::ot_Entity:
2125         case UMLObject::ot_EntityAttribute:
2126         case UMLObject::ot_UniqueConstraint:
2127         case UMLObject::ot_ForeignKeyConstraint:
2128         case UMLObject::ot_CheckConstraint:
2129         case UMLObject::ot_Category:
2130             mt = Uml::ModelType::EntityRelationship;
2131             break;
2132         default:
2133             mt = Uml::ModelType::Logical;
2134             break;
2135     }
2136     return mt;
2137 }
2138 
2139 /**
2140  * Converts from the UpdateDeleteAction enum to a QString
2141  * @param uda The UpdateDeleteAction enum literal
2142  */
updateDeleteActionToString(UMLForeignKeyConstraint::UpdateDeleteAction uda)2143 QString updateDeleteActionToString(UMLForeignKeyConstraint::UpdateDeleteAction uda)
2144 {
2145     switch(uda) {
2146      case UMLForeignKeyConstraint::uda_NoAction:
2147          return QLatin1String("NO ACTION");
2148      case  UMLForeignKeyConstraint::uda_Restrict:
2149          return QLatin1String("RESTRICT");
2150      case UMLForeignKeyConstraint::uda_Cascade:
2151          return QLatin1String("CASCADE");
2152      case  UMLForeignKeyConstraint::uda_SetNull:
2153          return QLatin1String("SET NULL");
2154      case  UMLForeignKeyConstraint::uda_SetDefault:
2155          return QLatin1String("SET DEFAULT");
2156      default:
2157          return QString();
2158     }
2159 }
2160 
2161 /**
2162  * Return true if the object type is allowed in the related diagram
2163  * @param o UML object instance
2164  * @param scene diagram instance
2165  * @return true type is allowed
2166  * @return false type is not allowed
2167  */
typeIsAllowedInDiagram(UMLObject * o,UMLScene * scene)2168 bool typeIsAllowedInDiagram(UMLObject* o, UMLScene *scene)
2169 {
2170     //make sure dragging item onto correct diagram
2171     // concept - class, seq, coll diagram
2172     // actor, usecase - usecase diagram
2173     UMLObject::ObjectType ot = o->baseType();
2174     Uml::ID::Type id = o->id();
2175     Uml::DiagramType::Enum diagramType = scene->type();
2176     bool bAccept = true;
2177 
2178     switch (diagramType) {
2179     case Uml::DiagramType::UseCase:
2180         if ((scene->widgetOnDiagram(id) && ot == UMLObject::ot_Actor) ||
2181             (ot != UMLObject::ot_Actor && ot != UMLObject::ot_UseCase))
2182             bAccept = false;
2183         break;
2184     case Uml::DiagramType::Class:
2185         if (scene->widgetOnDiagram(id) ||
2186             (ot != UMLObject::ot_Class &&
2187              ot != UMLObject::ot_Package &&
2188              ot != UMLObject::ot_Interface &&
2189              ot != UMLObject::ot_Enum &&
2190              ot != UMLObject::ot_Datatype &&
2191              ot != UMLObject::ot_Instance)) {
2192             bAccept = false;
2193         }
2194         break;
2195     case Uml::DiagramType::Object:
2196         if (scene->widgetOnDiagram(id) || ot != UMLObject::ot_Instance)
2197             bAccept = false;
2198         break;
2199     case Uml::DiagramType::Sequence:
2200         if (ot != UMLObject::ot_Class &&
2201             ot != UMLObject::ot_Interface &&
2202             ot != UMLObject::ot_Actor)
2203             bAccept = false;
2204         break;
2205     case Uml::DiagramType::Collaboration:
2206         if (ot != UMLObject::ot_Class &&
2207             ot != UMLObject::ot_Interface &&
2208             ot != UMLObject::ot_Instance &&
2209             ot != UMLObject::ot_Actor)
2210             bAccept = false;
2211         break;
2212     case Uml::DiagramType::Deployment:
2213         if (scene->widgetOnDiagram(id))
2214             bAccept = false;
2215         else if (ot != UMLObject::ot_Interface &&
2216                  ot != UMLObject::ot_Package &&
2217                  ot != UMLObject::ot_Component &&
2218                  ot != UMLObject::ot_Class &&
2219                  ot != UMLObject::ot_Node)
2220             bAccept = false;
2221         else if (ot == UMLObject::ot_Package &&
2222                  o->stereotype() != QLatin1String("subsystem"))
2223             bAccept = false;
2224         break;
2225     case Uml::DiagramType::Component:
2226         if (scene->widgetOnDiagram(id) ||
2227             (ot != UMLObject::ot_Interface &&
2228              ot != UMLObject::ot_Package &&
2229              ot != UMLObject::ot_Component &&
2230              ot != UMLObject::ot_Port &&
2231              ot != UMLObject::ot_Artifact &&
2232              ot != UMLObject::ot_Class))
2233             bAccept = false;
2234         else if (ot == UMLObject::ot_Class && !o->isAbstract())
2235             bAccept = false;
2236         else if (ot == UMLObject::ot_Port) {
2237             const bool componentOnDiagram = scene->widgetOnDiagram(o->umlPackage()->id());
2238             bAccept = componentOnDiagram;
2239         }
2240         break;
2241     case Uml::DiagramType::EntityRelationship:
2242         if (scene->widgetOnDiagram(id) ||
2243             (ot != UMLObject::ot_Entity &&
2244              ot != UMLObject::ot_Category))
2245             bAccept = false;
2246         break;
2247     default:
2248         break;
2249     }
2250     return bAccept;
2251 }
2252 
2253 /**
2254  * Return true if the widget type is allowed in the related diagram
2255  * @param w UML widget object
2256  * @param scene diagram instance
2257  * @return true type is allowed
2258  * @return false type is not allowed
2259  */
typeIsAllowedInDiagram(UMLWidget * w,UMLScene * scene)2260 bool typeIsAllowedInDiagram(UMLWidget* w, UMLScene *scene)
2261 {
2262     UMLWidget::WidgetType wt = w->baseType();
2263     Uml::DiagramType::Enum diagramType = scene->type();
2264     bool bAccept = true;
2265 
2266     // TODO: check additional widgets
2267     switch (diagramType) {
2268     case Uml::DiagramType::Activity:
2269     case Uml::DiagramType::Class:
2270     case Uml::DiagramType::Object:
2271     case Uml::DiagramType::Collaboration:
2272     case Uml::DiagramType::Component:
2273     case Uml::DiagramType::Deployment:
2274     case Uml::DiagramType::EntityRelationship:
2275     case Uml::DiagramType::Sequence:
2276     case Uml::DiagramType::State:
2277     case Uml::DiagramType::UseCase:
2278     default:
2279         switch(wt) {
2280         case WidgetBase::wt_Note:
2281             break;
2282         case WidgetBase::wt_Text:
2283             {
2284                 FloatingTextWidget *ft = w->asFloatingTextWidget();
2285                 if (ft && ft->textRole() != Uml::TextRole::Floating) {
2286                     bAccept = false;
2287                 }
2288             }
2289             break;
2290         default:
2291             bAccept = false;
2292             break;
2293         }
2294         break;
2295     }
2296     return bAccept;
2297 }
2298 
2299 /**
2300  * return true if given object type supports associations
2301  * @param type uml object type to check
2302  */
hasAssociations(UMLObject::ObjectType type)2303 bool hasAssociations(UMLObject::ObjectType type)
2304 {
2305     switch (type) {
2306         case UMLObject::ot_Actor:
2307         case UMLObject::ot_UseCase:
2308         case UMLObject::ot_Class:
2309         case UMLObject::ot_Package:
2310         case UMLObject::ot_Component:
2311         case UMLObject::ot_Node:
2312         case UMLObject::ot_Artifact:
2313         case UMLObject::ot_Interface:
2314         case UMLObject::ot_Enum:
2315         case UMLObject::ot_Entity:
2316         case UMLObject::ot_Datatype:
2317         case UMLObject::ot_Category:
2318         case UMLObject::ot_Instance:
2319             return true;
2320         default:
2321             return false;
2322     }
2323 }
2324 }  // namespace Model_Utils
2325 
2326