My blog has been moved to

Saturday, December 31, 2005


Good bye, 2005. Welcome to 2006!

Guess what the number means... :-P

Friday, December 30, 2005


In Qt application, outputting printf-like formatted debug message involving QString means using latin1 or utf8 such as:

QString name = "Willy Wonka";
int num = 5;
qDebug("My name is %s, I invite %d children", name.latin1(), num);

But in Qt 4.x, you can use qPrintable function:

QString str = "a chocolate factory";
qDebug("I have %s", qPrintable(str));

For non-formatted output, just use qDebug() as an output stream.

Friday, December 23, 2005

OpenMortal Combat

Remember the old good time with Mortal Kombat? Well, look no more! Why don't you try OpenMortal?

Installation is supereasy. In a standard box with SDL, that would only mean typical extract, configure, make and make install steps. Few minutes are all that you need. Mac OS X and Windows packages are also available.

OpenMortal is practically meant to be a parody, but nevertheless it is a good one and quite joyful to play. Don't expect the same touches and completeness as the original Mortal Kombat. Looking at what has been achieved so far, then it's simply amazing! The characters are for real, at least real persons whose movements are digitized and imported to the game. If you are willing to undertake the tedious steps, the you can also become a character. However, it's safe to say we would not see someone like Goro in the near future :-P

Network play is supported, but no AI means you can not play against the computer. Since that old Mortal Kombat could have such a simple (and dumb) AI in a ridiculously prehistoric machine by today's standard, I bet it's only a question of lack of contribution rather that difficulties. If you're a programmer looking for something for fun, this could be a nice holiday project indeed.

Oh, how I miss Fatality...

The Famous Cat

OK, finally I got my Schrödinger's Cat T-shirt (has nothing to do with this guy's encyclopedia). Unless you live under the rock, you would know what this shirt has different statement (about the life of the cat) on its front and back side. And if you don't live under the rock, you might want to know that this shirt can boost your charm, at least that what happened to Wil Wheaton.

Now I'm awaiting someone to make the Heisenberg version of the shirt, saying that "Schrödinger's Cat May Have Been There". That would be funny :-P

Wednesday, December 21, 2005

Language Autodetect

If you often compose mails with different languages and use spell checker quite often, GMail cleverly does not ask you in which language the mail is written, nor you need to specify one. You write in English, then English spell checker is used. You write in German, then German spell checker is used. Seems trivial, still I was happy when I realized this for the first time.

On related thing, GMail seems to use Sophos for its antivirus.

Monday, December 19, 2005

Pulsating Effect for QToolTip

About ten months ago, I played around with the idea of pulsating effect in QToolTip. Basically, the background color is changed quickly to series of some colors. See this Flash animation. The actual effect is of course much smoother than what is shown in this Flash demo.

Unfortunately that trick does not work anymore with the new Qt 4 as you can't change QToolTip's palette. However, I am able to get the solution: find the QTipLabel and then apply the same crime.

void MyWindow::beat()
  static QPointer<QLabel> tipLabel;
  static int index = 0;

    foreach(QWidget *widget, QApplication::allWidgets())
        tipLabel = qobject_cast<QLabel*>(widget);
    int k = (index>7) ? 14-index : index;
    index += (index<14) ? 1 : -14;
    QColor c = QColor( 255, 128+k*16, k*20 );
    QPalette pal = tipLabel->palette();
    pal.setColor( QPalette::Background, c );
    tipLabel->setPalette( pal );
  QTimer::singleShot(tipLabel? 100 : 1000, this, SLOT(beat()));

This is again a dirty hack, but it works as long as your program does not create its own QTipLabel and QToolTip implementation won't be radically changed.

if (party) CEO = false

I haven't read How to Become CEO yet, but looking at the excerpt, something is very interesting indeed:

There is no such thing as a business or office party. It is not a social gathering. It is business. Never party at an office party. It won't hurt you not to go at all. Don't offend people by criticizing the party or by publicly announcing your intentions. Simply don't go. Give polite excuses.

Sunday, December 18, 2005

Mission Impossible 3.0

Yes, Tom Cruise wants to catch up with the (amazing) 3.x series of KDE :-P

