My blog has been moved to

Thursday, October 27, 2005

Wednesday, October 26, 2005

Improving QSplitter with Quantized Splitting Step

QSplitter is undoubtly quite a very useful widget. Dragging the handle allows the user to easily resize other widgets. This screenshot shows how the splitter resizes a multiline editor QTextEdit:

The font used in the editor is made deliberately large. Why? This is to show that with normal QSplitter, you may drag the mouse and move the rubber band anywhere. So you may end up resizing the editor widget right in the middle of a line, like shown above. The third line would only be half visible, or half hidden.

Wouldn't it be nice if we restrict the splitter a bit so that it won't "cut" any line? Like for example in the screenshot below. Now the rubberband is either below the fourth line or above it, it will never be in the middle of the line.

Is it possible? Of course. Fortunately Qt offers an easy way to do this. Note that I'm talking about Qt 4 here, it will be a different workaround for Qt 3.

The trick is to use a customized splitter and its handle.

So first derive a new class from QSplitter, e.g. CustomSplitter and override the createHandle method, as easy as:

QSplitterHandle* CustomSplitter::createHandle()
  return new CustomSplitterHandle( this );

Of course you now need to create class CustomSplitterHandle, derived from the standard QSplitterHandle. In this class, we need to reimplement two mouse event handlers: mouseMoveEvent and mouseReleaseEvent.

The first one should look like:

void CustomSplitterHandle::mouseMoveEvent(QMouseEvent *e)
  if( !(e->buttons() & Qt::LeftButton) )
  QFont font("Arial",20)  ;
  QFontMetrics fm( font );
  int fh = fm.height();
  int margin = 2;
  int pos = parentWidget()->mapFromGlobal(e->globalPos()).y();
  pos = pos - margin;
  pos = (int)(pos/fh)*fh;
  pos = pos + margin;
  splitter->setRubberBand( closestLegalPosition(pos) );

For illustration purpose, I hardcode the splitter step as the height of Arial, 20pt font. And I also only consider the case where the splitter's orientation is vertical and it is in opaque sizing mode. As you can see, variable pos here will only be an integer multiple of the step, thereby giving a quantized step for the handle movement.

Moving the rubber band itself does not resize the widget. So mouseReleaseEvent needs to be implemented as well, like shown herebelow. Note the much duplicate code...

void CustomSplitterHandle::mouseReleaseEvent(QMouseEvent *e)

  QFont font("Arial",20)  ;
  QFontMetrics fm( font );
  int fh = fm.height();
  int margin = 2;
  int pos = parentWidget()->mapFromGlobal(e->globalPos()).y();
  pos = pos - margin;
  pos = (int)(pos/fh)*fh;
  pos = pos + margin;

  moveSplitter( pos );

Don't forget to make class CustomSplitterHandle as a friend of CustomSplitter. If they are not in good friendship, moveSplitter will not work.

When can this trick be useful? At least, in a spreadsheet application. Seasoned Excel users know that splitting a worksheet into two (and into four) parts exactly works in this way. Excel won't divide the view halfway within one column, the splitter is always positioned between two columns. Also, in the upcoming Excel 12, user can resize the formula bar so it will not be a single line anymore. I bet that you can't make it one-and-half line.

Tuesday, October 25, 2005

Function AutoComplete

Range highlighting is not enough? Well, how about autocomplete for function name:

It was quite easy because I just need to adapt the fancy completion code that I have already. I still need to polish this (and check for bugs) before committing to SVN. Likely however that it will make it into next KOffice 1.5.

And, seems that Microsoft Office people are doing the same :-P

Keep the Changes

Though sounds like a chapter in Tom Clancy's technothriller, this doctored report scandal is for real. United Nations - in its investigation report on the assassination of Rafik Hariri (ex-Lebanese Prime Minister) - simply dropped some names and changed them to unnamed reference e.g. "officials". However, the original version was possible to be easily constructed because changes were made using the track changes feature of Microsoft Word and apparently somebody forgot to click Accept All Changes, thus leaving the changes intact.

You can see yourself the HTML-version of the document. The parts striked in red were deleted later for the final draft, but these still exist and quite readable.

Monday, October 24, 2005

Asymmetrical Tabs

