Commit c7fdfefc authored by Oliver Kellogg's avatar Oliver Kellogg
Browse files

Create branch work/73847-tagged-uml from master@9817ffc :

umbrello/basictypes.h
- New namespace PrimitiveTypes encapsulates basic element of the
  support for UML primitive types:
  - enum Enum lists the available primitive types plus a final value
    Reserved which is used for determining the number of values.
  - Integer constant n_types acts as synonym for Reserved.
  - Functions toString convert an Enum or equivalent integer value
    to the corresponding string.
  - Function fromString converts a string to the corresponding Enum.
    If the string doe not correspond to an Enum value then the value
    Reserved is returned.
  - Function fromInt converts an integer position number to the Enum
    value at that position.
- At ProgrammingLanguage::Enum value `Reserved' document that this is
  now used for selecting the UML Primitive Types.

umbrello/basictypes.cpp
- Implement the functions in new namespace PrimitiveTypes.
- In namespace ProgrammingLanguage function toString return "none"
  for the Reserved value.

umbrello/uml1model/stereotype.{h,cpp}
- Class AttributeDef defines a stereotype attribute.
- Type AttributeDefs is a QVector of AttributeDef.
  This is the type used by the new protected member m_attrDefs.
- Function clearAttributeDefs clears m_attrDefs.
- Function setAttributeDefs sets m_attrDefs.
- Function getAttributeDefs() returns m_attrDefs.
- Function load1 loads m_attrDefs from XMI.
- Function saveToXMI1 is extended to save m_attrDefs to XMI.

umbrello/model_utils.cpp
- In function isCommonDataType case (gen == 0) return true to reflect
  the fact that UML primitive types are common types.

umbrello/dialogs/stereoattributedialog.{h,cpp}
- Dialog for specifying up to N_STEREOATTRS stereotype attributes.
  A stereotype attribute has a name and type.
  The type can be chosen from among the UML Primitive Types.

umbrello/stereotypeswindow.cpp
- Extend function contextMenuEvent so that if the user clicks on an
  existing stereotype row then a StereoAttributeDialog is opened
  which permits to define the attributes for the selected stereotype.

umbrello/codegenwizard/codegenoptionspage.cpp
- In function setupActiveLanguageBox while-loop, include
  Uml::ProgrammingLanguage::Reserved in the range covered by
  indexCounter.
- In function updateCodeGenerationPolicyTab, do not call
  CodeGenFactory::newCodeGenPolicyExt(pl) if pl is
  Uml::ProgrammingLanguage::Reserved.

umbrello/umldoc.cpp
- In function loadExtensionsFromXMI1 decoding of tag "codegeneration",
  the cgelement attribute "language" may now assume the value "none"
  to denote that the UML primitive types are selected. In this case do
  not attempt setting a code generator.
- In function addDefaultDatatypes, if UMLApp::app()->generator() returns
  null on entry then this causes the UML primitive types to be created.

umbrello/uml.h
- In private slots declare void setLang_none().
- At declaration of m_langAct increase array size by 1 to accomodate
  the action for Uml::ProgrammingLanguage::Reserved.

umbrello/uml.cpp
- In function initActions(),
  - call setProgLangAction for associating Uml::ProgrammingLanguage::
    Reserved with the action "setLang_none";
  - connect m_langAct[Uml::ProgrammingLanguage::Reserved] trigger with
    the setLang_none slot.
- In function setGenerator :
  - Remove early actions / early return on
    (pl == Uml::ProgrammingLanguage::Reserved).
  - If pl is Uml::ProgrammingLanguage::Reserved then avoid allocating
    and calling functions on m_codegen. The only actions taken in this
    case are: Set m_activeLanguage, call updateLangSelectMenu(pl),
    call slotAddDefaultDatatypes().
- Define added slot setLang_none to call
  setActiveLanguage(Uml::ProgrammingLanguage::Reserved).
- In function updateLangSelectMenu include Uml::ProgrammingLanguage::
  Reserved in the range covered by for-loop variable `i'.

umbrello/main.cpp
- In for-loop constructing the "set-language-" options include
  Uml::ProgrammingLanguage::Reserved in the iteration in order to
  construct "set-language-none".
- In for-loop listing the supported languages for option "--languages"
  include Uml::ProgrammingLanguage::Reserved in the iteration.

umbrello/uml1model/umlobject.h
- Add member m_TaggedValues of type QStringList.

