Bug 73202 - Text / Font problems with kweather with horizontal kicker
Summary: Text / Font problems with kweather with horizontal kicker
Status: RESOLVED FIXED
Alias: None
Product: kweather-kde3
Classification: Applications
Component: general (show other bugs)
Version: unspecified
Platform: Gentoo Packages Linux
: NOR normal
Target Milestone: ---
Assignee: geiseri
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-01-22 02:06 UTC by Jon Jaloszynski
Modified: 2006-12-28 01:06 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments
Image of kweather exhibiting the first problem. (30.01 KB, image/jpeg)
2004-01-22 02:07 UTC, Jon Jaloszynski
Details
Image of kweather exhibiting the first problem. (30.87 KB, image/jpeg)
2004-01-22 02:07 UTC, Jon Jaloszynski
Details
Shot showing problem (applet is on the left) (38.33 KB, image/png)
2005-04-12 02:46 UTC, Rob
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jon Jaloszynski 2004-01-22 02:06:05 UTC
Version:           2.1.0 (using KDE 3.2.1 RC1) (using KDE KDE 3.2.0)
Installed from:    Gentoo Packages
Compiler:          gcc version 3.2.3 20030422 (Gentoo Linux 1.4 3.2.3-r1, propolice)
 
OS:          Linux

There are two problems that I have observed with a horizontal kicker containing the kweather applet.  I believe that they are related.  Neither of these problems occurs all of the time, but there is a series of steps that can be performed to reproduce them.

The first problem appears when kweather is using "show icon and temerature" mode.  The base of the temperature text is roughly aligned with the center of the weather icon.  At the font size that is used, the top of the temperature text is cut off.  To reproduce this problem:
1) Start kweather in a horizontal kicker
2) Go to the kweather configuration dialog.
3) Select "Show icon only".  Press apply.
4) Select "Show icon, temperature, wind, and pressure information".  Press apply.
5) Select "Show icon and temperature".  Press apply.
The problem should now be apparent.

The second problem involves the temperature not being displayed when kweather is in "show icon, temperature, wind, and pressure information" mode.  The icon, wind speed, and pressure are all shown, but the temperature is missing.  To produce this problem.
1) Start kweather in a horizontal kicker
2) Go to the kweather configuration dialog.
3) Select "Show icon only".  Press apply.
4) Select "Show icon and temperature".  Press apply.
5) Select "Show icon, temperature, wind, and pressure information".  Press apply.
The problem should now be apparent.

Note that the two procedures are almost identical, except that steps 4 and 5 are reversed.  Either of "Show icon and temperature" or "Show icon, temperature, wind, and pressure information" will display the text correctly if kweather has just been in "show icon only" mode.
Comment 1 Jon Jaloszynski 2004-01-22 02:07:07 UTC
Created attachment 4284 [details]
Image of kweather exhibiting the first problem.
Comment 2 Jon Jaloszynski 2004-01-22 02:07:36 UTC
Created attachment 4285 [details]
Image of kweather exhibiting the first problem.
Comment 3 Rob 2005-04-12 02:46:53 UTC
Created attachment 10586 [details]
Shot showing problem (applet is on the left)
Comment 4 Rob 2005-04-12 02:47:35 UTC
About a year later, I have the same problem on KDE 3.4 on (K)Ubuntu. The text of the weather applet is cut off unless I increase the size of my panel. I'm not sure if it is a problem with the icon being too big or the text being too big.
Comment 5 Rob 2005-04-12 02:49:36 UTC
A few things to add... the applet is on the RIGHT, and my kindergarten teacher should shoot me.
Comment 6 Martin Koller 2006-12-28 01:06:10 UTC
SVN commit 617101 by mkoller:

BUG: 81098
BUG: 73202
BUG: 134387

Fix layouting in all different display modes and kicker orientation modes
Always use a sane font size and limit overall size of applet


 M  +209 -68   dockwidget.cpp  
 M  +2 -2      weatherbutton.h  


--- branches/KDE/3.5/kdetoys/kweather/dockwidget.cpp #617100:617101
@@ -21,7 +21,7 @@
 #include "weatherservice_stub.h"
 
 #include <qtooltip.h>
-#include <qvbox.h>
+#include <qlayout.h>
 #include <qlabel.h>
 #include <qtimer.h>
 