As part of my janitor work, some time ago I rewrote the tab bar in KOffice - used among others in KSpread to select the active worksheet. To get more familiar with Qt 4, I decided to port it to Qt 4 which turned out to be easier than I thought:

Also I changed the look so that each tab becomes asymmetric, i.e. only one of the sides is angled, just like tabs in Microsoft Office 12.

Expect this to appear in (still in the) future KDE4-based KOffice. Oh yes, the new setRenderHint(QPainter::Antialiasing) is of course abused here :-)

Friday, October 21, 2005

Highlight is Cool, Dragging is Sweet

Few weeks ago, Robert Knight has implemented formula editing with color syntax highlighting (in KSpread). Not only that, ranges referred in the formula can be modified by dragging the size grip:

SVN users can already enjoy this. Or, just wait for KOffice 1.5 next year.

Thanks to Robert, now we're on par with Excel.

Thursday, October 20, 2005

Qt 4.1 Sports PDF Print, Backing Store, Highlighter

The upcoming Qt 4.1 will bring a new print engine: PDF. Yes, that's the Portable Document Format. A quick glance at the code reveals that it will be at PDF 1.4. We don't need to go to PostScript first and the use ps2pdf. All you need to create a PDF file from your application is:

  QPrinter printer( QPrinter::HighResolution );

  printer.setOutputFormat( QPrinter::PdfFormat );
  printer.setOutputFileName( "test.pdf" );
  QPainter painter;
  painter.setPen( Qt::red );
  painter.drawRect( printer.pageRect() );
  painter.drawLine( printer.pageRect().topRight(), 
    printer.pageRect().bottomLeft() );

The above example draws red borders and a diagonal line in the paper. Note that somehow I still couldn't manage to output text. Either it is not supported (yet) or I made mistake.

Another neat feature is per-window backing store as it has been hinted by Matthias Ettrich. I do not know exactly what is backing store (perhaps some gurus can explain it?), but I supposed it will surpress flickers and give perceived smoothness in painting operations.

Last but not least, QSyntaxHighlighter for Qt 4's QTextEdit will make a debut. The lack of this in Qt 4.0 made implementing my favorite expressions highlighting difficult, but now I worry no more.

Qt 4.1 will be cool.

Wednesday, October 19, 2005

Spook in Your Office/House

Do you realize that something in your office/house might work for Secret Service? According to EFF, print outs from Xerox DocuColor have hidden information for forensic tracking. See, these yellow dots look harmful:

...BUT someone can reveal that e.g. it was printed on June 21st, 2006 2005 !

So far, only code from Xerox DocuColor printers has been cracked, though EFF researchers believe similar things appear in other printers as well.

Tuesday, October 18, 2005


In the upcoming Excel 12, there is a kind of visualization called data bars. When applied to a certain range, bars with gradient color appear on each of the cell, the length corresponds to the relative value of the cell.

I suppose it is a matter of time before this feature is cloned in other spreadsheet programs.

Dancing with Noatun

Everybody loves JuK and/or Amarok. However, one hidden gem of Noatun is usually all I need to impress friends with KDE. This old feature (dated back to KDE 2.2 time) never failed me.

Launch Noatun, then choose menu Settings, Configure Noatun. Click Plugins icon from the list on the left, continue to tab named Visualizations. Now make sure entry Madness is checked and then click OK.

Open few windows just to populate the desktop. Harmless things like some folders opened in Konqueror will be fine.

Pick an interesting song which suits your audience well, play the song in Noatun, and see how they are stunned watching all those dancing windows!

Monday, October 17, 2005

Help! I can't run my program!

I do not know who invented this trick for the first time.

First, choose your victim and get access to her/his computer. Next, launch an image editing tool, e.g. Gimp. Take a screenshot of her/his desktop, select one of the shortcut icons (preferably the favorite one, of course) as the bait, and copy this icon. Find out the real background image/wallpaper, duplicate it to a new file, load this into your image editor. Put the wonderful icon that you just copied (from the desktop screenshot), place it on the new image, save it. Now, change the background image/wallpaper to this booby trap. The chosen icon/bait still appears twice, one as the real shortcut and the other embodied in the background. Delete the shortcut and you are ready.

