KMessageBox preferred size algorithm

mauricio at tabuleiro.com mauricio at tabuleiro.com
Fri Aug 11 21:35:22 BST 2006


Hi. I came across some layout issues when using KMessageBox, with longer
text being cut, usually half a line on the bottom or half a character at
left. This was happening with several screens of KGoldrunner and were
reported as sighted in KBlackbox as well (new KDE 4 ports, using QGV).

I traced the problem to a commit 40 days ago in kmessagebox.cpp (commit
559160), where an extra 10 pixel margin was removed. I restored the
previous behavior, which was the same used in KDE3. The svn commit log for
kmessagebox.cpp (today) includes more information.

However, I would like to find a more definitive solution to this problem.
The line in question is now

label2->setFixedSize(QSize(pref_width + 10, pref_height + 10));

And pref_width and pref_height are calculated in a routine just above its
usage, reproduced below for your convenience. Notice that the
Q3SimpleRichText widget is never used, it is just set with the same text
used in the label (qt_text) and used only to calculate the best geometry,
as Q3SimpleRichText has the widthused() property.

  // Calculate a proper size for the text.
    {
       Q3SimpleRichText rt(qt_text, dialog->font());
       QRect d = KGlobalSettings::desktopGeometry(dialog);

       pref_width = d.width() / 3;
       pref_height = label2->heightForWidth(pref_width);

       rt.setWidth(pref_width);
       int used_width = rt.widthUsed();
       pref_height = rt.height();
       if (3*pref_height > 2*d.height())
       {
          // Very high dialog.. make it wider
          pref_width = d.width() / 2;
          rt.setWidth(pref_width);
          used_width = rt.widthUsed();
          pref_height = rt.height();
       }
       if (used_width <= pref_width)
       {
          while(true)
          {
             int new_width = (used_width * 9) / 10;
             rt.setWidth(new_width);
             int new_height = rt.height();
             if (new_height > pref_height)
                break;
             used_width = rt.widthUsed();
             if (used_width > new_width)
                break;
          }
          pref_width = used_width;
       }
       else
       {
          if (used_width > (pref_width *2))
             pref_width = pref_width *2;
          else
             pref_width = used_width;
       }
   }

What would be the correct way to calculate this without using the
intermediary Q3SimpleRichText, preferrably using the QLabel that will be
displayed directly? I am still getting used to setting layouts in code.
Until now all my usage of Qt was based on Designer .ui files, and things
usually "just worked" right for me, without the need to tweak the size
hints or anything like that.

Regards,
Mauricio Piacentini





More information about the kde-core-devel mailing list