@@ -32,11 +32,11 @@
 dockwidget::dockwidget(const QString &location, QWidget *parent,
         const char *name) : QWidget(parent,name), m_locationCode( location ), m_orientation( Horizontal )
 {
+    m_font = KGlobalSettings::generalFont();
     initDock();
     connect(m_button, SIGNAL( clicked() ), SIGNAL( buttonClicked() ));
 
     m_weatherService = new WeatherService_stub( "KWeatherService", "WeatherService" );
-    m_font = KGlobalSettings::generalFont();
 
     setBackgroundOrigin( AncestorOrigin );
 }
@@ -176,6 +176,18 @@
     m_lblWind->setMargin(0);
     m_lblPres->setMargin(0);
 
+    QBoxLayout *mainLayout = new QBoxLayout(this, QBoxLayout::TopToBottom);
+    mainLayout->setSpacing(0);
+    mainLayout->setMargin(0);
+    mainLayout->addWidget(m_button, 0, Qt::AlignCenter);
+
+    QBoxLayout *layout = new QBoxLayout(mainLayout, QBoxLayout::TopToBottom);
+    layout->setSpacing(0);
+    layout->setMargin(0);
+    layout->addWidget(m_lblTemp);
+    layout->addWidget(m_lblWind);
+    layout->addWidget(m_lblPres);
+
     updateFont();
 
     QTimer::singleShot( 0, this, SLOT( showWeather() ) );
@@ -187,86 +199,168 @@
     kdDebug(12004) << "Changing to size " << size << endl;
     resize(size);
 
-    int w = size.width();
-    int h = size.height();
-
-    if (m_orientation == Horizontal)
+    if ( m_orientation == Horizontal ) // Kicker in horizontal mode
     {
-        // in case we previously set this to hcenter previously
-        // and now change the layout
-        m_lblTemp->setAlignment(AlignVCenter);
+        int h = size.height();
 
-        // Kicker in horizontal mode
-        if( m_mode == ShowAll)
+        if ( m_mode == ShowAll )
         {
-            m_lblTemp->setGeometry(h+1, 0, w-h, h/3);
-            m_lblWind->setGeometry(h+1, h/3, w-h, h/3);
-            m_lblPres->setGeometry(h+1, 2*h/3, w-h, h/3);
-            m_button->setGeometry(0, 0, h, h);
+            if ( h <= 128 )  // left to right layout
+            {
+                static_cast<QBoxLayout*>(layout())->setDirection(QBoxLayout::LeftToRight);
+                m_lblTemp->setAlignment(Qt::AlignAuto | Qt::AlignVCenter);
+                m_lblWind->setAlignment(Qt::AlignAuto | Qt::AlignVCenter);
+                m_lblPres->setAlignment(Qt::AlignAuto | Qt::AlignVCenter);
+            }
+            else  // top to bottom
+            {
+                static_cast<QBoxLayout*>(layout())->setDirection(QBoxLayout::TopToBottom);
+                QFontMetrics fm(m_font);
+                h = 128 - (3 * fm.height());  // 3 lines of text below the button
+                m_lblTemp->setAlignment(Qt::AlignCenter);
+                m_lblWind->setAlignment(Qt::AlignCenter);
+                m_lblPres->setAlignment(Qt::AlignCenter);
+            }
+            m_button->setFixedSize(h, h);
         }
-        else if ( m_mode == ShowTempOnly)
+        else if ( m_mode == ShowTempOnly )
         {
-            if (h > 32)
+            if ( h <= 32 )  // left to right
             {
-                m_lblTemp->setAlignment(AlignVCenter | AlignHCenter);
-                m_lblTemp->setGeometry(1, h - h/5, w - 2, h/5);
-                m_button->setGeometry(0, 0, 4*h/5, 4*h/5);
+                static_cast<QBoxLayout*>(layout())->setDirection(QBoxLayout::LeftToRight);
+                m_lblTemp->setAlignment(Qt::AlignAuto | Qt::AlignVCenter);
             }
-            else
+            else  // top to bottom
             {
-                m_lblTemp->setGeometry(h+1, 0, w-h, h);
-                m_button->setGeometry(0, 0, h, h );
+                static_cast<QBoxLayout*>(layout())->setDirection(QBoxLayout::TopToBottom);
+                QFontMetrics fm(m_font);
+                h = QMIN(128, h) - fm.height();
+                m_lblTemp->setAlignment(Qt::AlignCenter);
             }
+            m_button->setFixedSize(h, h);
         }
         else
         {
-            m_button->setGeometry(0, 0, h, h );
+            h = QMIN(h, 128);
+            m_button->setFixedSize(h, h);
         }
     }