When your victim wants to use the computer back, and s/he tries to click the shortcut icon to launch the program, of course it will not work! In fact, s/he just hits emtpy space...

Next Level, Slipstream, Flying Daggers, Hostage

xXx: Next Level was a big disappointment (and I hope they bring back Vin Diesel for third installment, if they ever want to make it). Unbelievable storyline can be forgiven, but not the one-liners and poor casts. Xzibit's appearance was perhaps entertaining, especially for those who watch MTV PMR regularly.

Slipstream's idea was not genuine and hence many parts were very much predictable. I mean, if you have a time-machine (or a prototype thereof, whatever) and your beloved died, what you would do can be guessed easily.

House of Flying Daggers was nice and as usual, full of colors. But do not expect the same level (of anything, including the fight scenes) to that of Hero or Tiger and Dragon. Hopefully the next Hollywood wuxia movie will be better.

Hostage was supposed to be a thriller, fortunately it didn't expose the action parts too much. Although it was also not too complicated, it still made me want to read the novel.

Saturday, October 15, 2005

Navigating Between Sheets

After reading Gary's excellent accessibility assessment for KOffice, I'd like to share here one tip of KSpread which may be useful.

Normally you navigate between sheets by using the so-called sheet tab, it sits on the bottom left corner (or right corner, if your sheet is right-to-left). Unfortunately, this might be difficult for low-sighted person as the buttons there are small:

The alternative way is to use the navigational tool bar. This is hidden by default, so go to menu Settings, Toolbars, Navigation and then it will show up:

The buttons in this tool bar can be made large (i.e. in 48 pixels) if necessary.

For mouseless operation, of course this tool bar does not help. But you can use the assigned keyboard shortcut: Ctrl+PageDown for previous sheet and Ctrl+PageUp for next sheet.

Friday, October 14, 2005

12-bit Microsoft Excel's Format Index

Guess how does Microsoft Excel store formatting information for the cells? Amazing to see that such a simple knowledge base article Q213904 can reveal the answer and lead to an explanation (although because I never see Excel's source code, this is mostly just an educated guess).

I bet you also prompty associate that "...approximately 4,000 different combinations of cell formats..." to an index which is 12-bit wide. It is likely that when the user formats a cell, that formatting information is actually stored somewhere and only the index to the format is stored in the cell. To be more efficient, I also believe that a formatted range also shares the space, i.e. the same index numbers are not duplicated in all its contained cells. And knowing Excel, I am not astonished if a bunch of these are allocated for special format - for example as trivial as 0 marks no formatting at all.

And for the next Microsoft Office 12, this index is apparently upgraded to 16-bit.

Thursday, October 13, 2005

DOOM: The Movie

Who can forget DOOM? Now, before its 12th birthday, the movie that we all have been waiting will be out. This will definitely make into my list. I can't wait, for example, to find out whether Spider Mastermind makes an appearance, and whether some guy picks up the chainsaw to fight the demons. Visual effect of BFG9000's impact will be also wonderful. And I am eager as well to know what this Dr. Carmack (yes, that the name of one of the characters) is doing there!

In the mean time, just get the trailers.

Wednesday, October 12, 2005

Optimization for Pipelining

A unit block that I worked on was interesting. It is not memoryless, and by certain optimization one could precompute part of the next output. Therefore, this system can give a correct output almost immediately, only after taking account the current input, although the whole processing steps will still finish some time later.

At first I didn't really pay attention to this. I thought, it was just a waste. When the computing process is not really finished anyway, I still can't trigger the system for next operation, although I get its output already.

It was not until I had to form a bigger system by cascading these blocks, then I realized how it saved my day. When three such blocks are cascading, the second one needs to wait for the output of the first, and so does the last one. By giving the output as soon as possible for the next stage, the total time needed to undertake the cascading operation is of course shortened!

The above graph shows the idea. Just assume x-axis represents time and it should be really clear. The small arrow denotes the time where the output of a gray block is ready to be fetched and which (in this configuration) will be fed to the next block. The big arrow show how long it takes until the last stage's output is available. It is faster compared to the case where you just give the output of a block at the end of its processing:

Optimization rocks!

Tuesday, October 11, 2005

New Home

For various reasons, from now on I decide to blog in this new place. Of course, previous blog entries in are still always available.