Bug 66461

Summary: Widgets (classes, enum...) are not wide enough
Product: [Applications] umbrello Reporter: Sebastian Stein <seb.kde>
Component: generalAssignee: Umbrello Development Group <umbrello-devel>
Status: RESOLVED FIXED    
Severity: normal CC: edwin, osirven
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: Compiled Sources   
OS: Linux   
Latest Commit: Version Fixed In:
Attachments: wrong sized class widgets
2 widgets with missing pixels
PATH Fixes to narrow classifier boxes for italics and templates
PATCH fixes all cases of wrong width settings in classifierwidget.cpp

Description Sebastian Stein 2003-10-23 16:29:34 UTC
Version:           1.2-beta (using KDE 3.1.4)
Installed from:    compiled sources
Compiler:          gcc version 3.2.3
OS:          Linux (i686) release 2.4.22

I noticed, that class widgets are not wide enough. Only some pixels are missing. I think this bug must have been introduced in the last weeks.

You can reproduce this problem by creating a class and adding an operation with a operation name not much bigger then the widget box.
Comment 1 Sebastian Stein 2003-10-23 16:30:12 UTC
Created attachment 2860 [details]
wrong sized class widgets
Comment 2 Sebastian Stein 2003-10-28 21:24:53 UTC
this bug should be fixed before KDE 3.2 release

I will try to fix this in the next days.
Comment 3 Sebastian Stein 2003-11-06 12:02:27 UTC
*** Bug has been marked as fixed ***.
Comment 4 Jonathan Riddell 2004-01-04 21:09:45 UTC
Not completely fixed yet.
Comment 5 Jonathan Riddell 2004-01-04 21:10:32 UTC
*** Bug 71174 has been marked as a duplicate of this bug. ***
Comment 6 Jonathan Riddell 2004-01-04 21:13:02 UTC
Fixed now, calculated size was done with a different fontMatrix than drawn font size.

Still some tidying up to do here, UMLWidget::getFontMatrix() seems a peculiar method which probably should be done away with.
Comment 7 Sebastian Stein 2004-01-04 22:18:28 UTC
It isn't fixed yet. I have some ways to reproduce the bug:

1. Create a class named new_class_1 -> the first n won't be complete ; This only happens if there is a char 1 in at the end
2. Add an abstract static operation new_operation_2 to this class. The void won't be displayed fully
3. create an interface and call it new_interface_1, some pixels are missing

The problem seems to be, that QFontMetrics.boundingRect().width() or QFontMetrics.size().width() return the same value for italic and non-italic fonts. I'm not sure, but I think this is incorrect.
Comment 8 Jonathan Riddell 2004-01-06 23:29:08 UTC
I can't reproduce Sebastian's latest report.

This screenshot shows it drawing correctly for me
http://muse.19inch.net/~jr/tmp/umbrello-drawing.png

It doesn't even have problems if I change the typeface and font size.

Can anyone else confirm?

Comment 9 Sebastian Stein 2004-01-07 09:08:22 UTC
Created attachment 4016 [details]
2 widgets with missing pixels
Comment 10 Sebastian Stein 2004-01-11 16:47:06 UTC
It is working in most cases and I think it isn't a very critical bug. Nevertheless, it isn't fixed at all.
Comment 11 Peter Soetens 2005-08-25 17:09:41 UTC
Created attachment 12370 [details]
PATH Fixes to narrow classifier boxes for italics and templates

Hi,
This patch fixes two bugs (trunk, today):

After digging trough the classifier code, I found that the QFontMetric was not
correctly used to measure _italic_ text, such as abstract classes/functions.
The old method used fnt.width("string"), which returns the minimal width after
which you may place the next character. You needed to use
fnt.size(0,"string").width(), which returns the full bounding box (QBox) and
which width is the actual width we need.

Next, when templates were used, the template-added pixelwidth was added at the
wrong place, discarding it actually.

Tested and looks beautiful !

Peter
Comment 12 Peter Soetens 2005-08-25 23:14:11 UTC
Created attachment 12375 [details]
PATCH fixes all cases of wrong width settings in classifierwidget.cpp

This patch also fixes the width of the template name in classifiers. This could
only be seen when exporting to EPS for some reason... I iterated over all uses
of width() in this file, this patch should fix all of them.

Peter.
Comment 13 Oliver Kellogg 2005-08-27 21:40:33 UTC
SVN commit 454047 by okellogg:

BUG:66461 - Comment #11 From Peter Soetens 2005-08-25 17:09
> This patch fixes two bugs (trunk, today): 
>  
> After digging trough the classifier code, I found that the QFontMetric was not 
> correctly used to measure _italic_ text, such as abstract classes/functions. 
> The old method used fnt.width("string"), which returns the minimal width after 
> which you may place the next character. You needed to use 
> fnt.size(0,"string").width(), which returns the full bounding box (QBox) and 
> which width is the actual width we need. 
> 
> Next, when templates were used, the template-added pixelwidth was added at the 
> wrong place, discarding it actually. 



 M  +2 -2      ChangeLog  
 M  +20 -17    umbrello/classifierwidget.cpp  


