Commit 576a4346 authored by Ralf Habacker's avatar Ralf Habacker
Browse files

Refactor UMLInstance to be more UML and XMI 1.4 compatible.

- Create classifier instance on construction if not present
  and save it internal instead to be a non sharable classifier.
  Class UMLInstance itself stays to be derived from UMLClassifier
  because of the usage of UMLAttribute representing instance
  attributes.
- Save and load 'classifier' attribute to be xmi 1.4 compatible

CCBUG:123633
parent c499bfff
......@@ -255,8 +255,6 @@ add_unstable_feature(XMIRESOLUTION) # see https://bugs.kde.org/show_bug.cgi?id=9
# Current object diagram implementation does not follow UML 1.4 standard
# because of using umbrello specific XMI tag (UML:InstanceAttribute).
# Additional UMLInstance is the classifier and do not references a classifier
# which creates non sharable and incomplete classifiers.
add_unstable_feature(OBJECT_DIAGRAM) # see https://bugs.kde.org/show_bug.cgi?id=123633
if(LIBXSLT_FOUND AND LIBXML2_FOUND)
......
......@@ -334,10 +334,10 @@ set(libcmds_SRCS
cmds/cmdremovediagram.cpp
cmds/cmdsetstereotype.cpp
cmds/cmdsetvisibility.cpp
cmds/generic/cmdrenameumlinstancetype.cpp
cmds/generic/cmdcreateumlobject.cpp
cmds/generic/cmdremoveumlobject.cpp
cmds/generic/cmdrenameumlobject.cpp
cmds/generic/cmdrenameumlinstance.cpp
cmds/widget/cmdbasewidgetcommand.cpp
cmds/widget/cmdchangefont.cpp
cmds/widget/cmdchangetextcolor.cpp
......
......@@ -26,8 +26,8 @@
************************************************************/
#include "cmds/generic/cmdcreateumlobject.h"
#include "cmds/generic/cmdremoveumlobject.h"
#include "cmds/generic/cmdrenameumlinstancetype.h"
#include "cmds/generic/cmdrenameumlobject.h"
#include "cmds/generic/cmdrenameumlinstance.h"
/************************************************************
* Widgets
......
......@@ -4,13 +4,13 @@
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* copyright (C) 2002-2016 *
* copyright (C) 2017 *
* Umbrello UML Modeller Authors <umbrello-devel@kde.org> *
***************************************************************************/
#include "cmdrenameumlinstance.h"
#include "cmdrenameumlinstancetype.h"
// app includes
//app includes
#include "instance.h"
// kde includes
......@@ -18,26 +18,25 @@
namespace Uml
{
CmdRenameUMLInstance::CmdRenameUMLInstance(UMLInstance* o, const QString& name)
: m_obj(o), m_name(name)
CmdRenameUMLInstanceType::CmdRenameUMLInstanceType(UMLInstance* o, UMLClassifier *type)
: m_obj(o),
m_type(type)
{
setText(i18n("Rename object : %1 to %2", o->instanceName(), name));
m_oldname = o->instanceName();
setText(i18n("Rename type: %1 to %2", o->classifier()->name(), type->name()));
m_oldType = o->classifier();
}
CmdRenameUMLInstance::~CmdRenameUMLInstance()
CmdRenameUMLInstanceType::~CmdRenameUMLInstanceType()
{
}
void CmdRenameUMLInstance::redo()
void CmdRenameUMLInstanceType::redo()
{
m_obj->setInstanceNameCmd(m_name);
m_obj->setClassifierCmd(m_type);
}
void CmdRenameUMLInstance::undo()
void CmdRenameUMLInstanceType::undo()
{
m_obj->setInstanceName(m_oldname);
m_obj->setClassifierCmd(m_oldType);
}
}
......@@ -4,32 +4,36 @@
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* copyright (C) 2002-2016 *
* copyright (C) 2017 *
* Umbrello UML Modeller Authors <umbrello-devel@kde.org> *
***************************************************************************/
#ifndef CMD_RENAME_UMLINSTANCE_H
#define CMD_RENAME_UMLNSTANCE_H
#ifndef CMD_RENAME_UMLINSTANCE_TYPE_H
#define CMD_RENAME_UMLINSTANCE_TYPE_H
#include <QPointer>
#include <QUndoCommand>
#include <KLocalizedString>
class UMLInstance;
class UMLClassifier;
namespace Uml
{
class CmdRenameUMLInstance : public QUndoCommand
class CmdRenameUMLInstanceType : public QUndoCommand
{
public:
CmdRenameUMLInstance(UMLInstance *o, const QString& name);
~CmdRenameUMLInstance();
public:
CmdRenameUMLInstanceType(UMLInstance* o, UMLClassifier *type);
~CmdRenameUMLInstanceType();
void redo();
void undo();
void redo();
void undo();
private:
UMLInstance* m_obj;
QString m_name;
QString m_oldname;
private:
QPointer<UMLInstance> m_obj;
QPointer<UMLClassifier> m_type;
QPointer<UMLClassifier> m_oldType;
};
}
......
......@@ -94,10 +94,10 @@ ClassGeneralPage::ClassGeneralPage(UMLDoc* d, QWidget* parent, UMLObject* o)
if( t == UMLObject::ot_Instance) {
Q_ASSERT(m_pObject->asUMLInstance());
QString name = UMLObject::toI18nString(t);
m_instanceNameWidget = new UMLObjectNameWidget(name, m_pObject->asUMLInstance()->instanceName());
m_instanceNameWidget = new UMLObjectNameWidget(name, m_pObject->name());
m_instanceNameWidget->addToLayout(m_pNameLayout, 0);
QString className = UMLObject::toI18nString(UMLObject::ot_Class);
m_nameWidget = new UMLObjectNameWidget(className, m_pObject->name());
m_nameWidget = new UMLObjectNameWidget(className, m_pObject->asUMLInstance()->classifier()->name());
m_nameWidget->addToLayout(m_pNameLayout, 1);
}
else {
......@@ -310,7 +310,8 @@ void ClassGeneralPage::apply()
}
if(m_instanceNameWidget && m_pObject->isUMLInstance()) {
m_pObject->asUMLInstance()->setInstanceName(m_instanceNameWidget->text());
m_pObject->asUMLInstance()->setName(m_instanceNameWidget->text());
m_pObject->asUMLInstance()->setClassifierName(m_nameWidget->text());
}
//make sure unique name
......@@ -323,8 +324,6 @@ void ClassGeneralPage::apply()
} else {
m_pObject->setName(name);
}
} else {
m_pObject->setName(name);
}
if (t != UMLObject::ot_Stereotype) {
......
......@@ -10,45 +10,95 @@
#include "instance.h"
//local includes
#include "cmds/generic/cmdrenameumlinstance.h"
//app includes
#include "cmds.h"
#include "classifier.h"
#include "classpropertiesdialog.h"
#include "debug_utils.h"
#include "instanceattribute.h"
#include "umlinstanceattributedialog.h"
#include "umldoc.h"
#include "object_factory.h"
#include "uml.h"
#include "debug_utils.h"
#include "umldoc.h"
#include "umlinstanceattributedialog.h"
#include "uniqueid.h"
//kde includes
#include <KLocalizedString>
#include <KMessageBox>
/**
* Construct UMLInstance
* @param name Name of referenced classifier
* @param id The unique id to assign
*/
UMLInstance::UMLInstance(const QString &name, Uml::ID::Type id)
: UMLClassifier(name, id)
: UMLClassifier(QString(), id)
{
m_BaseType = UMLObject::ot_Instance;
if (UMLApp::app()->document()->loading())
return;
UMLClassifier *c = Object_Factory::createUMLObject(UMLObject::ot_Class, name)->asUMLClassifier();
Q_ASSERT(c);
m_classifier = c;
}
QString UMLInstance::instanceName() const
/**
* Set undoable type name
* This method is used from property dialogs.
* @param name type name to set
*/
void UMLInstance::setClassifierName(const QString &name)
{
return m_instanceName;
if (m_classifier->name() == name || m_classifier->fullyQualifiedName() == name)
return;
UMLClassifier *c = Object_Factory::createUMLObject(UMLObject::ot_Class, name)->asUMLClassifier();
Q_ASSERT(c);
UMLApp::app()->executeCommand(new Uml::CmdRenameUMLInstanceType(this, c));
m_classifier = c;
emitModified();
}
/**
* @brief UMLObject::setInstanceName
* Set object/instance name in case of a Object Diagram
* return type name
* @return type name
*/
void UMLInstance::setInstanceName(const QString &strName)
QString UMLInstance::classifierName()
{
if(instanceName() != strName)
UMLApp::app()->executeCommand(new Uml::CmdRenameUMLInstance(this, strName));
return m_classifier->name();
}
/**
* Set undoable classifier
* @param classifier
*/
void UMLInstance::setClassifier(UMLClassifier *classifier)
{
if (m_classifier == classifier)
return;
UMLApp::app()->executeCommand(new Uml::CmdRenameUMLInstanceType(this, classifier));
m_classifier = classifier;
emitModified();
}
void UMLInstance::setInstanceNameCmd(const QString &strName)
/**
* Set classifier
* @param classifier
*/
void UMLInstance::setClassifierCmd(UMLClassifier *classifier)
{
m_instanceName = strName;
if (m_classifier == classifier)
return;
m_classifier = classifier;
emitModified();
}
UMLClassifier *UMLInstance::classifier()
{
return m_classifier;
}
UMLAttribute *UMLInstance::createAttribute(const QString &name, UMLObject *type, Uml::Visibility::Enum vis, const QString &init)
{
Uml::ID::Type id = UniqueID::gen();
......@@ -97,7 +147,7 @@ UMLAttribute *UMLInstance::createAttribute(const QString &name, UMLObject *type,
void UMLInstance::saveToXMI1(QDomDocument &qDoc, QDomElement &qElement)
{
QDomElement instanceElement = UMLObject::save1(QLatin1String("UML:Instance"), qDoc);
instanceElement.setAttribute(QLatin1String("instancename"), m_instanceName);
instanceElement.setAttribute(QLatin1String("classifier"), Uml::ID::toString(m_classifier->id()));
//save attributes
UMLClassifierListItemList instanceAttributes = getFilteredList(UMLObject::ot_InstanceAttribute);
UMLClassifierListItem* pInstanceAttribute = 0;
......@@ -112,7 +162,7 @@ void UMLInstance::saveToXMI1(QDomDocument &qDoc, QDomElement &qElement)
*/
bool UMLInstance::load1(QDomElement &element)
{
m_instanceName = element.attribute(QLatin1String("instancename"));
m_SecondaryId = element.attribute(QLatin1String("classifier"));
QDomNode node = element.firstChild();
while(!node.isNull()) {
if (node.isComment()) {
......@@ -132,3 +182,34 @@ bool UMLInstance::load1(QDomElement &element)
}//end while
return true;
}
/**
* Resolve forwared declaration of referenced classifier hold in m_pSecondaryId
* after loading object from xmi file.
* @return true - resolve was successful
* @return false - resolve was not successful
*/
bool UMLInstance::resolveRef()
{
if (!UMLClassifier::resolveRef())
return false;
if (!m_pSecondary)
return false;
UMLClassifier *c = m_pSecondary->asUMLClassifier();
Q_ASSERT(c);
m_classifier = c;
m_pSecondary = 0;
return true;
}
/**
* Display the properties configuration dialog.
* @param parent Parent widget
* @return true - configuration has been applied
* @return false - configuration has not been applied
*/
bool UMLInstance::showPropertiesDialog(QWidget* parent)
{
ClassPropertiesDialog dialog(parent, this);
return dialog.exec();
}
......@@ -28,9 +28,12 @@ class UMLInstance : public UMLClassifier
public:
explicit UMLInstance(const QString& name = QString(), Uml::ID::Type id = Uml::ID::None);
QString instanceName() const;
virtual void setInstanceName(const QString &strName);
void setInstanceNameCmd(const QString &strName);
void setClassifierName(const QString &name);
QString classifierName();
void setClassifier(UMLClassifier *classifier);
void setClassifierCmd(UMLClassifier *classifier);
UMLClassifier *classifier();
virtual UMLAttribute* createAttribute(const QString &name = QString(),
UMLObject *type = 0, Uml::Visibility::Enum vis = Uml::Visibility::Private,
......@@ -38,9 +41,13 @@ public:
virtual void saveToXMI1(QDomDocument& qDoc, QDomElement& qElement);
protected:
bool load1(QDomElement& element);
QString m_instanceName; ///< objects instance
virtual bool resolveRef();
bool showPropertiesDialog(QWidget *parent);
QPointer<UMLClassifier> m_classifier;
};
#endif // UMLINSTANCE_H
......@@ -268,8 +268,7 @@ void AssociationWidget::setUMLObject(UMLObject *obj)
this, SLOT(slotClassifierListItemRemoved(UMLClassifierListItem*)));
break;
case UMLObject::ot_InstanceAttribute:
klass = obj->umlParent()->asUMLInstance();
connect(klass, SIGNAL(attributeRemoved()), this, SLOT(slotClassifierListItemRemoved()));
connect(obj->umlParent(), SIGNAL(attributeRemoved()), this, SLOT(slotClassifierListItemRemoved()));
attr = obj->asUMLInstanceAttribute();
connect(attr, SIGNAL(attributeChanged()), this, SLOT(slotAttributeChanged()));
break;
......
......@@ -511,14 +511,22 @@ QSizeF ClassifierWidget::calculateSize(bool withExtensions /* = true */) const
height += fontHeight;
// ... width
QString name;
UMLObject *o;
if (m_umlObject && m_umlObject->isUMLInstance() && m_umlObject->asUMLInstance()->classifier())
o = m_umlObject->asUMLInstance()->classifier();
else
o = m_umlObject;
if (!o)
name = m_Text;
else
if (visualProperty(ShowPackage))
name = m_umlObject->fullyQualifiedName();
name = o->fullyQualifiedName();
else
name = m_umlObject->name();
name = o->name();
QString displayedName;
if (m_umlObject->isUMLInstance())
displayedName = m_umlObject->asUMLInstance()->instanceName() + QLatin1String(" : ") + name;
displayedName = m_umlObject->name() + QLatin1String(" : ") + name;
else
displayedName = name;
......@@ -785,15 +793,21 @@ void ClassifierWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *
// draw name
QString name;
if (visualProperty(ShowPackage)) {
name = m_umlObject->fullyQualifiedName();
} else {
name = m_umlObject->name();
}
UMLObject *o;
if (m_umlObject && m_umlObject->isUMLInstance() && m_umlObject->asUMLInstance()->classifier())
o = m_umlObject->asUMLInstance()->classifier();
else
o = m_umlObject;
if (!o)
name = m_Text;
else if (visualProperty(ShowPackage))
name = o->fullyQualifiedName();
else
name = o->name();
QString displayedName;
if (m_umlObject->isUMLInstance())
displayedName = m_umlObject->asUMLInstance()->instanceName() + QLatin1String(" : ") + name;
displayedName = m_umlObject->name() + QLatin1String(" : ") + name;
else
displayedName = name;
......
......@@ -135,6 +135,9 @@ UMLWidget *createWidget(UMLScene *scene, UMLObject *o)
}
break;
case UMLObject::ot_Class:
if (diagramType == Uml::DiagramType::Object)
break;
//see if we really want an object widget or class widget
if (diagramType == Uml::DiagramType::Class || diagramType == Uml::DiagramType::Component) {
UMLClassifier *c = o->asUMLClassifier();
......
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