Mission: Impossible III will be out next summer. The teaser is already available, unfortunately nothing else has been revealed so far. Judging from the teaser, quite likely it will be the same like the last two: full of action and with boring plot. Frankly, I was quite disappointed that Ethan Hunt became more a 007-style agent, rather than one belongs to a group with astonishing teamwork skills. Let see what will happen to Ethan this time.

Trailer MI3

Thursday, December 15, 2005

Buzz, or Shake My Window

Ctrl+G is a very well-known shortcut by Yahoo! Messenger users. It means buzz your contact. Essentially, the other side will get "Buzz!" message, along with sound effect (if enabled) and the shaking of the chat window. The last part is very interesting and obviously used to steal the attention. It is difficult to explain if you never have experienced it :-)

To buzz-enabling your Qt application, here is the code snippet taken from what I have implemented for KYIM long time ago:

void Mainwin::buzz()
  int xp = x();
  int yp = y();
  QTime t;

  for ( int i = 32; i > 0; )
    if ( t.elapsed() >= 1 )
      int delta = i >> 2;
      int dir = i & 3;
      int dx = ((dir==1)||(dir==2)) ? delta : -delta;
      int dy = (dir<2) ? delta : -delta;
      move( xp+dx, yp+dy );
  move( xp, yp );

Happy buzzing !

Wednesday, December 14, 2005

Arrow in Plastique QComboBox