umbrello/uml1model/umlobject.cpp   WORK IN PROGRESS
- In function save1 add saving of m_TaggedValues (if non empty).
  This creates a new subelement, <UML:ModelElement.taggedValues> in
  which the <UML:TaggedValue> elements are embedded.
- In function loadFromXMI1 add loading of subelement
  <UML:ModelElement.taggedValues> with nested elements
  <UML:TaggedValue>.

umbrello/CMakeLists.txt
- On setting libdialogs_SRCS include new file
  dialogs/stereoattributedialog.cpp.

umbrello/umbrelloui.rc.cmake
- In menu "code" submenu "active_lang_menu" add action "setLang_none".

umbrello/version.h
- Increase XMI_FILE_VERSION to "1.6.20" due to added <UML:Attribute>
  subelements of <UML:Stereotype>.

CCBUG: 73847
parent 9817ffc9
......@@ -209,6 +209,7 @@ set(libdialogs_SRCS
dialogs/settingsdialog.cpp
dialogs/singlepagedialogbase.cpp
dialogs/statedialog.cpp
dialogs/stereoattributedialog.cpp
dialogs/umlattributedialog.cpp
dialogs/umlinstanceattributedialog.cpp
dialogs/umlcheckconstraintdialog.cpp
......
......@@ -865,6 +865,57 @@ Enum fromInt(int item)
//-----------------------------------------------------------------------------
namespace PrimitiveTypes {
const char *strings[] = {
"String",
"Boolean",
"UnlimitedNatural",
"Integer",
"Real",
"not_a_primitivetype"
};
QString toString(Enum item)
{
return QLatin1String(strings[item]);
}
QString toString(int item)
{
if (item < 0 || item >= n_types)
return QLatin1String(strings[Reserved]);
return QLatin1String(strings[item]);
}
/**
* Converts the string of an Enum to the Enum value.
* @param item The string to convert to Enum
* @param strict Controls the value returned if the given string does not
* represent an Enum value: If strict is true then the value
* Reserved is returned, otherwise the value String is
* returned.
*/
Enum fromString(const QString& item, bool strict /* = false */)
{
for (int i = 0; i < n_types; i++) {
if (item == toString(i))
return Enum(i);
}
return (strict ? Reserved : String);
}
Enum fromInt(int item)
{
if (item < 0 || item >= n_types)
return Reserved;
return Enum(item);
}
} // end namespace PrimitiveTypes
//-----------------------------------------------------------------------------
namespace ProgrammingLanguage {
/**
......@@ -916,7 +967,7 @@ QString toString(Enum item)
default:
break;
}
return QString();
return QLatin1String("none");
}
/**
......
......@@ -263,6 +263,28 @@ namespace Uml
Enum fromInt(int item);
}
/**
* UML primitive types
*/
namespace PrimitiveTypes
{
enum Enum {
String,
Boolean,
UnlimitedNatural,
Integer,
Real,
Reserved
};
const int n_types = int(Reserved);
QString toString(Enum item);
QString toString(int item);
Enum fromString(const QString& item, bool strict = false);
Enum fromInt(int item);
}
/**
* Supported programming languages.
*/
......@@ -289,7 +311,7 @@ namespace Uml
Tcl,
Vala,
XMLSchema,
Reserved
Reserved // for UML Primitive Types (no code generator)
};
QString toString(Enum item);
Enum fromString(const QString& item);
......
......@@ -89,7 +89,7 @@ CodeGenOptionsPage::~CodeGenOptionsPage()
void CodeGenOptionsPage::setupActiveLanguageBox()
{
int indexCounter = 0;
while (indexCounter < Uml::ProgrammingLanguage::Reserved) {
while (indexCounter <= Uml::ProgrammingLanguage::Reserved) {
QString language = Uml::ProgrammingLanguage::toString(Uml::ProgrammingLanguage::fromInt(indexCounter));
ui_SelectLanguageBox->insertItem(indexCounter, language);
indexCounter++;
......@@ -188,7 +188,9 @@ void CodeGenOptionsPage::updateCodeGenerationPolicyTab()
}
Uml::ProgrammingLanguage::Enum pl = Uml::ProgrammingLanguage::fromInt(ui_SelectLanguageBox->currentIndex());
CodeGenPolicyExt *policyExt = CodeGenFactory::newCodeGenPolicyExt(pl);
CodeGenPolicyExt *policyExt = 0;
if (pl != Uml::ProgrammingLanguage::Reserved)
policyExt = CodeGenFactory::newCodeGenPolicyExt(pl);
if (policyExt) {
m_pCodePolicyPage = policyExt->createPage(0, "codelangpolicypage");
......
/***************************************************************************
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* copyright (C) 2020 *
* Umbrello UML Modeller Authors <umbrello-devel@kde.org> *
***************************************************************************/
// own header
#include "stereoattributedialog.h"
// app includes
#include "stereotype.h"
#include "umldoc.h"
#include "uml.h"
#include "dialog_utils.h"
#include "debug_utils.h"
// kde includes
#include <klineedit.h>
#include <kcombobox.h>
#include <kcompletion.h>
#include <KLocalizedString>
#include <KMessageBox>
// qt includes
#include <QGridLayout>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLayout>
#include <QLabel>
#include <QGroupBox>
#include <QComboBox>
#include <QDialogButtonBox>
StereoAttributeDialog::StereoAttributeDialog(QWidget *parent, UMLStereotype *stereotype)
: SinglePageDialogBase(parent)
{
setCaption(i18n("Stereotype Properties"));
m_pStereotype = stereotype;
setupDialog();
}
StereoAttributeDialog::~StereoAttributeDialog()
{
}
/**
* Sets up the dialog
*/
void StereoAttributeDialog::setupDialog()
{
int margin = fontMetrics().height();
QFrame * frame = new QFrame(this);
setMainWidget(frame);
QVBoxLayout * mainLayout = new QVBoxLayout(frame);
m_pValuesGB = new QGroupBox(i18n("Stereotype Attributes for ") + m_pStereotype->name(true),
frame);
QGridLayout * valuesLayout = new QGridLayout(m_pValuesGB);
valuesLayout->setMargin(margin);
valuesLayout->setSpacing(10);
/*
QLabel *m_pNameLabel[N_STEREOATTRS];
KLineEdit *m_pNameEdit [N_STEREOATTRS];
QLabel *m_pTypeLabel[N_STEREOATTRS];
QComboBox *m_pTypeCombo[N_STEREOATTRS];
*/
const UMLStereotype::AttributeDefs& adefs = m_pStereotype->getAttributeDefs();
for (int row = 0; row < N_STEREOATTRS; row++) {
Dialog_Utils::makeLabeledEditField(valuesLayout, row,
m_pNameLabel[row], i18nc("attribute name", "&Name:"),
m_pNameEdit[row]); // columns 0, 1
m_pTypeLabel[row] = new QLabel(i18nc("attribute type", "Type:"));
valuesLayout->addWidget(m_pTypeLabel[row], row, 2); // column 2
m_pTypeCombo[row] = new QComboBox(this);
for (int type = 0; type < Uml::PrimitiveTypes::n_types; type++) {
m_pTypeCombo[row]->addItem(Uml::PrimitiveTypes::toString(type));
}
valuesLayout->addWidget(m_pTypeCombo[row], row, 3); // column 3
m_pTypeLabel[row]->setBuddy(m_pTypeCombo[row]);
if (adefs.count() > row) {
const UMLStereotype::AttributeDef& adef = adefs.at(row);
if (!adef.name.isEmpty()) {
m_pNameEdit[row]->setText(adef.name.trimmed());
int type = int(adef.type);
if (type >= 0 && type < m_pTypeCombo[row]->count())
m_pTypeCombo[row]->setCurrentIndex(type);
else
uDebug() << "StereoAttributeDialog::setupDialog: Illegal type " << type;
}
}
}
mainLayout->addWidget(m_pValuesGB);
}
/**
* Used when the OK button is clicked. Applies the stereotype attribute changes.
*/
bool StereoAttributeDialog::apply()
{
m_pStereotype->clearAttributeDefs();
UMLStereotype::AttributeDefs adefs;
for (int i = 0; i < N_STEREOATTRS; i++) {
QString name = m_pNameEdit[i]->text().trimmed();
if (!name.isEmpty()) {
int typeIndex = m_pTypeCombo[i]->currentIndex();
if (typeIndex < 0)
typeIndex = 0;
UMLStereotype::AttributeDef attrDef(name, Uml::PrimitiveTypes::Enum(typeIndex));
adefs.append(attrDef);
}
}
if (adefs.count())
m_pStereotype->setAttributeDefs(adefs);
return true;
}
/***************************************************************************
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* copyright (C) 2020 *
* Umbrello UML Modeller Authors <umbrello-devel@kde.org> *
***************************************************************************/
#ifndef STEREOATTRIBUTEDIALOG_H
#define STEREOATTRIBUTEDIALOG_H
#include "singlepagedialogbase.h"
class QGroupBox;
class QLabel;
class KLineEdit;
class QComboBox;
class UMLStereotype;
/**
* @author Oliver Kellogg
* Bugs and comments to umbrello-devel@kde.org or https://bugs.kde.org
*/
class StereoAttributeDialog : public SinglePageDialogBase
{
Q_OBJECT
public:
StereoAttributeDialog(QWidget *parent, UMLStereotype *stereotype);
~StereoAttributeDialog();
protected:
void setupDialog();
bool apply();
/**
* The Stereotype to represent
*/
UMLStereotype *m_pStereotype;
#define N_STEREOATTRS 3
//GUI Widgets
QGroupBox * m_pValuesGB;
QLabel * m_pNameLabel[N_STEREOATTRS];
KLineEdit * m_pNameEdit [N_STEREOATTRS];
QLabel * m_pTypeLabel[N_STEREOATTRS];
QComboBox * m_pTypeCombo[N_STEREOATTRS];
};
#endif
......@@ -159,7 +159,7 @@ int main(int argc, char *argv[])
options.add("languages", i18n("list supported languages"));
options.add("use-folders", i18n("keep the tree structure used to store the views in the document in the target directory"));
options.add("import-directory <dir>", i18n("import files from directory <dir>"));
for(int i = Uml::ProgrammingLanguage::ActionScript; i < Uml::ProgrammingLanguage::Reserved; i++) {
for (int i = Uml::ProgrammingLanguage::ActionScript; i <= Uml::ProgrammingLanguage::Reserved; i++) {
Uml::ProgrammingLanguage::Enum pl = Uml::ProgrammingLanguage::fromInt(i);
QByteArray optionString = "set-language-" + Uml::ProgrammingLanguage::toString(pl).toLower().toLocal8Bit();
options.add(optionString, i18n("set active language"));
......@@ -184,7 +184,7 @@ int main(int argc, char *argv[])
fprintf(stdout, "%s\n", qPrintable(type));
return 0;
} else if (args->isSet("languages")) {
for(int i = Uml::ProgrammingLanguage::ActionScript; i < Uml::ProgrammingLanguage::Reserved; i++) {
for (int i = Uml::ProgrammingLanguage::ActionScript; i <= Uml::ProgrammingLanguage::Reserved; i++) {
Uml::ProgrammingLanguage::Enum pl = Uml::ProgrammingLanguage::fromInt(i);
fprintf(stdout, "%s\n", qPrintable(Uml::ProgrammingLanguage::toString(pl)));
}
......
......@@ -787,7 +787,7 @@ bool isCommonDataType(QString type)
{
CodeGenerator *gen = UMLApp::app()->generator();
if (gen == 0)
return false;
return true; // gen == NULL means we use UMLPrimitiveTypes
const bool caseSensitive = UMLApp::app()->activeLanguageIsCaseSensitive();
const QStringList dataTypes = gen->defaultDatatypes();
QStringList::ConstIterator end(dataTypes.end());
......
......@@ -12,8 +12,10 @@
// app includes
#include "dialog_utils.h"
#include "debug_utils.h"
#include "stereotype.h"
#include "models/stereotypesmodel.h"
#include "dialogs/stereoattributedialog.h"
#include "uml.h"
#include "umldoc.h"
......@@ -24,6 +26,7 @@
#include <QHeaderView>
#include <QTableView>
#include <QSortFilterProxyModel>
#include <QContextMenuEvent>
#include <QtDebug>
StereotypesWindow::StereotypesWindow(const QString &title, QWidget *parent)
......@@ -76,7 +79,25 @@ void StereotypesWindow::slotStereotypesDoubleClicked(QModelIndex index)
void StereotypesWindow::contextMenuEvent(QContextMenuEvent *event)
{
Q_UNUSED(event);
const QPoint& pos = event->pos();
int row = m_stereotypesTree->rowAt(pos.y() - 60);
// Apparently we need the "- 60" to subtract height of title lines "Stereotypes", "Name / Usage"
uDebug() << "StereotypesWindow::contextMenuEvent: "
<< " pos =" << event->pos() << ", row =" << row;
if (row >= 0) {
QModelIndex index = m_stereotypesTree->model()->index(row, 0); // first column
uDebug() << "StereotypesWindow::contextMenuEvent: QModelIndex " << index;
QVariant v = m_stereotypesTree->model()->data(index, Qt::UserRole);
if (v.canConvert<UMLStereotype*>()) {
UMLStereotype *s = v.value<UMLStereotype*>();
StereoAttributeDialog *dialog = new StereoAttributeDialog(this, s);
dialog->exec();
delete dialog;
} else {
uDebug() << "StereotypesWindow::contextMenuEvent: QVariant::canConvert returns false";
}
return;
}
QString name;
if (!Dialog_Utils::askDefaultNewName(UMLObject::ot_Stereotype, name))
return;
......
......@@ -75,6 +75,7 @@
<Action name="setLang_tcl"/>
<Action name="setLang_vala"/>
<Action name="setLang_xmlschema"/>
<Action name="setLang_none"/>
</Menu>
<Separator/>
<Action name="create_default_datatypes"/>
......
......@@ -395,6 +395,7 @@ void UMLApp::initActions()
setProgLangAction(Uml::ProgrammingLanguage::Tcl, "Tcl", "setLang_tcl");
setProgLangAction(Uml::ProgrammingLanguage::Vala, "Vala", "setLang_vala");
setProgLangAction(Uml::ProgrammingLanguage::XMLSchema, "XMLSchema", "setLang_xmlschema");
setProgLangAction(Uml::ProgrammingLanguage::Reserved, "none", "setLang_none");
connect(m_langAct[Uml::ProgrammingLanguage::ActionScript], SIGNAL(triggered()), this, SLOT(setLang_actionscript()));
connect(m_langAct[Uml::ProgrammingLanguage::Ada], SIGNAL(triggered()), this, SLOT(setLang_ada()));
......@@ -416,6 +417,7 @@ void UMLApp::initActions()
connect(m_langAct[Uml::ProgrammingLanguage::Tcl], SIGNAL(triggered()), this, SLOT(setLang_tcl()));
connect(m_langAct[Uml::ProgrammingLanguage::Vala], SIGNAL(triggered()), this, SLOT(setLang_vala()));
connect(m_langAct[Uml::ProgrammingLanguage::XMLSchema], SIGNAL(triggered()), this, SLOT(setLang_xmlschema()));
connect(m_langAct[Uml::ProgrammingLanguage::Reserved], SIGNAL(triggered()), this, SLOT(setLang_none()));
fileNew->setToolTip(i18n("Creates a new document"));
fileOpen->setToolTip(i18n("Opens an existing document"));
......@@ -2310,13 +2312,6 @@ CodeGenPolicyExt *UMLApp::policyExt() const
*/
CodeGenerator *UMLApp::setGenerator(Uml::ProgrammingLanguage::Enum pl)
{
if (pl == Uml::ProgrammingLanguage::Reserved) {
if (m_codegen) {
delete m_codegen;
m_codegen = 0;
}
return 0;
}
if (m_codegen) {
// Do not return a possible preexisting code generator:
// if (m_codegen->language() == pl) return m_codegen;
......@@ -2331,14 +2326,17 @@ CodeGenerator *UMLApp::setGenerator(Uml::ProgrammingLanguage::Enum pl)
m_codegen = 0;
}
m_activeLanguage = pl;
m_codegen = CodeGenFactory::createObject(pl);
if (pl != Uml::ProgrammingLanguage::Reserved) {
m_codegen = CodeGenFactory::createObject(pl);
}
updateLangSelectMenu(pl);
slotAddDefaultDatatypes();
m_codegen->createDefaultStereotypes();
if (m_policyext) {
m_policyext->setDefaults(false); // picks up language specific stuff
if (pl != Uml::ProgrammingLanguage::Reserved) {
m_codegen->createDefaultStereotypes();
if (m_policyext) {
m_policyext->setDefaults(false); // picks up language specific stuff
}
}
return m_codegen;
}
......@@ -2491,6 +2489,11 @@ void UMLApp::setLang_xmlschema()
setActiveLanguage(Uml::ProgrammingLanguage::XMLSchema);
}
void UMLApp::setLang_none()
{
setActiveLanguage(Uml::ProgrammingLanguage::Reserved);
}
#if QT_VERSION >= 0x050000
/**
* Called when right clicking on tab widget.
......@@ -2934,7 +2937,7 @@ void UMLApp::initGenerator()
void UMLApp::updateLangSelectMenu(Uml::ProgrammingLanguage::Enum activeLanguage)
{
//m_langSelect->clear();
for (int i = 0; i < Uml::ProgrammingLanguage::Reserved; ++i) {
for (int i = 0; i <= Uml::ProgrammingLanguage::Reserved; ++i) {
m_langAct[i]->setChecked(i == activeLanguage);
}
}
......
......@@ -350,6 +350,7 @@ private slots:
void setLang_tcl();
void setLang_vala();
void setLang_xmlschema();
void setLang_none();
#if QT_VERSION >= 0x050000
void slotDiagramPopupMenu(const QPoint& point);
#endif
......@@ -448,7 +449,7 @@ private:
QAction* zoom100Action;
QAction* m_langAct[Uml::ProgrammingLanguage::Reserved];
QAction* m_langAct[Uml::ProgrammingLanguage::Reserved + 1];
#if QT_VERSION >= 0x050000
QAction* deleteSelectedWidget;
QAction* deleteDiagram;
......
......@@ -92,6 +92,38 @@ UMLObject* UMLStereotype::clone() const
return clone;
}
/**
* Reset stereotype attribute definitions to none.
*/
void UMLStereotype::clearAttributeDefs()
{
m_attrDefs.clear();
}
/**
* Setter for stereotype attribute definitions.
*/
void UMLStereotype::setAttributeDefs(const AttributeDefs& adefs)
{
m_attrDefs = adefs;
}
/**
* Const getter for stereotype attribute definitions.
*/
const UMLStereotype::AttributeDefs& UMLStereotype::getAttributeDefs() const
{
return m_attrDefs;
}
/**
* Getter for stereotype attribute definitions returning writable data.
*/
UMLStereotype::AttributeDefs& UMLStereotype::getAttributeDefs()
{
return m_attrDefs;
}
/**
* Saves to the <UML:StereoType> XMI element.
*/
......@@ -99,9 +131,56 @@ void UMLStereotype::saveToXMI1(QDomDocument& qDoc, QDomElement& qElement)
{
//FIXME: uml13.dtd compliance
QDomElement stereotypeElement = UMLObject::save1(QLatin1String("UML:Stereotype"), qDoc);
if (!m_attrDefs.isEmpty()) {
QDomElement featureElement = qDoc.createElement(QLatin1String("UML:Stereotype.feature"));
foreach (AttributeDef ad, m_attrDefs) {
QDomElement attElement = qDoc.createElement(QLatin1String("UML:Attribute"));
attElement.setAttribute(QLatin1String("name"), ad.name);
attElement.setAttribute(QLatin1String("type"), Uml::PrimitiveTypes::toString(ad.type));
featureElement.appendChild(attElement);
}
stereotypeElement.appendChild(featureElement);
}
qElement.appendChild(stereotypeElement);
}
/**
* Auxiliary to loadFromXMI:
* The loading of stereotype attributes is implemented here.
*/
bool UMLStereotype::load1(QDomElement& element)
{
if (!element.hasChildNodes()) {
return true;
}
for (QDomNode node = element.firstChild(); !node.isNull(); node = node.nextSibling()) {
if (node.isComment())
continue;
element = node.toElement();
QString tag = element.tagName();
if (UMLDoc::tagEq(tag, QLatin1String("Stereotype.feature"))) {
QDomNode attNode = element.firstChild();
QDomElement attElem = attNode.toElement();
while (!attElem.isNull()) {
tag = attElem.tagName();
if (UMLDoc::tagEq(tag, QLatin1String("Attribute"))) {
QString name = attElem.attribute(QLatin1String("name"));
QString typeStr = attElem.attribute(QLatin1String("type"));
Uml::PrimitiveTypes::Enum type = Uml::PrimitiveTypes::fromString(typeStr);
AttributeDef ad(name, type);
m_attrDefs.append(ad);
} else {
uDebug() << "UMLStereotype::::load1(" << m_name
<< "): Unknown Stereotype.feature child " << tag;
}
attNode = attNode.nextSibling();
attElem = attNode.toElement();
}
}
}
return true;
}
/**
* Display the properties configuration dialog for the stereotype
* (just a line edit).
......
......@@ -59,12 +59,31 @@ public:
QString name(bool includeAdornments=false) const;
class AttributeDef
{
public:
QString name;
Uml::PrimitiveTypes::Enum type;
AttributeDef() : type(Uml::PrimitiveTypes::String) {}
AttributeDef(QString nm, Uml::PrimitiveTypes::Enum t) : name(nm), type(t) {}
virtual ~AttributeDef() {}
};
typedef QVector<AttributeDef> AttributeDefs; ///< size is at most N_STEREOATTRS
void clearAttributeDefs();
void setAttributeDefs(const AttributeDefs& adefs);
const AttributeDefs& getAttributeDefs() const;
AttributeDefs& getAttributeDefs();
void saveToXMI1(QDomDocument& qDoc, QDomElement& qElement);