summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRalf Habacker <[email protected]>2015-05-07 16:20:43 +0200
committerRalf Habacker <[email protected]>2015-05-08 09:58:39 +0200
commit5a05d35e2e809899b2f65bea9fb44681042d10f8 (patch)
tree456864711f8a15fbd11ef1ef13348042c6a72b12
parent66ed34766b015c56a4f1ed880d614a9127c44697 (diff)
Fix 'Crash when copying actor of use case to collaboration diagram'.
The crash happened by accessing deleted widgets in the scene widget list; the bug is fixed by excluding invalid uml objects and widget in UMLDragData::decodeClip4() before any widget is added to the scene. BUG:345571
-rw-r--r--umbrello/clipboard/umlclipboard.cpp47
-rw-r--r--umbrello/clipboard/umlclipboard.h2
-rw-r--r--umbrello/clipboard/umldragdata.cpp22
-rw-r--r--umbrello/model_utils.cpp46
-rw-r--r--umbrello/model_utils.h1
5 files changed, 69 insertions, 49 deletions
diff --git a/umbrello/clipboard/umlclipboard.cpp b/umbrello/clipboard/umlclipboard.cpp
index bbd1c3f..31485a1 100644
--- a/umbrello/clipboard/umlclipboard.cpp
+++ b/umbrello/clipboard/umlclipboard.cpp
@@ -525,14 +525,6 @@ bool UMLClipboard::pasteClip4(const QMimeData* data)
}
UMLScene *currentScene = UMLApp::app()->currentView()->umlScene();
- if(diagramType != currentScene->type()) {
- if(!checkPasteWidgets(widgets)) {
- while (!assocs.isEmpty()) {
- delete assocs.takeFirst();
- }
- return false;
- }
- }
idchanges = doc->changeLog();
if(!idchanges) {
@@ -739,45 +731,6 @@ bool UMLClipboard::pasteClip5(const QMimeData* data)
}
/**
- * When pasting widgets see if they can be pasted on
- * different diagram types. Will return true if all the
- * widgets to be pasted can be. At the moment this only
- * includes NoteWidgets and lines of text.
- *
- * @param widgetList List of widgets to examine.
- * @return True if all widgets can be put on different diagrams.
- */
-bool UMLClipboard::checkPasteWidgets(UMLWidgetList & widgetList)
-{
- bool retval = true;
-
- foreach (UMLWidget* p, widgetList) {
- switch(p->baseType()) {
- case WidgetBase::wt_Note:
- break;
-
- case WidgetBase::wt_Text:
- {
- FloatingTextWidget *ft = static_cast<FloatingTextWidget*>(p);
- if (ft->textRole() != Uml::TextRole::Floating) {
- widgetList.removeAll(p);
- delete ft;
- retval = false;
- }
- }
- break;
-
- default:
- widgetList.removeAll(p);
- delete p;
- retval = false;
- break;
- }
- }
- return retval;
-}
-
-/**
* Gives a `sorry' message box if you're pasting an item which
* already exists and can't be duplicated.
*/
diff --git a/umbrello/clipboard/umlclipboard.h b/umbrello/clipboard/umlclipboard.h
index c1bf639..b67d6ab 100644
--- a/umbrello/clipboard/umlclipboard.h
+++ b/umbrello/clipboard/umlclipboard.h
@@ -60,8 +60,6 @@ private:
bool pasteClip4(const QMimeData* data);
bool pasteClip5(const QMimeData* data);
- bool checkPasteWidgets(UMLWidgetList & widgetList);
-
UMLObjectList m_ObjectList;
UMLListViewItemList m_ItemList;
UMLWidgetList m_WidgetList;
diff --git a/umbrello/clipboard/umldragdata.cpp b/umbrello/clipboard/umldragdata.cpp
index 846b210..99cd27e 100644
--- a/umbrello/clipboard/umldragdata.cpp
+++ b/umbrello/clipboard/umldragdata.cpp
@@ -548,6 +548,25 @@ bool UMLDragData::decodeClip4(const QMimeData* mimeData, UMLObjectList& objects,
continue;
}
+ // check if widget is pastable
+ if (sourceView->umlScene()->type() != scene->type()) {
+ UMLObject *object = widget->umlObject();
+ if (object) {
+ if (!Model_Utils::typeIsAllowedInDiagram(object, scene)) {
+ delete widget;
+ widgetNode = widgetNode.nextSibling();
+ widgetElement = widgetNode.toElement();
+ continue;
+ }
+ }
+ else if (!Model_Utils::typeIsAllowedInDiagram(widget, scene)) {
+ delete widget;
+ widgetNode = widgetNode.nextSibling();
+ widgetElement = widgetNode.toElement();
+ continue;
+ }
+ }
+
// Generate a new unique 'local ID' so a second widget for the same
// UMLObject can be distinguished from the first widget
widget->setLocalID(doc->assignNewID(widget->localID()));
@@ -570,6 +589,9 @@ bool UMLDragData::decodeClip4(const QMimeData* mimeData, UMLObjectList& objects,
widgetElement = widgetNode.toElement();
}
+ if (widgets.size() == 0)
+ return false;
+
IDChangeLog* log = doc->changeLog();
// Make sure all object widgets are loaded before adding messages or
diff --git a/umbrello/model_utils.cpp b/umbrello/model_utils.cpp
index 2bb48ca..862aa87 100644
--- a/umbrello/model_utils.cpp
+++ b/umbrello/model_utils.cpp
@@ -12,6 +12,7 @@
#include "model_utils.h"
// app includes
+#include "floatingtextwidget.h"
#include "debug_utils.h"
#include "umlobject.h"
#include "umlpackagelist.h"
@@ -1864,5 +1865,50 @@ bool typeIsAllowedInDiagram(UMLObject* o, UMLScene *scene)
return bAccept;
}
+/**
+ * Return true if the widget type is allowed in the related diagram
+ * @param w UML widget object
+ * @param scene diagram instance
+ * @return true type is allowed
+ * @return false type is not allowed
+ */
+bool typeIsAllowedInDiagram(UMLWidget* w, UMLScene *scene)
+{
+ UMLWidget::WidgetType wt = w->baseType();
+ Uml::DiagramType::Enum diagramType = scene->type();
+ bool bAccept = true;
+
+ // TODO: check additional widgets
+ switch (diagramType) {
+ case Uml::DiagramType::Activity:
+ case Uml::DiagramType::Class:
+ case Uml::DiagramType::Collaboration:
+ case Uml::DiagramType::Component:
+ case Uml::DiagramType::Deployment:
+ case Uml::DiagramType::EntityRelationship:
+ case Uml::DiagramType::Sequence:
+ case Uml::DiagramType::State:
+ case Uml::DiagramType::UseCase:
+ default:
+ switch(wt) {
+ case WidgetBase::wt_Note:
+ break;
+ case WidgetBase::wt_Text:
+ {
+ FloatingTextWidget *ft = dynamic_cast<FloatingTextWidget*>(w);
+ if (ft && ft->textRole() != Uml::TextRole::Floating) {
+ bAccept = false;
+ }
+ }
+ break;
+ default:
+ bAccept = false;
+ break;
+ }
+ break;
+ }
+ return bAccept;
+}
+
} // namespace Model_Utils
diff --git a/umbrello/model_utils.h b/umbrello/model_utils.h
index c73db0f..960b1a2 100644
--- a/umbrello/model_utils.h
+++ b/umbrello/model_utils.h
@@ -77,6 +77,7 @@ bool typeIsClassifier(UMLListViewItem::ListViewType type);
bool typeIsAllowedInType(UMLListViewItem::ListViewType childType,
UMLListViewItem::ListViewType parentType);
bool typeIsAllowedInDiagram(UMLObject *o, UMLScene *scene);
+bool typeIsAllowedInDiagram(UMLWidget *w, UMLScene *scene);
Uml::ModelType::Enum convert_DT_MT(Uml::DiagramType::Enum dt);
UMLListViewItem::ListViewType convert_MT_LVT(Uml::ModelType::Enum mt);