If you try to find the dimension and position of the combobox arrow button, one of your chance is by using subControlRect of the style in use. Unfortunately, this can not work in Plastique style because this style does not return a correct QRect associated with the arrow's geometry, as evidence from the source code:

    case CC_ComboBox:
        switch (subControl) {
        case SC_ComboBoxArrow:
            rect = option->rect;

It simply gives back option->rect which is likely the widget's own rect(). Your program might believe that the arrow occupies the whole combobox.

Fortunately, thanks to the Trolls, this problem is gone with the upcoming Qt 4.1.

But just in case you still want to work with Qt 4.0 (and 4.0.1), then you have to implement hackish fix like this:

    QRect arrowRect = style()->subControlRect(QStyle::CC_ComboBox, 
        &opt, QStyle::SC_ComboBoxArrow, this);
    if( arrowRect == opt.rect )
        // workaround for broken subControlRect
        int fw = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
        arrowRect = QRect(width()-16-fw, height()-2*fw);

Tuesday, December 13, 2005

Mostly Europe

According to Google Analytics, visitors to my blog are mostly from Europe:

Could it be because the majority of Planet KDE readers are KDE users? Will be interesting to see the result from Planet GNOME.

Monday, December 05, 2005

Virus from Aliens

Beware of the aliens, as they may send viruses: "...scientists searching the heavens for signals from extra-terrestrial civilisations are putting Earth's security at risk..."

Man, did these aliens watch Independence Day?

Friday, December 02, 2005

Scientific Example

A young English professor opened his first lecture for freshmen with a question, "Could anyone give an example of a sentence using the word learn, please?"

A student raised his hand and said, "I learn physics".

"Good", continued the professor, "but since you are now not in high school anymore, could you rather give a more interesting example? A more scientific one perhaps?"

The student thought for a few seconds. Then he came up with another example, "Albert Einstein learned physics".

Monday, November 28, 2005


N24 aired an interesting documentary film on Tenerife accident between two 747s, considered one of the biggest pre-9/11 aircraft disaster. Detailed information, including released reports and reconstructed illustrations are also available from Project Tenerife website.

This accident happened long time ago (when I was few days old), the lessons learned from it proved be to useful for improvements in the regulations. Even for people outside airline industry, it shows how good communication is indeed very very important.

The Danger of Spamming

Rick Downes is against spamming. Yet he was arrested because the police suspected that he spams people with advertisement of pharmaceutical products.

Friday, November 25, 2005

Seven-Segment Problem

After too long working on a prototype board, I had an idea to invent this question.


You have a 7-segment display. A byte is sent to the display, 7 bits are used to switch on (if the bit is set) or switch off (if the bit is reset) the segments. One bit in this byte is not used and always zero.

Values in the byte which correspond to decimal number (0 to 9) shown in the display are summarized as follows:

  "0"    0xE7 
  "1"    0x22 
  "2"    0xAD 
  "3"    0xAB 
  "4"    0x6A 
  "5"    0xCB 
  "6"    0xCF 
  "7"    0xA2 
  "8"    0xEF 
  "9"    0xEB 

Find out what value you must send so that the display shows "E".

In an interview, see how fast your candidate can get the answer (of course, you can replace "E" with another letter). Also, if he or she spends too much time studying number "8", time to try another candidate...

Thursday, November 24, 2005

Pronounciation of 'char'

From Bjarne Stroustrup's C++ FAQ:

How do you pronounce "char"?
"char" is usually pronounced "tchar", not "kar". This may seem illogical because "character" is pronounced "ka-rak-ter", but nobody ever accused English pronounciation and spelling of being logical.

All these years, I've pronounced it incorrectly...

Monday, November 21, 2005

RealTime vs Live

WordPerfect Office, since version 9, has a very nice timesaving feature called RealTime Preview. When choosing specific font from the dropdown list, the selected text is already reformatted and displayed using that font. This applies also with other types of formatting. And because the update is instant, you can scroll throughout the font list and see the text "morphs" into different look and finally choose what suits you best. This is not like in other office suite, where you need that many repetitive clicks because every time you change the font, the text just looks ugly and you have to repeat and repeat it again.

Half a decade later, Office 12 has Live Preview, which is basically the same thing.

Unzipping in C

If your C program needs to extract files from a ZIP-compressed package, using minizip (and zlib) is a fast and easy solution. Not to pollute planetkde (no pun intended here :-), a simple function to extract one file from a ZIP and write it to the specified output file is shown in this simple unzip example instead.

Friday, November 18, 2005

rand(): font, Qt 4.1, Superman, beauty

Some random goodies, welcoming the weekend.

Amusing history of Verdana and Georgia fonts. Got this link when reading Office UI blog.

Changelog for Qt 4.1 is quietly available.

Superman Returns will be out in Summer 2006. The released teaser so far contains almost nothing. Do not waste your time downloading it.

Beauty? Per definition, beauty is in the eye of the beer holder.

Unoptimize's content.xml

This is probably not of much interest for normal users.

If you work with OpenDocument and, you know that XML file produced by is not quite human-friendly as it contains no CR/LF and no indentation because it is (so to speak) "optimized" for size. The XML file of course looks ugly in normal text editor. To change this, open menu Tools, Option to bring the Options dialog. Choose Load/Save, General from the list of the left and uncheck the option Size optimization for XML format.

Thursday, November 17, 2005

No Test? It's Broken!

I'd like to add one important point to Aaron's list to good practices in open source software: extensive tests. Sure, manually testing the program is good, but since open-source software is done mostly by volunteers, tests that run by themselves are of great help. In the past, I have witnessed so many bugs in KOffice, including mine of course, that surely would be earlier exposed, had we an automated test suite for that.

This taught me first hand the importance of testing (unit test is the obvious choice, but even a bunch of plain assert()s is better than nothing), until I finally adopt the "if no test exists for this module, assume it's broken" philosophy. For my personal projects, now I am very careful to make the corresponding tester for all modules/classes. That will save my days and reduce the headache later. It is funny to observe that the code which does the testing is sometimes longer than the code under test (though this fact definitely plays little role here).

Test suite is also very useful on stuff being developed by many people. Some day in the future, maybe the maintenanceship of your code is transferred to another person and when s/he wants to further develop it (implement feature, fix the bug, add workaround, you name it), the test suite will give early hints whether the new code breaks the regression or not. "But the code looks good (and I am a great hacker!)" just does not guarantee anything and completely antipodal to that broken philosophy I've mentioned.

Speaking about test, I can as well mentioned that it is a good idea to valgrindify the program from time to time. Ideally, after a feature is correctly implemented and does not break any tests, Valgrind should be used to point any possibilities of memory leaks and other similar mistakes.

Programming is 1% coding, and 99% debugging. You surely would appreciate any extra help for that 99% part, wouldn't you?

So, happy testing.

Wednesday, November 16, 2005

Browser's Blue Screen

I wonder whether novice Windows users would get panic if you give them this link: Can possibly some Ajax guru make it more scary?

"Related" HAL 9000 Technorati link: notexist :-))

Compiler Talk

When for the first time I learned C++, I used to practise guessing what goes wrong when the compiler issues errors. Basically, I jumped to the line where the error is spotted and, without reading further error message, tried to deduce the mistake just by looking at the code. I found that this is quite effective (but not efficient, do not do this for in real-world because you will waste lots of your time) to understand many advanced programming caveats. I even always recommend it to C/C++ newbie who has the guts to do so. Up to certain points, you can even start to understand the distinct behaviors of different type of compilers.

