Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Commit 5a05d35e authored by Ralf Habacker's avatar Ralf Habacker

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
parent 66ed3476
......@@ -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) {
......@@ -738,45 +730,6 @@ bool UMLClipboard::pasteClip5(const QMimeData* data)
return result;
}
/**
* 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.
......
......@@ -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;
......
......@@ -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
......
......@@ -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
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment