Bug 363582 - It would be nice for XMI file to have stable format.
Summary: It would be nice for XMI file to have stable format.
Status: RESOLVED FIXED
Alias: None
Product: umbrello
Classification: Applications
Component: general (show other bugs)
Version: 2.19.1 (KDE Applications 16.04.1)
Platform: Arch Linux Linux
: NOR wishlist
Target Milestone: ---
Assignee: Oliver Kellogg
URL:
Keywords:
Depends on:
Blocks: 373932
  Show dependency treegraph
 
Reported: 2016-05-27 09:20 UTC by Michał Walenciak
Modified: 2021-03-09 07:36 UTC (History)
5 users (show)

See Also:
Latest Commit:
Version Fixed In: 2.33.80 (KDE releases 21.03.80)


Attachments
xslt file for reordering xmi file (470 bytes, application/xslt+xml)
2016-06-02 09:38 UTC, Ralf Habacker
Details
canonicalize_umbrello_xmi_attributes.pl (8.82 KB, application/x-perl)
2020-12-10 06:51 UTC, Oliver Kellogg
Details
canonicalize_umbrello_xmi_attributes.pl (9.79 KB, application/x-perl)
2021-01-02 10:43 UTC, Oliver Kellogg
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Michał Walenciak 2016-05-27 09:20:08 UTC
Now with almost every save my xmi file gets many changes, mostly due to some reordering.
Example:

-  <UML:Model isLeaf="false" name="Model UML" isRoot="false" xmi.id="m1" isSpecification="false" isAbstract="false">
+  <UML:Model isRoot="false" isLeaf="false" xmi.id="m1" isAbstract="false" isSpecification="false" name="Model UML">

It would be nice to have it stable (for changes review and version controlling).
 

Reproducible: Sometimes


Actual Results:  
Unstable xmi file format.

