Better width with Open Sources…

While the Decoding table is being redone for KDE 4.2 there was a bug report pending about the old version of it, in that larger values do not fit into the witdh of the value fields.

The culprit code:

QFontMetrics metric( font() );
const int int16Width = metric.width( "88888888" );
KLineEdit* mInt16Display = new KLineEdit( this );
mInt16Display->setFixedWidth( int16Width );

Bogus, as the width of the lineedit widget also includes the width of the frame plus some left and right margins, not just the width of the rendered string.

While this report was filed as a wish, I considered it still as a bug. And because it looked simple (and to keep the Zarro-Boogs state for Okteta 🙂 ) I navigated my editor to the 4.1 branch… to find out, it wasn’t that simple to fix.

There is no such thing as a void QTreeView::resizeColumnToContents() for QLineEdit, or similar. So I tried QSize QStyle::sizeFromContents(), but the results were not as expected, the widget was always to small.

Frustration. The night was becoming longer. This *peep* little thing should be solveable somehow.

“Use the Source, Luke!” I remembered. Oh yes, of course, the Power of White boxes. A quick look at the implementation of QSize QLineEdit::sizehint() const showed that the content of a QLineEdit also includes the margins, for whatever reason. And, oh shame for the responsible, there are some hardcoded additional margins not exposed by functions like void void QWidget::getContentsMargins(), looks like work in progress. But then it was documented, by the source code itself, so that’s what makes it different from some Blackbox toolkit.

Now the fixing code:

KLineEdit* mInt16Display = new KLineEdit( this );
const int verticalMargin = 1; // hardcoded in gui/widgets/qlineedit.cpp
const int horizontalMargin = 2; // hardcoded in gui/widgets/qlineedit.cpp
const int mysticBonusMargin = 1; // no idea where it come from, but with one pixel more it is equally margined
int leftMargin, rightMargin, topMargin, bottomMargin;
mInt16Display->getContentsMargins( &leftMargin, &topMargin, &rightMargin, &bottomMargin );

QFontMetrics metric( font() );
const int int16Width = metric.width( "88888888" );
const int lineSpacing = fontMetrics.lineSpacing();

const int minLineSpacing = 14;
const int contentHeight =
+ topMargin + 2 * verticalMargin + bottomMargin;
const int contentOtherWidth = leftMargin + 2 * horizontalMargin + rightMargin + mysticBonusMargin;
const QSize int16ContentSize( int16Width + contentOtherWidth, contentHeight );

QStyleOptionFrameV2 option;
option.initFrom( mInt16Display );
option.lineWidth = mInt16Display->hasFrame() ?
style()->pixelMetric( QStyle::PM_DefaultFrameWidth, &option, mInt16Display ) : 0;
// rest of QStyleOptionFrameV2 does not seem to have an influence
const int int16DisplayWidth =
style()->sizeFromContents( QStyle::CT_LineEdit, &option, int16ContentSize, mInt16Display ).width();

mInt16Display->setFixedWidth( int16DisplayWidth );

Not wonderful, should be rather a service function in QLineEdit, but well, it works.

And so the rest of the night was saved, and some users will be more happy after the release of KDE 4.1.3. Thank you, Open Sources Knights. 🙂

PS: Still I can not believe it had to be solved this complicated. What did I miss?

Update: Problems now reported via the Qt Task Tracker, to have things fixed and not just workarounded, see #231859 and #231683 🙂

New Decoder table for Okteta

Work on Okteta has been stalled a little. My pet next big feature is also big in work needed, bigger than hoped for, so it looks like it will have it’s come-out time rather with KDE 4.3.

For some quick’n’easy success I turned to the Decoding Table tool the last evenings. As it comes with the 0.1 version of Okteta, it is pretty much inspired from the one of KHexEdit, minus the bitfield width setting:

Now with 64 bit architectures pretty much spread, one data type is missing there, 64 bit integer. Also support for UTF-8 might be useful in general. And perhaps even some more, or specific ones, one day hopefully addable by plugins.

The KHexEdit style table does not scale. So for the inclusion of the new datatypes I decided to replace it with a simple two-columned list table. Now done and committed it is, heading for the KDE 4.2 release:

Please tell me, what other decoders would you generally expect in the table?