--- branches/KDE/3.5/kdesdk/umbrello/ChangeLog #454046:454047
@@ -9,8 +9,8 @@
 * Automatic Diagram Layout (67059, not yet closed)
 
 * Bugs fixed / wishes implemented (see http://bugs.kde.org)
- 57588  58809  67719  72016  79433  87252  88117  97162 105564 108223
-109591 109636 110216 110231 110379 111470 111502
+ 57588  58809  66461  67719  72016  79433  87252  88117  97162 105564
+108223 109591 109636 110216 110231 110379 111470 111502
 
 Version 1.4.2 (maintenance release)
 
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/classifierwidget.cpp #454046:454047
@@ -316,23 +316,15 @@
 
     const QFontMetrics &fm = getFontMetrics(UMLWidget::FT_NORMAL);
     const int fontHeight = fm.lineSpacing();
+    // width is the width of the longest 'word'
     int width = 0, height = 0;
 
-    // consider template box
-    QSize templatesBoxSize = calculateTemplatesBoxSize();
-    if (templatesBoxSize.width() != 0) {
-        width += templatesBoxSize.width() / 2;
-    }
-    if (templatesBoxSize.height() != 0) {
-        height += templatesBoxSize.height() - MARGIN;
-    }
-
     // consider stereotype
     if (m_bShowStereotype && !m_pObject->getStereotype(false).isEmpty()) {
         height += fontHeight;
         // ... width
         const QFontMetrics &bfm = UMLWidget::getFontMetrics(UMLWidget::FT_BOLD);
-        const int stereoWidth = bfm.width(m_pObject->getStereotype());
+        const int stereoWidth = bfm.size(0,m_pObject->getStereotype()).width();
         if (stereoWidth > width)
             width = stereoWidth;
     }
@@ -347,7 +339,7 @@
         displayedName = m_pObject->getName();
     const UMLWidget::FontType nft = (m_pObject->getAbstract() ? FT_BOLD_ITALIC : FT_BOLD);
     //const int nameWidth = getFontMetrics(nft).boundingRect(displayName).width();
-    const int nameWidth = UMLWidget::getFontMetrics(nft).width(displayedName);
+    const int nameWidth = UMLWidget::getFontMetrics(nft).size(0,displayedName).width();
     if (nameWidth > width)
         width = nameWidth;
 
@@ -362,7 +354,7 @@
         for (UMLClassifierListItem *a = list.first(); a; a = list.next()) {
             if (m_bShowPublicOnly && a->getScope() != Uml::Public)
                 continue;
-            const int attWidth = fm.width(a->toString(m_ShowAttSigs));
+            const int attWidth = fm.size(0,a->toString(m_ShowAttSigs)).width();
             if (attWidth > width)
                 width = attWidth;
         }
@@ -382,12 +374,23 @@
             const QString displayedOp = op->toString(m_ShowOpSigs);
             UMLWidget::FontType oft;
             oft = (op->getAbstract() ? UMLWidget::FT_ITALIC : UMLWidget::FT_BOLD);
-            const int w = UMLWidget::getFontMetrics(oft).width(displayedOp);
+            const int w = UMLWidget::getFontMetrics(oft).size(0,displayedOp).width();
             if (w > width)
                 width = w;
         }
     }
 
+    // consider template box _as last_ !
+    QSize templatesBoxSize = calculateTemplatesBoxSize();
+    if (templatesBoxSize.width() != 0) {
+        // add width to largest 'word'
+        width += templatesBoxSize.width() / 2;
+    }
+    if (templatesBoxSize.height() != 0) {
+        height += templatesBoxSize.height() - MARGIN;
+    }
+
+
     // allow for height margin
     if (!m_bShowOperations && !m_bShowAttributes && !m_bShowStereotype) {
         height += MARGIN * 2;
@@ -500,7 +503,7 @@
     height = count * fm.lineSpacing() + (MARGIN*2);
 
     for (UMLTemplate *t = list.first(); t; t = list.next()) {
-        int textWidth = fm.width( t->toString() );
+        int textWidth = fm.size(0, t->toString() ).width();
         if (textWidth > width)
             width = textWidth;
     }
@@ -578,7 +581,7 @@
         int y = offsetY + MARGIN;
         for ( UMLTemplate *t = tlist.first(); t; t = tlist.next() ) {
             QString text = t->toString();
-            p.drawText(x, y, fm.width(text), fontHeight, AlignVCenter, text);
+            p.drawText(x, y, fm.size(0,text).width(), fontHeight, AlignVCenter, text);
             y += fontHeight;
         }
     }
@@ -689,7 +692,7 @@
     } else {
         displayedName = m_pObject->getName();
     }
-    const int nameWidth = fm.width(displayedName);
+    const int nameWidth = fm.size(0,displayedName).width();
     if (nameWidth > width)
         width = nameWidth;
     width += MARGIN * 2;
@@ -711,7 +714,7 @@
         f.setUnderline( obj->getStatic() );
         p.setFont( f );
         QFontMetrics fontMetrics(f);
-        p.drawText(x, y, fontMetrics.width(text), fontHeight, AlignVCenter, text);
+        p.drawText(x, y, fontMetrics.size(0,text).width(), fontHeight, AlignVCenter, text);
         f.setItalic(false);
         f.setUnderline(false);
         p.setFont(f);
Comment 14 Oliver Kellogg 2005-09-10 12:37:15 UTC
*** Bug 107389 has been marked as a duplicate of this bug. ***