Expected Results:  
Stable xmi file format.
Comment 1 Ralf Habacker 2016-05-27 10:45:42 UTC
(In reply to Michał Walenciak from comment #0)
> Now with almost every save my xmi file gets many changes, mostly due to some reordering.
Is that version running with KDE4 or KF5/Qt5 ?

Qt5 has an issue with ordering, see http://stackoverflow.com/questions/27378143/qt-5-produce-random-attribute-order-in-xml
Comment 2 Ralf Habacker 2016-05-31 08:03:57 UTC
From https://www.archlinux.de/?page=PackageDetails;repo=extra;arch=x86_64;pkgname=umbrello it looks that this bug has been reported for a Qt5 build.

The question is if the fix mentioned in comment 1 uses the same ordering as Qt4.
Comment 3 Ralf Habacker 2016-06-02 08:04:46 UTC
(In reply to Ralf Habacker from comment #2)
> From
> https://www.archlinux.de/?page=PackageDetails;repo=extra;arch=x86_64;
> pkgname=umbrello it looks that this bug has been reported for a Qt5 build.
> 
> The question is if the fix mentioned in comment 1 uses the same ordering as
> Qt4.

Some research returns:
1. Qt4 has a stable order between multiple saves 
2. Qt5 with seed fix has a stable attribute order between multiple saves but differs from Qt4 builds
Comment 4 Ralf Habacker 2016-06-02 09:38:58 UTC
Created attachment 99323 [details]
xslt file for reordering xmi file

The simplest solutions is to post process the generated xmi file with an xslt processer for example xsltproc. https://social.msdn.microsoft.com/Forums/en-US/a75f9afc-f4f2-44e2-afa4-dffe6ca33b0f/xslt-how-can-i-sort-attributes-in-all-tags-by-name?forum=xmlandnetfx mentions the appended xslt file for this purpose.

If someone provides a patch this feature could be integrated in umbrello. If xsltproc is available in the settings  there could be a checkbox to enable this support. On save first a temporay file will be created, then post processed and saved on the requested location.
Comment 5 Ralf Habacker 2016-06-03 08:12:38 UTC
Here are some details from the Qt bug tracker https://bugreports.qt.io/browse/QTBUG-28892
Comment 6 Christian David 2016-06-17 09:40:52 UTC
As this should be solved in Qt and patches are in review I close this bug. Thank you for reporting and finding the Qt bug report!
Comment 7 Christian David 2016-06-17 11:51:05 UTC
(In reply to Christian David from comment #6)
> As this should be solved in Qt and patches are in review I close this bug.
> Thank you for reporting and finding the Qt bug report!

Sorry for closing. I just noticed this bug was not filed for KMyMoney (only a copy was forwarded to our mailing list). Please open it again if you want to. Sorry, again.
Comment 8 Jack 2018-05-18 20:53:17 UTC
Is there any resolution to this?  I still have the problem with KMyMoney git master.  I don't use umbrello, so I don't know if the problem remains there or not.  The QT bug looks like it was closed as "out of scope" which sounds to me like it was NOT fixed.  As my concern is with KMyMoney, do I need to open a separate bug, or is there some way to treat this more generally?
Comment 9 Ralf Habacker 2018-05-22 23:50:40 UTC
Currently not. In general I see several options to fix this:
1. Use the code fragment from https://stackoverflow.com/questions/27378143/qt-5-produce-random-attribute-order-in-xml to save an ordered way.
2. use a different xml writer 
3. There is always the way to patch Qt to address this issue
4. Embed a copy of QtXml source from Qt4 and use QDomDocument from the embedded copy
Comment 10 Ralf Habacker 2018-05-28 08:58:04 UTC
> do I need to open a separate bug, or is there some way to treat this more generally?
Is suggest to open a dedicated bug in the kmymoney bug tracker because the mentioned issue could not be solved by the umbrello project.
Comment 11 Ralf Habacker 2018-07-16 23:12:20 UTC
363582(In reply to Ralf Habacker from comment #9)
> Currently not. In general I see several options to fix this:
> 3. There is always the way to patch Qt to address this issue
http://code.qt.io/cgit/qt/qtbase.git/tree/src/xml/dom/qdom.cpp#n4589 is the related code fragment writing attributes. There may be a property setting method in some of the QDom related classes to write out an alphabetic ordered attribute list.
Comment 12 Ralf Habacker 2018-07-16 23:18:03 UTC
(In reply to Ralf Habacker from comment #9)
> Currently not. In general I see several options to fix this:
> 2. use a different xml writer 

The very rudimentary xml writer as shown below may be used as starting point

class KDomElement {
public:
  KDomElement(const QString &name = QString()) : m_tag(name) {}

  void setAttribute(const QString &name, const QString &value)
  {
    m_attributes.append(QString("%1=\"%2\"").arg(name, value));
  }
  // add more methods

  void appendChild(KDomElement &element)
  {
    m_childs.append(element);
  }

  QString toString() const
  {
    if (m_childs.size() > 0) {
      QString s = !m_tag.isEmpty() ? QString("<%1 %2>\n").arg(m_tag, m_attributes.join(" ")) : "";
      foreach(const KDomElement &child, m_childs) {
        s += child.toString();
      }
      s += !m_tag.isEmpty() ? QString("</%1>\n").arg(m_tag) : "";
      return s;
    } else
      return !m_tag.isEmpty() ? QString("<%1 %2 />\n").arg(m_tag, m_attributes.join(" ")) : "";
  }

protected:
  QString m_tag;
  QStringList m_attributes;
  QList<KDomElement> m_childs;
};

class KDomDocument : public KDomElement {
public:
  KDomDocument(const QString &name=QString())
    : KDomElement(name)
  {
  }

  KDomElement createElement(const QString &name)
  {
    return KDomElement(name);
  }
};
Comment 13 Robert Hairgrove 2020-08-11 14:44:45 UTC
I think the problem is that attributes of XML elements are not guaranteed to be in any specific order by the XML standard. QDomDocument (used by Umbrello) seems to put the attributes in random order any time it loads a file or saves it to a string. The ordering of the elements themselves is stable, IIRC -- just not the attributes.

An external processing step, such as XSLT suggested by Ralf Habacker, seems to be the way to go.
Comment 14 Oliver Kellogg 2020-11-02 06:37:13 UTC
QXmlStreamWriter supports preservation of attribute order,
https://doc.qt.io/qt-5/qxmlstreamwriter.html
Comment 15 Ralf Habacker 2020-11-02 07:37:27 UTC
(In reply to Oliver Kellogg from comment #14)
> QXmlStreamWriter supports preservation of attribute order,
> https://doc.qt.io/qt-5/qxmlstreamwriter.html

Wouldn't that require to rewrite the xml-writing completely, because the api doesn't match?
Comment 16 Oliver Kellogg 2020-11-03 07:30:17 UTC
(In reply to Ralf Habacker from comment #15)
> (In reply to Oliver Kellogg from comment #14)
> > QXmlStreamWriter supports preservation of attribute order,
> > https://doc.qt.io/qt-5/qxmlstreamwriter.html
> 
> Wouldn't that require to rewrite the xml-writing completely, because the api
> doesn't match?

No problem.
The writeNamespace call in UMLDoc::saveToXMI took a bit of fiddling but otherwise it looks to be straight forward.
Comment 17 Oliver Kellogg 2020-11-05 04:55:38 UTC
Git commit bc83b26458e15d36620f4b93023925f76f19aa84 by Oliver Kellogg.
Committed on 05/11/2020 at 04:53.
Pushed by okellogg into branch 'master'.

umbrello/umldoc.cpp
- In function saveDocument, on saving as uncompressed XMI close tmpfile
  after calling saveToXMI1.
  Reason: On changing the saveToXMI1 implementation to QXmlStreamWriter
  the file saved is empty if we leave out the close().

M  +1    -0    umbrello/umldoc.cpp

https://invent.kde.org/sdk/umbrello/commit/bc83b26458e15d36620f4b93023925f76f19aa84
Comment 18 Ralf Habacker 2020-11-05 08:07:37 UTC
(In reply to Oliver Kellogg from comment #16)
> No problem.
> The writeNamespace call in UMLDoc::saveToXMI took a bit of fiddling but
> otherwise it looks to be straight forward.

If I open a present xmi file with that change applied and save it again - will that change the attribute order ? 

If so, can it be brought in line with the current implementation to avoid unnecessary changes to the files ?
Comment 19 Oliver Kellogg 2020-11-05 20:28:30 UTC
(In reply to Ralf Habacker from comment #18)
> If I open a present xmi file with that change applied and save it again -
> will that change the attribute order ? 

What do you mean by "that change" ?
I have only just begun doing the conversion and have not committed anything yet.

> If so, can it be brought in line with the current implementation to avoid
> unnecessary changes to the files ?

What do you mean by "the files"?
XMI files or Umbrello C++ implementation files?

If you mean XMI files:
The order in which attributes will appear will be the order in which they are written in the source code.

If you mean Umbrello C++ implementation files:
The conversion will affect approx. 190 header (.h) and implementation (.cpp) files.
Comment 20 Oliver Kellogg 2020-11-08 22:09:40 UTC
Git commit 776c2eaa09b7fff83f901165d62c53f5d28711ab by Oliver Kellogg.
Committed on 08/11/2020 at 22:58.
Pushed by okellogg into branch 'work/363582-stable-xmi'.

- Arguments of functions saveToXMI1 and save1 are changed from
    QDomDocument& doc, QDomElement& elem
  to
    QXmlStreamWriter& writer
- Basic load/save are working but more testing is needed.
  In particular, drag, cut/copy/paste, and undo/redo need testing.
- Unit tests are adapted and are passed.

https://invent.kde.org/sdk/umbrello/commit/776c2eaa09b7fff83f901165d62c53f5d28711ab
Comment 21 Oliver Kellogg 2020-11-13 20:57:33 UTC
From my point of view, with commit
https://invent.kde.org/sdk/umbrello/-/commit/74abf217331b4ce7b745f5ec0ba3453f7809ffc7
the work/363582-stable-xmi branch is approaching usability.
I appreciate your comments.
Comment 22 Ralf Habacker 2020-11-16 08:02:12 UTC
(In reply to Oliver Kellogg from comment #21)
> From my point of view, with commit
> https://invent.kde.org/sdk/umbrello/-/commit/
> 74abf217331b4ce7b745f5ec0ba3453f7809ffc7
> the work/363582-stable-xmi branch is approaching usability.
> I appreciate your comments.

I will take a look this week.
Comment 23 Ralf Habacker 2020-11-18 19:55:40 UTC
(In reply to Ralf Habacker from comment #22)
> I will take a look this week.

Please open a merge request from your work branch with the prefix "WIP:" before the title to indicate a "work in progress" branch. 

This merge request gives us a better opportunity to discuss this than here in the bug tracker. Opening an mr with one line 

BUG:xxx

in the text will create a link to this ticket.
Comment 24 Bug Janitor Service 2020-11-18 22:00:36 UTC
A possibly relevant merge request was started @ https://invent.kde.org/sdk/umbrello/-/merge_requests/17
Comment 25 Oliver Kellogg 2020-12-05 00:10:28 UTC
Git commit cbb0c90c5938f650cb91c4be709165378733e6ce by Oliver Kellogg.
Committed on 09/11/2020 at 22:37.
Pushed by okellogg into branch 'master'.

umbrello/version.h
- Increase XMI_FILE_VERSION to "1.6.20" due to reordering of XML
  attributes.

M  +1    -1    umbrello/version.h

https://invent.kde.org/sdk/umbrello/commit/cbb0c90c5938f650cb91c4be709165378733e6ce
Comment 26 Oliver Kellogg 2020-12-05 00:10:30 UTC
Git commit 3d17c9692c7466fd7e0d3bc6d4aac2a888d9f685 by Oliver Kellogg.
Committed on 22/11/2020 at 15:33.
Pushed by okellogg into branch 'master'.

https://invent.kde.org/sdk/umbrello/-/merge_requests/17#note_140469
On saving <UML:Operation> avoid empty <UML:BehavioralFeature.parameter/>

umbrello/uml1model/operation.cpp
- In function saveToXMI1, before calling writer.writeStartElement for
  "UML:BehavioralFeature.parameter", if m_pSecondary is null and m_List
  is empty then write </UML:Operation> closing element and return.

M  +4    -0    umbrello/uml1model/operation.cpp

https://invent.kde.org/sdk/umbrello/commit/3d17c9692c7466fd7e0d3bc6d4aac2a888d9f685
Comment 27 Oliver Kellogg 2020-12-05 00:10:37 UTC
Git commit 776c2eaa09b7fff83f901165d62c53f5d28711ab by Oliver Kellogg.
Committed on 08/11/2020 at 21:58.
Pushed by okellogg into branch 'master'.

Create branch work/363582-stable-xmi from master @ df0d454

- Arguments of functions saveToXMI1 and save1 are changed from
    QDomDocument& doc, QDomElement& elem
  to
    QXmlStreamWriter& writer
- Basic load/save are working but more testing is needed.
  In particular, drag, cut/copy/paste, and undo/redo need testing.
- Unit tests are adapted and are passed.

M  +55   -48   umbrello/clipboard/umldragdata.cpp
M  +16   -6    umbrello/cmds/cmdremovediagram.cpp
M  +28   -6    umbrello/cmds/widget/cmdcreatewidget.cpp
M  +49   -8    umbrello/cmds/widget/cmdremovewidget.cpp
M  +11   -10   umbrello/codegenerators/classifiercodedocument.cpp
M  +2    -2    umbrello/codegenerators/classifiercodedocument.h
M  +9    -8    umbrello/codegenerators/codeaccessormethod.cpp
M  +3    -2    umbrello/codegenerators/codeaccessormethod.h
M  +7    -7    umbrello/codegenerators/codeblock.cpp
M  +2    -2    umbrello/codegenerators/codeblock.h
M  +12   -9    umbrello/codegenerators/codeblockwithcomments.cpp
M  +2    -2    umbrello/codegenerators/codeblockwithcomments.h
M  +13   -12   umbrello/codegenerators/codeclassfield.cpp
M  +2    -2    umbrello/codegenerators/codeclassfield.h
M  +9    -7    umbrello/codegenerators/codeclassfielddeclarationblock.cpp
M  +2    -2    umbrello/codegenerators/codeclassfielddeclarationblock.h
M  +4    -4    umbrello/codegenerators/codecomment.cpp
M  +1    -1    umbrello/codegenerators/codecomment.h
M  +15   -14   umbrello/codegenerators/codedocument.cpp
M  +3    -2    umbrello/codegenerators/codedocument.h
M  +10   -9    umbrello/codegenerators/codegenerator.cpp
M  +2    -1    umbrello/codegenerators/codegenerator.h
M  +7    -4    umbrello/codegenerators/codegenobjectwithtextblocks.cpp
M  +2    -1    umbrello/codegenerators/codegenobjectwithtextblocks.h
M  +7    -5    umbrello/codegenerators/codemethodblock.cpp
M  +2    -1    umbrello/codegenerators/codemethodblock.h
M  +9    -6    umbrello/codegenerators/codeoperation.cpp
M  +2    -2    umbrello/codegenerators/codeoperation.h
M  +11   -8    umbrello/codegenerators/codeparameter.cpp
M  +2    -1    umbrello/codegenerators/codeparameter.h
M  +4    -4    umbrello/codegenerators/cpp/cppcodecomment.cpp
M  +1    -1    umbrello/codegenerators/cpp/cppcodecomment.h
M  +4    -4    umbrello/codegenerators/cpp/cppcodedocumentation.cpp
M  +1    -1    umbrello/codegenerators/cpp/cppcodedocumentation.h
M  +6    -6    umbrello/codegenerators/cpp/cppcodegenerator.cpp
M  +1    -1    umbrello/codegenerators/cpp/cppcodegenerator.h
M  +4    -4    umbrello/codegenerators/cpp/cppheaderclassdeclarationblock.cpp
M  +1    -1    umbrello/codegenerators/cpp/cppheaderclassdeclarationblock.h
M  +4    -4    umbrello/codegenerators/cpp/cppheadercodedocument.cpp
M  +1    -1    umbrello/codegenerators/cpp/cppheadercodedocument.h
M  +4    -4    umbrello/codegenerators/d/dclassdeclarationblock.cpp
M  +1    -1    umbrello/codegenerators/d/dclassdeclarationblock.h
M  +5    -2    umbrello/codegenerators/d/dcodeaccessormethod.cpp
M  +1    -1    umbrello/codegenerators/d/dcodeaccessormethod.h
M  +4    -4    umbrello/codegenerators/d/dcodecomment.cpp
M  +1    -1    umbrello/codegenerators/d/dcodecomment.h
M  +4    -4    umbrello/codegenerators/d/dcodedocumentation.cpp
M  +1    -1    umbrello/codegenerators/d/dcodedocumentation.h
M  +12   -9    umbrello/codegenerators/hierarchicalcodeblock.cpp
M  +4    -2    umbrello/codegenerators/hierarchicalcodeblock.h
M  +7    -6    umbrello/codegenerators/java/javaantcodedocument.cpp
M  +3    -2    umbrello/codegenerators/java/javaantcodedocument.h
M  +4    -4    umbrello/codegenerators/java/javaclassdeclarationblock.cpp
M  +1    -1    umbrello/codegenerators/java/javaclassdeclarationblock.h
M  +5    -2    umbrello/codegenerators/java/javacodeaccessormethod.cpp
M  +1    -1    umbrello/codegenerators/java/javacodeaccessormethod.h
M  +4    -4    umbrello/codegenerators/java/javacodedocumentation.cpp
M  +1    -1    umbrello/codegenerators/java/javacodedocumentation.h
M  +7    -4    umbrello/codegenerators/ownedcodeblock.cpp
M  +2    -1    umbrello/codegenerators/ownedcodeblock.h
M  +5    -5    umbrello/codegenerators/ownedhierarchicalcodeblock.cpp
M  +2    -2    umbrello/codegenerators/ownedhierarchicalcodeblock.h
M  +4    -4    umbrello/codegenerators/ruby/rubyclassdeclarationblock.cpp
M  +1    -1    umbrello/codegenerators/ruby/rubyclassdeclarationblock.h
M  +3    -2    umbrello/codegenerators/ruby/rubycodeaccessormethod.cpp
M  +1    -1    umbrello/codegenerators/ruby/rubycodeaccessormethod.h
M  +4    -4    umbrello/codegenerators/ruby/rubycodedocumentation.cpp
M  +1    -1    umbrello/codegenerators/ruby/rubycodedocumentation.h
M  +6    -8    umbrello/codegenerators/textblock.cpp
M  +4    -2    umbrello/codegenerators/textblock.h
M  +10   -7    umbrello/codegenerators/xml/xmlelementcodeblock.cpp
M  +2    -2    umbrello/codegenerators/xml/xmlelementcodeblock.h
M  +33   -33   umbrello/optionstate.cpp
M  +7    -6    umbrello/optionstate.h
M  +3    -3    umbrello/uml1model/actor.cpp
M  +1    -1    umbrello/uml1model/actor.h
M  +4    -4    umbrello/uml1model/artifact.cpp
M  +1    -1    umbrello/uml1model/artifact.h
M  +28   -28   umbrello/uml1model/association.cpp
M  +2    -1    umbrello/uml1model/association.h
M  +5    -5    umbrello/uml1model/attribute.cpp
M  +1    -1    umbrello/uml1model/attribute.h
M  +4    -4    umbrello/uml1model/category.cpp
M  +1    -1    umbrello/uml1model/category.h
M  +4    -5    umbrello/uml1model/checkconstraint.cpp
M  +1    -1    umbrello/uml1model/checkconstraint.h
M  +19   -23   umbrello/uml1model/classifier.cpp
M  +1    -1    umbrello/uml1model/classifier.h
M  +7    -7    umbrello/uml1model/component.cpp
M  +1    -1    umbrello/uml1model/component.h
M  +6    -7    umbrello/uml1model/datatype.cpp
M  +1    -1    umbrello/uml1model/datatype.h
M  +8    -7    umbrello/uml1model/entity.cpp
M  +1    -1    umbrello/uml1model/entity.h
M  +11   -11   umbrello/uml1model/entityattribute.cpp
M  +1    -1    umbrello/uml1model/entityattribute.h
M  +6    -6    umbrello/uml1model/enum.cpp
M  +1    -1    umbrello/uml1model/enum.h
M  +4    -4    umbrello/uml1model/enumliteral.cpp
M  +1    -1    umbrello/uml1model/enumliteral.h
M  +47   -49   umbrello/uml1model/folder.cpp
M  +3    -3    umbrello/uml1model/folder.h
M  +10   -10   umbrello/uml1model/foreignkeyconstraint.cpp
M  +1    -1    umbrello/uml1model/foreignkeyconstraint.h
M  +5    -5    umbrello/uml1model/instance.cpp
M  +1    -1    umbrello/uml1model/instance.h
M  +7    -7    umbrello/uml1model/instanceattribute.cpp
M  +1    -1    umbrello/uml1model/instanceattribute.h
M  +3    -3    umbrello/uml1model/node.cpp
M  +1    -1    umbrello/uml1model/node.h
M  +22   -24   umbrello/uml1model/operation.cpp
M  +1    -1    umbrello/uml1model/operation.h
M  +7    -7    umbrello/uml1model/package.cpp
M  +1    -1    umbrello/uml1model/package.h
M  +3    -3    umbrello/uml1model/port.cpp
M  +1    -1    umbrello/uml1model/port.h
M  +3    -3    umbrello/uml1model/stereotype.cpp
M  +1    -1    umbrello/uml1model/stereotype.h
M  +4    -4    umbrello/uml1model/template.cpp
M  +1    -1    umbrello/uml1model/template.h
M  +20   -21   umbrello/uml1model/umlobject.cpp
M  +5    -4    umbrello/uml1model/umlobject.h
M  +17   -17   umbrello/uml1model/umlrole.cpp
M  +1    -1    umbrello/uml1model/umlrole.h
M  +6    -6    umbrello/uml1model/uniqueconstraint.cpp
M  +1    -1    umbrello/uml1model/uniqueconstraint.h
M  +3    -3    umbrello/uml1model/usecase.cpp
M  +1    -1    umbrello/uml1model/usecase.h
M  +55   -91   umbrello/umldoc.cpp
M  +5    -4    umbrello/umllistview.cpp
M  +2    -1    umbrello/umllistview.h
M  +14   -15   umbrello/umllistviewitem.cpp
M  +2    -1    umbrello/umllistviewitem.h
M  +29   -28   umbrello/umlscene.cpp
M  +2    -1    umbrello/umlscene.h
M  +10   -9    umbrello/umlwidgets/activitywidget.cpp
M  +1    -1    umbrello/umlwidgets/activitywidget.h
M  +7    -4    umbrello/umlwidgets/actorwidget.cpp
M  +1    -1    umbrello/umlwidgets/actorwidget.h
M  +7    -4    umbrello/umlwidgets/artifactwidget.cpp
M  +1    -1    umbrello/umlwidgets/artifactwidget.h
M  +17   -16   umbrello/umlwidgets/associationline.cpp
M  +2    -1    umbrello/umlwidgets/associationline.h
M  +23   -22   umbrello/umlwidgets/associationwidget.cpp
M  +1    -1    umbrello/umlwidgets/associationwidget.h
M  +8    -6    umbrello/umlwidgets/associationwidgetrole.cpp
M  +2    -1    umbrello/umlwidgets/associationwidgetrole.h
M  +5    -4    umbrello/umlwidgets/boxwidget.cpp
M  +1    -1    umbrello/umlwidgets/boxwidget.h
M  +5    -4    umbrello/umlwidgets/categorywidget.cpp
M  +1    -1    umbrello/umlwidgets/categorywidget.h
M  +24   -21   umbrello/umlwidgets/classifierwidget.cpp
M  +1    -1    umbrello/umlwidgets/classifierwidget.h
M  +9    -8    umbrello/umlwidgets/combinedfragmentwidget.cpp
M  +1    -1    umbrello/umlwidgets/combinedfragmentwidget.h
M  +7    -4    umbrello/umlwidgets/componentwidget.cpp
M  +1    -1    umbrello/umlwidgets/componentwidget.h
M  +5    -4    umbrello/umlwidgets/datatypewidget.cpp
M  +1    -1    umbrello/umlwidgets/datatypewidget.h
M  +5    -4    umbrello/umlwidgets/diagramproxywidget.cpp
M  +2    -1    umbrello/umlwidgets/diagramproxywidget.h
M  +8    -5    umbrello/umlwidgets/entitywidget.cpp
M  +1    -1    umbrello/umlwidgets/entitywidget.h
M  +8    -5    umbrello/umlwidgets/enumwidget.cpp
M  +1    -1    umbrello/umlwidgets/enumwidget.h
M  +8    -7    umbrello/umlwidgets/floatingdashlinewidget.cpp
M  +1    -1    umbrello/umlwidgets/floatingdashlinewidget.h
M  +9    -8    umbrello/umlwidgets/floatingtextwidget.cpp
M  +1    -1    umbrello/umlwidgets/floatingtextwidget.h
M  +6    -5    umbrello/umlwidgets/forkjoinwidget.cpp
M  +1    -1    umbrello/umlwidgets/forkjoinwidget.h
M  +5    -4    umbrello/umlwidgets/linkwidget.cpp
M  +2    -1    umbrello/umlwidgets/linkwidget.h
M  +15   -14   umbrello/umlwidgets/messagewidget.cpp
M  +1    -1    umbrello/umlwidgets/messagewidget.h
M  +5    -4    umbrello/umlwidgets/nodewidget.cpp
M  +1    -1    umbrello/umlwidgets/nodewidget.h
M  +8    -7    umbrello/umlwidgets/notewidget.cpp
M  +1    -1    umbrello/umlwidgets/notewidget.h
M  +11   -10   umbrello/umlwidgets/objectnodewidget.cpp
M  +1    -1    umbrello/umlwidgets/objectnodewidget.h
M  +12   -11   umbrello/umlwidgets/objectwidget.cpp
M  +1    -1    umbrello/umlwidgets/objectwidget.h
M  +5    -4    umbrello/umlwidgets/packagewidget.cpp
M  +1    -1    umbrello/umlwidgets/packagewidget.h
M  +9    -7    umbrello/umlwidgets/pinportbase.cpp
M  +1    -1    umbrello/umlwidgets/pinportbase.h
M  +8    -7    umbrello/umlwidgets/preconditionwidget.cpp
M  +1    -1    umbrello/umlwidgets/preconditionwidget.h
M  +11   -8    umbrello/umlwidgets/regionwidget.cpp
M  +1    -1    umbrello/umlwidgets/regionwidget.h
M  +10   -9    umbrello/umlwidgets/signalwidget.cpp
M  +1    -1    umbrello/umlwidgets/signalwidget.h
M  +16   -15   umbrello/umlwidgets/statewidget.cpp
M  +1    -1    umbrello/umlwidgets/statewidget.h
M  +11   -10   umbrello/umlwidgets/umlwidget.cpp
M  +1    -1    umbrello/umlwidgets/umlwidget.h
M  +7    -4    umbrello/umlwidgets/usecasewidget.cpp
M  +1    -1    umbrello/umlwidgets/usecasewidget.h
M  +37   -37   umbrello/umlwidgets/widget_utils.cpp
M  +4    -4    umbrello/umlwidgets/widget_utils.h
M  +18   -20   umbrello/umlwidgets/widgetbase.cpp
M  +2    -1    umbrello/umlwidgets/widgetbase.h
M  +4    -2    unittests/testassociation.cpp
M  +35   -24   unittests/testbase.h
M  +2    -2    unittests/testclassifier.cpp
M  +13   -2    unittests/testoptionstate.cpp
M  +2    -2    unittests/testpackage.cpp
M  +4    -2    unittests/testpreconditionwidget.cpp
M  +18   -2    unittests/testumlobject.cpp
M  +1    -1    unittests/testumlobject.h

https://invent.kde.org/sdk/umbrello/commit/776c2eaa09b7fff83f901165d62c53f5d28711ab
Comment 28 Oliver Kellogg 2020-12-05 00:10:38 UTC
Git commit 74abf217331b4ce7b745f5ec0ba3453f7809ffc7 by Oliver Kellogg.
Committed on 13/11/2020 at 20:48.
Pushed by okellogg into branch 'master'.

Followup to commit 776c2ea : Various fixes for writing of XMI

umbrello/umldoc.cpp
- In function saveToXMI1 reenable call to UMLListView::saveToXMI1 and
  CodeGenerator::saveToXMI1.

umbrello/uml1model/classifier.cpp
- In function saveToXMI1, avoid writing the <UML:Classifier.feature>
  element if both attList and opList are empty.

umbrello/umlwidgets/associationwidgetrole.{h,cpp}
- At function saveToXMI1 remove argument 'suffix'.

umbrello/umlwidgets/associationwidgetrole.cpp
- In function saveToXMI1 remove writing of attributes index[ab] and
  totalcount[ab].
  Writing of attributes shall not be mixed with writing the subelements
  multiplicityWidget/roleWidget/changeabilityWidget because
  attributes may not follow subelements (in particular, attributes of
  role B may not follow subelements of role A).

umbrello/umlwidgets/associationwidget.cpp
- In function saveToXMI1:
  - Postpone saving of m_nameWidget and m_associationLine until after
    all attributes have been written.
    Reason: Subelements may not precede attributes.
  - Save attributes of m_role[A] and m_role[B].  Reason: Their saving
    has been removed from AssociationWidgetRole::saveToXMI1.

M  +13   -11   umbrello/uml1model/classifier.cpp
M  +2    -2    umbrello/umldoc.cpp
M  +21   -8    umbrello/umlwidgets/associationwidget.cpp
M  +4    -4    umbrello/umlwidgets/associationwidgetrole.cpp
M  +1    -1    umbrello/umlwidgets/associationwidgetrole.h

https://invent.kde.org/sdk/umbrello/commit/74abf217331b4ce7b745f5ec0ba3453f7809ffc7
Comment 29 Oliver Kellogg 2020-12-05 00:10:46 UTC
Git commit b1a4f029a9f55a79d2b6ae1e3569cde493a8392e by Oliver Kellogg.
Committed on 13/11/2020 at 23:07.
Pushed by okellogg into branch 'master'.

umbrello/umlwidgets/regionwidget.cpp
- In function saveToXMI1 fix error on migrating from QDomDocument
  to QXmlStreamWriter.

umbrello/umlwidgets/umlwidget.cpp
- In function saveToXMI1 fix misleading comment about the placement
  of call from child classes.

M  +1    -1    umbrello/umlwidgets/regionwidget.cpp
M  +2    -1    umbrello/umlwidgets/umlwidget.cpp

https://invent.kde.org/sdk/umbrello/commit/b1a4f029a9f55a79d2b6ae1e3569cde493a8392e
Comment 30 Oliver Kellogg 2020-12-06 18:14:07 UTC
Git commit b0f4278b08330f8fe5729de1a516a8c3d470e1aa by Oliver Kellogg.
Committed on 06/12/2020 at 18:10.
Pushed by okellogg into branch 'master'.

umbrello/version.h
- Increase XMI_FILE_VERSION to 1.7.0 to reflect major change in XMI
  attribute order.

M  +1    -1    umbrello/version.h

https://invent.kde.org/sdk/umbrello/commit/b0f4278b08330f8fe5729de1a516a8c3d470e1aa
Comment 31 Oliver Kellogg 2020-12-10 06:51:32 UTC
Created attachment 133962 [details]
canonicalize_umbrello_xmi_attributes.pl

This shellscript takes an Umbrello XMI file created with exporterVersion
before 1.7 as input, reorders its XML attributes to conform to the order of
exporterVersion 1.7, and writes the converted XMI to stdout.
It is intended to simplify comparing older XMI files with the new format.
Comment 32 Oliver Kellogg 2021-01-02 10:43:39 UTC
Created attachment 134460 [details]
canonicalize_umbrello_xmi_attributes.pl

Version 2021-01-02 of canonicalize_umbrello_xmi_attributes.pl adds mapping of the
outermost <UML:Model> and of <XMI>, <XMI.metamodel>, <docsettings>, <listitem>.
Comment 33 Ralf Habacker 2021-03-09 07:36:14 UTC
Git commit 250c7e83df33cd6d9eedcd6981a1cb22db37ee48 by Ralf Habacker.
Committed on 09/03/2021 at 07:35.
Pushed by habacker into branch 'release/20.12'.

A much smarter approach to provide stable xml output for Qt5

Imported from https://stackoverflow.com/questions/27378143/qt-5-produce-random-attribute-order-in-xml/43524969#43524969
and adjusted to be used by umbrello.

M  +72   -0    umbrello/umldoc.cpp

https://invent.kde.org/sdk/umbrello/commit/250c7e83df33cd6d9eedcd6981a1cb22db37ee48