-    else
+    else // Kicker in vertical mode
     {
-        // Kicker in vertical mode
-        if( m_mode == ShowAll)
+        int w = size.width();
+        int h = size.height();
+
+        if ( m_mode == ShowAll )
         {
-            m_lblTemp->setGeometry(0, w, w, w/3);
-            m_lblWind->setGeometry(0, 4*w/3, w, w/3);
-            m_lblPres->setGeometry(0, 5*w/3, w, w/3);
+            if ( w <= 128 )  // top to bottom
+            {
+                static_cast<QBoxLayout*>(layout())->setDirection(QBoxLayout::TopToBottom);
+                m_lblTemp->setAlignment(Qt::AlignCenter);
+                m_lblWind->setAlignment(Qt::AlignCenter);
+                m_lblPres->setAlignment(Qt::AlignCenter);
+
+                QFontMetrics fm(m_font);
+                h = h - (3 * fm.height());  // 3 lines of text below the button
+                h = QMIN(w, h);
+            }
+            else  // left to right layout
+            {
+                static_cast<QBoxLayout*>(layout())->setDirection(QBoxLayout::LeftToRight);
+                m_lblTemp->setAlignment(Qt::AlignAuto | Qt::AlignVCenter);
+                m_lblWind->setAlignment(Qt::AlignAuto | Qt::AlignVCenter);
+                m_lblPres->setAlignment(Qt::AlignAuto | Qt::AlignVCenter);
+            }
+            m_button->setFixedSize(h, h);
         }
-        else if ( m_mode == ShowTempOnly)
+        else if ( m_mode == ShowTempOnly )
         {
-            m_lblTemp->setGeometry(1, w, w, h-(w+1) );
+            if ( w <= 128 )  // top to bottom
+            {
+                static_cast<QBoxLayout*>(layout())->setDirection(QBoxLayout::TopToBottom);
+                m_lblTemp->setAlignment(Qt::AlignCenter);
+
+                h = w;
+            }
+            else  // left to right layout
+            {
+                static_cast<QBoxLayout*>(layout())->setDirection(QBoxLayout::LeftToRight);
+                m_lblTemp->setAlignment(Qt::AlignAuto | Qt::AlignVCenter);
+
+                h = static_cast<int>(w * 0.33);
+            }
+            m_button->setFixedSize(h, h);
         }
-        m_button->setGeometry(0, 0, w, w );
+        else
+        {
+            w = QMIN(w, 128);
+            m_button->setFixedSize(w, w);
+        }
     }
