Commit 3409db0b authored by Ralf Habacker's avatar Ralf Habacker
Browse files

Fix 'Font sizing is wrong when sharing diagrams'.

For any new file the current screen resolution is written into the xmi
file. If a file contains resolution the file coordinates are recalculated
into current screen resolution on load and recalculated to file resolution
on save.

Files without coordinates resolution are not recalculated on load or save,
because it is currently not known how to estimate the resolution the file
is created with. Adjusting those files requires currently adding the
"resolution" attribute to the <diagrams> tag manually.

To solve that issue an option would be to add a user request to get the
correct resolution or to print out a user warning on the status line after
loading and to add an option to be able to change the resolution in
document settings or if possible to estimate it from any diagram
coordinates.

BUG:90103


FIXED-IN:2.20.80 (KDE Applications 16.11.80)

Signed-off-by: Ralf Habacker's avatarRalf Habacker <ralf.habacker@freenet.de>
parent d4f45447
......@@ -246,6 +246,7 @@ endmacro(add_unstable_feature)
add_unstable_feature(WIDGET_SHOW_DOC) # show documentation in classes ticket xxx
add_unstable_feature(NEW_CODE_GENERATORS) # new c++ code generator
add_unstable_feature(UML_OBJECTS_WINDOW) # objects dock window
add_unstable_feature(XMIRESOLUTION) # see https://bugs.kde.org/show_bug.cgi?id=90103
if(LIBXSLT_FOUND AND LIBXML2_FOUND)
add_subdirectory(umbrello)
......
<!--
========= umbrello specific =========
XMI_FILE_VERSION 1.6.3
XMI_FILE_VERSION 1.6.11
=====================================
-->
<!ENTITY % ids
......@@ -15,6 +15,7 @@
<!ELEMENT diagrams ANY >
<!ATTLIST diagrams
resolution CDATA #IMPLIED
>
<!ELEMENT diagram ANY >
<!ATTLIST diagram
......
......@@ -3279,7 +3279,7 @@
<UML:Class visibility="public" isSpecification="false" namespace="Logical View" isAbstract="false" isLeaf="false" isRoot="false" xmi.id="zKeUCT61MFDV" name="client"/>
</UML:Namespace.ownedElement>
<XMI.extension xmi.extender="umbrello">
<diagrams>
<diagrams resolution="88">
<diagram showopsig="1" linecolor="#ff0000" snapx="25" showattribassocs="1" snapy="25" linewidth="0" showattsig="1" textcolor="#000000" isopen="1" showpackage="1" showpubliconly="0" showstereotype="1" name="class diagram" font="Noto Sans,9,-1,0,50,0,0,0,0,0" canvasheight="1724" canvaswidth="2995.23" localid="-1" snapcsgrid="0" showgrid="0" showops="0" griddotcolor="#d3d3d3" backgroundcolor="#ffffff" usefillcolor="0" fillcolor="#ffffc0" zoom="94" xmi.id="TGcjrcWrBVaN" documentation="" showscope="1" snapgrid="0" showatts="1" type="1">
<widgets>
<classwidget linecolor="#ff0000" usesdiagramfillcolor="0" linewidth="0" showoperations="0" textcolor="#000000" usesdiagramusefillcolor="0" showpubliconly="0" showpackage="1" x="73" showattsigs="601" showstereotype="1" y="1107" showattributes="1" font="Noto Sans,9,-1,0,50,0,0,0,0,0" localid="SGEsI1ooVpGH" width="83" isinstance="0" usefillcolor="0" fillcolor="#ffffc0" xmi.id="LlxwhUsIdhSb" showscope="1" height="19" showopsigs="601"/>
......
......@@ -73,6 +73,7 @@
#include <QApplication>
#include <QBuffer>
#include <QDateTime>
#include <QDesktopWidget>
#include <QDir>
#include <QDomDocument>
#include <QDomElement>
......@@ -120,7 +121,8 @@ UMLDoc::UMLDoc()
m_bClosing(false),
m_diagramsModel(new DiagramsModel),
m_objectsModel(new ObjectsModel),
m_stereotypesModel(new StereotypesModel(&m_stereoList))
m_stereotypesModel(new StereotypesModel(&m_stereoList)),
m_resolution(0.0)
{
for (int i = 0; i < Uml::ModelType::N_MODELTYPES; ++i)
m_root[i] = 0;
......@@ -443,7 +445,7 @@ bool UMLDoc::newDocument()
closeDocument();
UMLApp::app()->setCurrentView(0);
setUrlUntitled();
setResolution(qApp->desktop()->logicalDpiX());
//see if we need to start with a new diagram
Settings::OptionState optionState = Settings::optionState();
Uml::DiagramType::Enum dt = optionState.generalState.diagram;
......@@ -488,6 +490,7 @@ bool UMLDoc::openDocument(const KUrl& url, const char* format /* =0 */)
m_doc_url = url;
closeDocument();
setResolution(0.0);
// IMPORTANT: set m_bLoading to true
// _AFTER_ the call of UMLDoc::closeDocument()
// as it sets m_bLoading to false after it was temporarily
......@@ -1966,6 +1969,41 @@ QString UMLDoc::name() const
return m_Name;
}
/**
* Set coordinates resolution for current document.
* @param document resolution in DPI
*/
void UMLDoc::setResolution(qreal resolution)
{
m_resolution = resolution;
}
/**
* Returns coordinates resolution for current document.
* @return document resolution in DPI
*/
qreal UMLDoc::resolution() const
{
return m_resolution;
}
/**
* Returns scale factor for recalculation of document coordinates.
* @return scale factor
*/
qreal UMLDoc::dpiScale() const
{
#ifdef ENABLE_XMIRESOLUTION
if (resolution() != 0.0)
return (qreal)qApp->desktop()->logicalDpiX() / resolution();
else
#endif
return 1.0;
}
/**
* Return the m_modelID (currently this a fixed value:
* Umbrello supports only a single document.)
......@@ -2701,6 +2739,18 @@ void UMLDoc::loadExtensionsFromXMI(QDomNode& node)
return;
}
diagramNode = diagramNode.firstChild();
} else {
qreal resolution = 0.0;
QString res = node.toElement().attribute(QLatin1String("resolution"), QLatin1String(""));
if (!res.isEmpty()) {
resolution = res.toDouble();
}
if (resolution != 0.0) {
UMLApp::app()->document()->setResolution(resolution);
} else {
// see UMLFolder::loadDiagramsFromXMI()
UMLApp::app()->document()->setResolution(0.0);
}
}
if (!loadDiagramsFromXMI(diagramNode)) {
uWarning() << "failed load on diagrams";
......
......@@ -159,6 +159,10 @@ public:
void setName(const QString& name);
QString name() const;
void setResolution(qreal resolution);
qreal resolution() const;
qreal dpiScale() const;
Uml::ID::Type modelID() const;
static bool tagEq (const QString& tag, const QString& pattern);
......@@ -319,6 +323,12 @@ private:
ObjectsModel *m_objectsModel;
StereotypesModel *m_stereotypesModel;
/**
* Holds widgets coordinates resolution.
* Unit is dpi.
*/
qreal m_resolution;
public slots:
void slotRemoveUMLObject(UMLObject*o);
void slotAutoSave();
......
......@@ -290,6 +290,8 @@ void UMLFolder::saveContents(QDomDocument& qDoc, QDomElement& qElement)
// Save diagrams to `extension'.
if (m_diagrams.count()) {
QDomElement diagramsElement = qDoc.createElement(QLatin1String("diagrams"));
if (UMLApp::app()->document()->resolution() != 0.0)
diagramsElement.setAttribute(QLatin1String("resolution"), UMLApp::app()->document()->resolution());
foreach (UMLView* pView, m_diagrams) {
pView->umlScene()->saveToXMI(qDoc, diagramsElement);
......@@ -382,8 +384,25 @@ void UMLFolder::saveToXMI(QDomDocument& qDoc, QDomElement& qElement)
* Auxiliary to load():
* Load the diagrams from the "diagrams" in the <XMI.extension>
*/
bool UMLFolder::loadDiagramsFromXMI(QDomNode& diagrams)
bool UMLFolder::loadDiagramsFromXMI(QDomNode& node)
{
qreal resolution = 0.0;
QString res = node.toElement().attribute(QLatin1String("resolution"), QLatin1String(""));
if (!res.isEmpty()) {
resolution = res.toDouble();
}
if (resolution != 0.0) {
UMLApp::app()->document()->setResolution(resolution);
} else {
/* FIXME how to get dpi ?
* 1. from user -> will open a dialog box for any old file
* 2. after loading from user changeable document settings
* 3. estimated from contained widgets
*/
UMLApp::app()->document()->setResolution(0.0);
}
QDomNode diagrams = node.firstChild();
const Settings::OptionState optionState = Settings::optionState();
UMLDoc *umldoc = UMLApp::app()->document();
bool totalSuccess = true;
......@@ -490,8 +509,7 @@ bool UMLFolder::load(QDomElement& element)
QDomElement el = xtnode.toElement();
const QString xtag = el.tagName();
if (xtag == QLatin1String("diagrams")) {
QDomNode diagramNode = xtnode.firstChild();
if (!loadDiagramsFromXMI(diagramNode))
if (!loadDiagramsFromXMI(xtnode))
totalSuccess = false;
} else if (xtag == QLatin1String("external_file")) {
#if QT_VERSION >= 0x050000
......
......@@ -72,7 +72,7 @@ protected:
void save(QDomDocument& qDoc, QDomElement& qElement);
bool loadDiagramsFromXMI(QDomNode& diagrams);
bool loadDiagramsFromXMI(QDomNode& node);
bool loadFolderFile(const QString& path);
......
......@@ -14,6 +14,8 @@
// application includes
#include "associationwidget.h"
#include "debug_utils.h"
#include "uml.h"
#include "umldoc.h"
#include "umlwidget.h"
// qt includes
......@@ -309,11 +311,12 @@ bool AssociationLine::loadFromXMI(QDomElement &qElement)
if(startElement.isNull() || startElement.tagName() != QLatin1String("startpoint")) {
return false;
}
qreal dpiScale = UMLApp::app()->document()->dpiScale();
QString x = startElement.attribute(QLatin1String("startx"), QLatin1String("0"));
qreal nX = toDoubleFromAnyLocale(x);
QString y = startElement.attribute(QLatin1String("starty"), QLatin1String("0"));
qreal nY = toDoubleFromAnyLocale(y);
QPointF startPoint(nX, nY);
QPointF startPoint(nX * dpiScale, nY * dpiScale);
node = startElement.nextSibling();
QDomElement endElement = node.toElement();
......@@ -324,8 +327,8 @@ bool AssociationLine::loadFromXMI(QDomElement &qElement)
nX = toDoubleFromAnyLocale(x);
y = endElement.attribute(QLatin1String("endy"), QLatin1String("0"));
nY = toDoubleFromAnyLocale(y);
QPointF endPoint(nX, nY);
setEndPoints(startPoint, endPoint);
QPointF endPoint(nX * dpiScale, nY * dpiScale);
setEndPoints(startPoint * dpiScale, endPoint * dpiScale);
QPointF point;
node = endElement.nextSibling();
QDomElement element = node.toElement();
......@@ -336,7 +339,7 @@ bool AssociationLine::loadFromXMI(QDomElement &qElement)
y = element.attribute(QLatin1String("y"), QLatin1String("0"));
point.setX(toDoubleFromAnyLocale(x));
point.setY(toDoubleFromAnyLocale(y));
insertPoint(i++, point);
insertPoint(i++, point * dpiScale);
}
node = element.nextSibling();
element = node.toElement();
......@@ -351,21 +354,26 @@ bool AssociationLine::loadFromXMI(QDomElement &qElement)
*/
void AssociationLine::saveToXMI(QDomDocument &qDoc, QDomElement &qElement)
{
QPointF point = m_associationWidget->mapToScene(startPoint());
QDomElement lineElement = qDoc.createElement(QLatin1String("linepath"));
lineElement.setAttribute(QLatin1String("layout"), toString(m_layout));
QDomElement startElement = qDoc.createElement(QLatin1String("startpoint"));
qreal dpiScale = UMLApp::app()->document()->dpiScale();
QPointF point = m_associationWidget->mapToScene(startPoint());
point /= dpiScale;
startElement.setAttribute(QLatin1String("startx"), QString::number(point.x()));
startElement.setAttribute(QLatin1String("starty"), QString::number(point.y()));
lineElement.appendChild(startElement);
QDomElement endElement = qDoc.createElement(QLatin1String("endpoint"));
point = m_associationWidget->mapToScene(endPoint());
point /= dpiScale;
endElement.setAttribute(QLatin1String("endx"), QString::number(point.x()));
endElement.setAttribute(QLatin1String("endy"), QString::number(point.y()));
lineElement.appendChild(endElement);
for(int i = 1; i < count()-1; ++i) {
QDomElement pointElement = qDoc.createElement(QLatin1String("point"));
point = m_associationWidget->mapToScene(this->point(i));
point /= dpiScale;
pointElement.setAttribute(QLatin1String("x"), QString::number(point.x()));
pointElement.setAttribute(QLatin1String("y"), QString::number(point.y()));
lineElement.appendChild(pointElement);
......
......@@ -1818,10 +1818,13 @@ void UMLWidget::saveToXMI(QDomDocument & qDoc, QDomElement & qElement)
*/
WidgetBase::saveToXMI(qDoc, qElement);
qElement.setAttribute(QLatin1String("xmi.id"), Uml::ID::toString(id()));
qElement.setAttribute(QLatin1String("x"), QString::number(x()));
qElement.setAttribute(QLatin1String("y"), QString::number(y()));
qElement.setAttribute(QLatin1String("width"), QString::number(width()));
qElement.setAttribute(QLatin1String("height"), QString::number(height()));
qreal dpiScale = UMLApp::app()->document()->dpiScale();
qElement.setAttribute(QLatin1String("x"), QString::number(x() / dpiScale));
qElement.setAttribute(QLatin1String("y"), QString::number(y() / dpiScale));
qElement.setAttribute(QLatin1String("width"), QString::number(width() / dpiScale));
qElement.setAttribute(QLatin1String("height"), QString::number(height() / dpiScale));
qElement.setAttribute(QLatin1String("isinstance"), m_isInstance);
if (!m_instanceName.isEmpty())
qElement.setAttribute(QLatin1String("instancename"), m_instanceName);
......@@ -1843,9 +1846,11 @@ bool UMLWidget::loadFromXMI(QDomElement & qElement)
QString y = qElement.attribute(QLatin1String("y"), QLatin1String("0"));
QString h = qElement.attribute(QLatin1String("height"), QLatin1String("0"));
QString w = qElement.attribute(QLatin1String("width"), QLatin1String("0"));
setSize(toDoubleFromAnyLocale(w), toDoubleFromAnyLocale(h));
setX(toDoubleFromAnyLocale(x));
setY(toDoubleFromAnyLocale(y));
qreal dpiScale = UMLApp::app()->document()->dpiScale();
setSize(toDoubleFromAnyLocale(w) * dpiScale,
toDoubleFromAnyLocale(h) * dpiScale);
setX(toDoubleFromAnyLocale(x) * dpiScale);
setY(toDoubleFromAnyLocale(y) * dpiScale);
QString isinstance = qElement.attribute(QLatin1String("isinstance"), QLatin1String("0"));
m_isInstance = (bool)isinstance.toInt();
......
......@@ -29,7 +29,7 @@ inline QByteArray umbrelloVersion()
}
// Update this version when changing the XMI file format
#ifdef ENABLE_WIDGET_SHOW_DOC
#if defined(ENABLE_WIDGET_SHOW_DOC) || defined(ENABLE_XMIRESOLUTION)
#define XMI_FILE_VERSION "1.6.11"
#else
#define XMI_FILE_VERSION "1.6.10"
......
Supports Markdown
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