Often, time does not permit me to do this kind of exercises anymore. So instead of "talking" to the compiler directly, now from time to time I just drop Gimpel Software's bug of the month a visit. Some of them can be quite inspiring, and it is always fascinating to try to get the bug in matter of seconds. Try it yourself.

Monday, November 14, 2005

Who Let The Bugs Out?

Whoever behind it, this is cool.


Normally, amazing fighting scenes are what you expect from Jet Li's movies. That also what I had mind when I inserted Unleashed into my DVD player. But I was wrong. This European-produced movie offered a good and strong (and believable) story, and most important is that it was not packed with unnecessary fights (except perhaps one in the pool, but that's acceptable considering this is Jet Li's). The story was a bit slow and probably disappoint those who favor thriller, but all in all it is very much enjoyable. The performance of Morgan Freeman playing a fatherly figure was fairly decent as well.

Excluding his Chinese movies, in my opinion until now this is the best from Jet Li.

Sunday, November 13, 2005

Afraid or Not?

This is another joke.

At a company picnic, the CEO wanted to hold a little game. After asked for attention, he started his speech, "People, it is often said that we, the men in the family, are afraid of our spouses. Is that really true? Or is it only a myth? Well, let us now experience the moment of truth."

"For all the women, please let go your husbands for a while. Come on guys, come forward! For those who are afraid of your wives, just stand up next to me, on my left side. For those who aren't, on my right side."

It took a while until all the married men lined themselves. After some chaotic movements, in the end only one cool-looking guy stood to the right of the CEO. This stunned everybody.

The CEO approached him. "So, you are the best among us. You are the only who dare to stand here, while others had chosen another path. How come?"

"No idea", the guy gave a calm answer, "my wife told me I must stand here".

Thursday, November 10, 2005

Property in C++

Almost ten years ago a friend of mine showed that he was happy to use Visual Basic's (and also later on Delphi's, with Borland's extensions to Pascal) feature of object property, which allows one to set a property of an object and have the object respond to the change. For example, this code:

Button1.Left = 43

will automagically also move that button to a new position, not only changing Left to a new value. In C++, this is not achievable because no function call is involved. Instead, the code must be modified to something like:


And we need to have another (getter) method to obtain the property's value:

int posx = Button1.Left();

while in VB and Delphi's Pascal, one Left is enough.

Personally, I believe this is only syntax stuff. It doesn't matter so much, it even improves nothing. But just to make a rebuttal, I crafted a simple example to show that it is also possible to implement such feature in C++.

The key here is that each property is an object. To cover all basic data type, obviously template-based is a good choice:

template<class T>
class Property
 Property(){ owner = 0; };
 operator T(){ return data; }
 Property( T dat ){ data = dat; }
 void setup( Object* obj, std::string n ){ owner = obj; name = n; }
 Property& operator=( T dat ){ 
  bool changed = dat!=data; data = dat; 
  if(owner && changed) owner->propertyChanged(name);return *this; }
 T data;
 Object* owner;
 std::string name;

Later on, to wrap that setup() method, a simple macro magic is employed:

#define INIT_PROPERTY(x)  (x).setup( this, #x )

The basic object system needs to have method to be called when its properties are modified:

class Object
  virtual void propertyChanged( std::string name ) = 0;

As you can guess already, propertyChanged is invoked when a new value is assigned to the property. So the secret is here is the overloaded assignment operator.

A hypotetical widget named Slider can be implemented as follows:

class Slider: public Object
  virtual void propertyChanged( std::string name );
  Property<int> min;
  Property<int> max;
  Property<double> value;

Properties of this Slider must be initialized in the constructor. This is so that each will get a unique name and assigned to an object (simply this) to which it will report when its value is changed. With the INIT_PROPERTY macro, this is as convenient as:

  std::cout << "Creating slider" << std::endl;
  INIT_PROPERTY( value );

The job of propertyChanged is then to handle the situation when one of the property has been changed:

void Slider::propertyChanged( std::string name )
  if( name == "min" )
     std::cout << "Slider.min has been changed" << std::endl;
     // do something

  if( name == "max" )
     std::cout << "Slider.max has been changed" << std::endl;
     // do something

  if( name == "value" )
     std::cout << "Slider.value has been changed" << std::endl;
     // do something