-    updateFont();
 }
 
 int dockwidget::widthForHeight(int h)
 {
-    int w=h;
-    QFontMetrics fm(m_font);
+    int w;
+    QFontInfo fi(KGlobalSettings::generalFont());
 
-    if( m_mode == ShowAll)
+    if ( m_mode == ShowAll )
     {
-        m_font.setPixelSize( h/3-2 );
-        w = h + QMAX(fm.width(m_lblWind->text()),
-        fm.width(m_lblPres->text())) + 1;
+        if ( h <= 128 )  // left to right layout
+        {
+            int pixelSize = h/3 - 3;
+            pixelSize = QMIN(pixelSize, fi.pixelSize());  // don't make it too large
+            m_font.setPixelSize(pixelSize);
+            QFontMetrics fm(m_font);
+            w = h + QMAX(fm.width(m_lblWind->text()), fm.width(m_lblPres->text())) + 1;
+        }
+        else  // top to bottom
+        {
+            if ( fi.pixelSize() * 3 <= (h/2) )  // half icon, half text
+            {
+                m_font = KGlobalSettings::generalFont();
+            }
+            else
+            {
+                m_font.setPixelSize(h/2/3);
+            }
+            QFontMetrics fm(m_font);
+            // size of icon
+            h = 128 - (3 * fm.height());  // 3 lines of text below the button
+            w = QMAX(fm.width(m_lblWind->text()), fm.width(m_lblPres->text())) + 1;
+            w = QMAX(h, w);  // at least width of square icon
+        }
     }
-    else if ( m_mode == ShowTempOnly)
+    else if ( m_mode == ShowTempOnly )
     {
-        QFontInfo fi( KGlobalSettings::generalFont() );
-        int pixelSize = QMIN( h, fi.pixelSize() );
-        m_font.setPixelSize( pixelSize );
-
-        if (h > 32)
+        if ( h <= 32 )  // left to right layout
         {
-            w = 4*h/5;
+            int pixelSize = h - 3;
+            pixelSize = QMIN(pixelSize, fi.pixelSize());  // don't make it too large
+            m_font.setPixelSize(pixelSize);
+            QFontMetrics fm(m_font);
+            w = h + fm.width(m_lblTemp->text()) + 1;
         }
-        else
+        else  // top to bottom
         {
-            w = h + fm.width(m_lblTemp->text()) + 1;
+            if ( fi.pixelSize() <= (h/2) )  // half icon, half text
+            {
+                m_font = KGlobalSettings::generalFont();
+            }
+            else
+            {
+                m_font.setPixelSize(h/2);
+            }
+            QFontMetrics fm(m_font);
+            // size of icon
+            h = QMIN(128, h) - fm.height();
+            w = fm.width(m_lblTemp->text()) + 1;
+            w = QMAX(h, w);  // at least width of square icon
         }
     }
+    else
+    {
+        w = QMIN(128, h);  // don't make it too large
+    }
 
     updateFont();
     return w;
@@ -275,33 +369,80 @@
 int dockwidget::heightForWidth( int w )
 {
     int h;
-    // Adjust the height of the font to compensate for width
-    int startSize = w;
-    int width = w + 1;
 
     if ( m_mode == ShowAll )
     {
-       while( (width > w)  && (startSize > 0))
-       {
-           m_font.setPixelSize( --startSize );
-           QFontMetrics fm(m_font);
-           width = QMAX(fm.width(m_lblWind->text()),
-                        fm.width(m_lblPres->text()));
-       }
-       h = ( w * 2 );
+        QFontMetrics fmg(KGlobalSettings::generalFont());
+        int maxWidth = fmg.width("888 km/h NNWW");  // a good approximation
+
+        if ( w <= 128 )  // top to bottom
+        {
+            if ( maxWidth <= w )  // enough space to use global font
+            {
+                m_font = KGlobalSettings::generalFont();
+            }
+            else  // we have to reduce the fontsize
+            {
+                m_font.setPixelSize(static_cast<int>(fmg.height() * double(w) / maxWidth));
+            }
+
+            QFontMetrics fm(m_font);
+            h = w + (3 * fm.height());  // 3 lines of text below the button
+        }
+        else
+        {
+            if ( w >= (maxWidth * 1.5) )  // half of text width shall be icon
+            {
+                m_font = KGlobalSettings::generalFont();
+            }
+            else
+            {
+                m_font.setPixelSize(static_cast<int>(fmg.height() * (w*0.66) / maxWidth));
+            }
+
+            QFontMetrics fm(m_font);
+            h = 3 * fm.height();  // 3 lines of text
+
+        }
     }
     else if ( m_mode == ShowTempOnly )
     {
-       while( (width > w)  && (startSize > 0))
-       {
-           m_font.setPixelSize( --startSize );
-           QFontMetrics fm(m_font);
-           width = fm.width(m_lblTemp->text());
-       }
-       h = w + startSize + 2;
+        QFontMetrics fmg(KGlobalSettings::generalFont());
+        int maxWidth = fmg.width("888.88 CC");  // a good approximation
+
+        if ( w <= 128 )  // top to bottom
+        {
+            if ( maxWidth <= w )  // enough space to use global font
+            {
+                m_font = KGlobalSettings::generalFont();
+            }
+            else  // we have to reduce the fontsize
+            {
+                m_font.setPixelSize(static_cast<int>(fmg.height() * double(w) / maxWidth));
+            }
+
+            QFontMetrics fm(m_font);
+            h = w + fm.height();  // text below the button
+        }
+        else
+        {
+            if ( w >= (maxWidth * 1.5) )  // half of text width shall be icon
+            {
+                m_font = KGlobalSettings::generalFont();
+            }
+            else
+            {
+                m_font.setPixelSize(static_cast<int>(fmg.height() * (w*0.66) / maxWidth));
+            }
+
+            QFontMetrics fm(m_font);
+            h = QMAX(fm.height(), static_cast<int>(w * 0.33));
+        }
     }
     else
-        h = w;
+    {
+        h = QMIN(128, w);  // don't make it too large
+    }
 
     updateFont();
     return h;
--- branches/KDE/3.5/kdetoys/kweather/weatherbutton.h #617100:617101
@@ -34,8 +34,8 @@
   protected:
     void drawButton( QPainter *p );
     void drawButtonLabel( QPainter *p );
-    QSize margin() const { return QSize( 5, 5 ); }
-    QSize pixmapSize() const { return size() - margin(); }
+    QSize margin() const { return QSize( 3, 3 ); }
+    QSize pixmapSize() const { return size() - margin()*2; }
     QPoint pixmapOrigin() const;
     void generateIcons();