Almost nothing else is needed. Then, the code snippet shown below is already comparable to how it is done in VB:

  Slider slider;
  slider.min = 1;
  slider.max = 42;
  slider.value = 8.3;

Althought is a "fake implementation", at least I have convinced my friend that C++ can have property.

Of course, this trick has some disadvantages. Properties needs to be initialized in the class constructor, so more boilerplate code compared to the case where this kind of feature is supported in the language itself. No checking when setting a value means corner cases must be well taken care of. Also, properties are object instances which are not so cheap. Comparing the property using string is also not fast. Infinite loop is even possible when it is not handled well.

I believe that some functors in combination with more template and macro magic will even allow the redirection of reading and writing property to the corresponding getter and setter methods. Left as an exercise for the reader :-P

Reading the Memoirs

Looking forward to seeing Zhang Ziyi's performance in Memoirs of a Geisha, I started to read the book from which the film is adapted. So the new few days will be hopefully quite exciting.

Wednesday, November 09, 2005

Qt 4.2: one tenth of...

As I write before, Qt 4.1 will be cool.

BUT, the next Qt 4.2 would be much more awesome because it is one tenth of the ultimate answer to life, the universe, and everything !

Tuesday, November 08, 2005

Reaper 3-D: Flight Combat

This Reaper 3-D, an open-source spaceship combat game seems to be underrated. It is of the same style as Terminal Velocity, but with better goodies such as improved 3-D ground objects (instead of flat, sprite-based ones like in TV). The OpenGL-based graphics is amazing, though it lacks the fast-paced background music which - in TV - pumps the adrenalin faster and faster. And granted, it has not been updated anymore since few years ago although the last release was still fun enough to play.

Image Hosted by

Give it a try!

Monday, November 07, 2005

Engineers (Again)

Following Aaron Krill, here is another engineer joke:

It was decided to build a bridge between heaven and hell. Half of the bridge should be made from hell and another half from heaven and these two shall meet in the middle. People from hell worked hard for this, as if the bridge is finished they could also once a while visit the heaven (who wouldn't?).

Up to a point where the two parts of the bridge should be connected, there wasn't any structure or whatsoever from the heaven's side. It was just empty space. Even after waiting for some time, there seems no activity at all from heaven regarding this bridge thing.

A call was made from hell to heaven, asking for explanation on what had happenned. "Well", expressed a representative from heaven, "we don't have engineers."

Friday, November 04, 2005

DOOM and KPresenter

DOOM is an FPS game. KPresenter is our lovely presentation tool. What do they have in common?

Image Hosted by

Well, long time ago I implemented lots of slide transition effects to KPresenter. Later on, just for fun I have added one effect called melting that IIRC has no equivalent in other presentation program. If you play the classic DOOM many times, you know how this effect looks like...

Thursday, November 03, 2005

Pocket Dragon

In Germany, a youngster might bump to you in and ask "Hey Alter, hast du Taschendrachen?" which is translated literally as "Hi dude, have you got pocket dragon?". Quite easily, one can guess that pocket dragon in this context means the lighter.

And there are still more phrases like this, such as Lungenbrötchen (bread for the lung, means cigarette), Fünf-Finger-Rabatt (five-finger discount or thief) and Tretferrari (Ferrari with pedal, definitely a bike).What a wonderful imagination, isnt it? IIRC there is even a special slang dictionary for that!

Wednesday, November 02, 2005


As I expected before, DOOM: The Movie was quite awesome. OK, as in the game, the story was rather weak. Often, it was quite predictable as well, e.g. that additional extra chromosome pair would apparently lead to something (although thumbs-up for mentioning Lucy).

The film is definitely more enjoyable for those who had experienced the game. The appearance of typical-scientist Dr. Carmack was a nod to John Carmack, this trivia would be hardly known if you are never exposed to iD Software. And Dr. Willits - for the famous DOOM levels designer Tim Willits - was also there (one may wonder though, where is Dr. Romero? :-P). Few minutes scene which was entirely in first-person perspective surely would be appreciated by the DOOM lovers. And of course, everybody has been waiting for that BFG show.

So, are we going to see Quake: The Movie soon?

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.