Send As SMS

Tuesday, August 30, 2005

Need the picture of a flag in your app ?

Internationalization is not only about text after all ;-)

There is a lot of web sites providing flags as bmp or gif files. Some are good and decently up-to-date. Many are bad.

The ultimate source is IMO the flags page of the CIA World Fact Book. The nice thing about it is that it's a free resource: You don't imagine the C(L)IA opening a Paypal account to let people pay for their flag pictures, do you ? :-) And yes, these images are in the public domain, hence can be used in your own app or website.

Oh! And just in case you wonder, this is the flag of my country:

Sunday, August 28, 2005

Carnival time

When I invite friends to my village's carnival, on the last week-end of June (Yes!), they think there's something wrong with me : Carnivals happen in spring, not in summer ! Well... ours is in early summer and I'll tell you what : It's great. Because it's always sunny. Way more fun than freezing in those end-of-winter carnivals.


Gilles at the Seneffe carnival

Now, I read that a few folks accross the Channel are celebrating their carnival yet another two months later ! And, as opposed to the Belgians, they realized that wearing winter suits in summertime is not a good idea... Happy Carnival, Notting Hill !


photo by Roifield Brown

Tuesday, August 23, 2005

Why is Windows UI for folder selection so lame ?

It doesn't happen often but everytime I have to code it, it always leaves me with the same bad feeling.

Today, I added a feature in a small app I'm developing for a client. The UI of this feature involves a Browse button to let Joe User tell the app in which directory some files can be found.



Is there only one person out of the hundreds of millions of Windows users who likes this dialog ? I seriously doubt. Is there only one who finds it usable ? I'm sure not.
This Browse for Folder dialog is plain unusable. Just go type a path in the edit box: You'd expect the tree selection to follow. No ! You at least expect what you just typed to be saved as your choice when you click OK. Not even !
Wait, there's more : Setting up this dialog programmatically requires that the programmer holds a PhD in Computer Science.

Besides this, we have a nice, usable, powerful and handy standard file dialog. And that's where it becomes more frustrating: That one won't allow you to let user select a directory. If you absolutely want to use it, you'll have to use dirty tricks such as forcing users to select a file in that dialog, even though you don't care about that file (hence why would user do ?). Remember old Windows drivers installation, when it prompted you for a location for the driver by forcing you to select a file that it won't choose anyway ?

So, pleaaaase, Microsoft, tell me why among the ton of flags in the good ol' open file dialog, there's not one that allows to select a directory !

Rhaaa ! End of rant. I guess I've been sitting in front of that computer for way too long... :-)

Saturday, August 20, 2005

GetNumberFormat() was 25 years late

Don't get me wrong: As a self-appointed i18n specialist, I consider locale-aware APIs (such as GetDateFormat(), GetNumberFormat() et al) blessings to make your apps world-ready by respecting your users' culture. It's not a question of politeness or education. It's just plain necessary if you want users to understand what your program display.

What d'you mean 9/23 ? There ain't no 23 months !?

Let's take dates for example: Take it the way you want but if you tell me 8/9, I'll understand Sep 8th. Don't expect me to think Aug 9th because I don't even know that somebody, somewhere, might read it Aug 9th ! And if you tell me 9/23, I'll tell you you read too much sci-fi about time machines. That's why using GetDateFormat() (or any of its higher level wrappers) is so important.

Regarding numbers, GetNumberFormat() and his sister GetCurrencyFormat() helps you make sure ten thousands is written 10.000,00 for most Europeans and 10,000.00 for Americans (and whatever format is used for each other culture).

Computers were babies, and babies don't study languages

Yes, we Europeans use a comma as a fractional separator. That's what we learn in elementary school. That's how we write numbers. We don't even think of doing it another way !

Errrr... Really ? Well, there is a catch : When the first "pocket" calculators appeared in the late 60's or early 70's, and when the grocer around the corner started to use a machine to print price tags, instead of writing them down, we started to set our minds: Printed numbers use a dot to indicate the fractions (we're not used to commas as thousands separator though) because the calculator was manufactered by an American company and so was the labelling machine used by the grocer... And these machines didn't have GetNumberFormat(), unfortunately !

The interesting point is that we learned that printed numbers use a dot. But we didn't change the way we write. And we inconsciously make a difference between handwritten numbers and printed numbers ! Since machines didn't speak our language, we learned theirs. But it doesn't mean we forgot ours.

By the time the kid grew up and studied languages, it was too late

Then came GetNumberFormat() and Excel starts using commas for fractions. WTF ! Nobody prints numbers that way ! It's just plain ununderstable. Pleaaase, get me rid of this comma and replace it by a good old decimal point... Thank you.

OK. Everybody happy again. But still, officially, Belgians use decimal commas. So when our IRS published its web-based tax declaration system 2 or 3 years ago, they followed the official rules and uses. I remember I filled the whole lot of fields in the huge form and clicked Next.

Please fill in with numbers. Beg your pardon ?? It took me 10 minutes and several tries to realize the problem was with my decimal points. The form wanted decimal commas ! Plain unusable !It didn't last: The next year, one could use decimal points...

The problem is that programs display so many numbers : We, the devs, just can't use GetNumberFormat() each time. And since people are used to it (people don't even think of printed numbers looking like written numbers !). If at least the CRT and other major libraries used it (After all, these libraries do use GetDateFormat()...), we would get correct display of numbers for free and the format would become ubiquitous. But for some reason, the CRT doesn't use locale-awre APIs to format numbers (I guess there are reasons. I'll ask my good friend Michael).

The net effect is that using GetNumberFormat() can become counter-effective, according to the context. And it's pretty hard to know if the context is good or bad :-(

"And Excel ?", you ask

Well, It looks like the Office team didn't want to break the whole work done by their colleagues at the i18n team : If I type the dot in the digits pad, Excel writes a comma (!) and considers it a decimal separator. Pretty weird at first, but you know what: We now get used to reading printed numbers with commas... as long as it's in Excel !

Monday, August 15, 2005

Traditional vs Modern Spanish

A couple of days ago, an appTranslator user reported a confusing behaviour of appTranslator when importing a Spanish translation into his project. "Does Spanish mean Traditional or International Spanish ?", he asked.

Do you speak Traditional or Modern Spanish ?

Hey, all alive languages evolve. Evolution is an intrinsic property of life after all. It reminds me this Petit Robert (famous french dictionary) radio commercial a couple of years ago : "Does your dictionary know that bugs are no longer only bugs and mice are no longer only mice ?"

But I didn't know that Spanish (I mean Castillian) had evolved so much to create the need for two different Language Identifiers : Traditional Spanish and Modern Spanish.
Well, these are not different languages. The only difference is their respective sorting rules (explained here by DrIntl).

Huh! Why use different LANGIDs to denote alternate sorts ?

Good question. There is a field in LCIDs that is devoted to specifying preferred sorting rules. So there doesn't seem to be any reason to use different LANGIDs. Raymond Chen would probably answer : "Because we have yet to invent time machines". It seems that LANGIDs were created before LCIDs and the problem (i.e. to maintain different sorts for one language) showed up with Spanish for the first time. Later on, the MS engineers created the SortId field in LCIDs to avoid future occurences of this problem (Source : MichKa).

OK. But why do I get Traditional Spanish when the 'Show countries' box is cleared ?

When it prompts you for a language, appTranslator offers to simplify the list by clearing this 'Show countries' checkbox. This way you don't get 16 Arabic variations, 20 Spanish variations,... You get only one occurence of each language. Fine. But as far as Spanish is concerned, which one do you get ? Traditional or International ?

To answer this, I need to clarify yet another naming issue : There are four namings use for Spanish spoken in Spain: Spanish (Castillian), Spanish (Traditional), Spanish (Modern) and Spanish (International). The formers are synonyms (Castillian and Traditional). So are the latters (Modern and International).
BTW, Catalan and Basque are not Spanish ! They have their own primary language identifier.

To come back to our question about appTranslator: Well, you get Spanish Castillian, aka Spanish Traditional. (I'll change the name to Traditional in the next release BTW). OK, but DrIntl just said that Spanish Modern/International is preferred to Traditional/Castillian. And you can check it in practice : In the Regional and Languages Options Control Panel applet, select Spanish (Spain) and click 'Customize...'. In the last page (Sorting), see that International is selected by default.

Yes, but appTranslator assumes the default langid for a language is MAKELANGID(PrimaryLangId, SUBLANG_DEFAULT), which in the case of Spanish yields Spanish Traditional.

Again, I can change this in future versions (for future users. I can't modify LANGIDs in existing projects data). I still have to check that there aren't major compatibility issues.

Anyway, if you want to have Spanish International in your appTranslator projects, just tick the Show countries box and choose... Spanish (Modern).

Why is my Spanish version info only partially imported ?

When you import your existing Spanish version into the project and choose Spanish (Modern), you might run into this problem: The strings in the version info resources are not imported.

This issue is worth an entire post. Most of that post will probably be a rant about version info resources. Don't get me wrong, version info resources are a must-have. But the way they were implemented is just overkill and leads to outrageously complicated code, concerns and complicated design decisions. I'll even show you that Visual Studio's resource compiler has a bug that can lead to corrupted version info resources. Amazing for such an apparently simple resource, isn't it !

For now, just remember that I'll change the behaviour of appTranslator to address this (somewhat minor) issue.

Quiz

Who said a mess ? Well, not me ! But to those who read up to here (Congrats !), do you remember why we have all these problems ?

A: Because Spaniards changed their mind over time and most of them no longer want their phone book to sort ch between c and d (and ll between l and m)...

Sunday, August 07, 2005

Do it well or don't do it at all

Earlier today, Ian Landsman shared his views about leaving features out of your product. He explains why he decided not to implement Web services support in v1.0 of his HelpSpot.

I agree with him on every point. But the point about limited integration of the feature into the product is IMO particularly important.
I am always careful about the good integration of features into appTranslator (or any other projects I've worked on) : Consistency and completeness are must-have or I'll drop the feature.

Consistency

Take Undo for instance. When I designed appTranslator, I figured users should be able to undo a translation they just typed. It happens that you select an item in a list, translate it, type then realize you did not select the right item in the first place. In such a case, Alt+Backspace (or Ctrl+Z) is welcome !
But if you can undo a translation in the string table, you expect to be able to undo in dialogs as well. And in the version info. And in the icons. And you expect to be able to undo the resizing of a dialog control. And the deletion of an executable module from the project,...

Completeness

What if you realize a little late that you're not translating the right items, say after you translated three of them ? You need to be able to undo the whole 3 of them. And you also need to redo if you incorrectly undid the last 4 translations.
And if you are in Items to be translated mode and you hit F5 (refresh) while typing translations ? These new translations are not displayed anymore. So when you undo, the item must appear again.
And if you switched to another resource, appTranslator must select the right resource again and select the item whose translation was undone !

Do it well or don't do it at all

As you can see, a small task as undoing the translation of a string quickly turns into... over a week of hard work ! There's very often a lot of sweat behind what seems an innocent little feature.

But it is necessary: Software must be comfortable. Users must feel they are in control. As much as possible, your program must behave as users expect. It must also help users do right things, which are not always the ones they want to do.

Consistency and completeness of features are must have to reach these goals. If that undo doesn't work as expected, users will get frustrated and they will quickly throw your program to the Recycle Bin, which in other words means : You LOOOSE !

You know what : You'd better not have implemented that lame undo in the first place because user simply would think : 'Oh! No undo ?'. Which is much less bad than 'I said Undo. Undo ! UNDO ! Why don't you just UNDO, you stupid program. Why can't you undo my typing HERE since you can undo it THERE !!!'

Clients requests are hard to manage

I used the Undo function to explain my thoughts because I wanted everyone to get my point, not only appTranslator users. But this 'do it well or don't do it' problem often comes as an e-mail from a client asking if I could add a little function that is so easy to do and would do a great job to help him workaround the lack of big feature X.

Of course, when it happens, you're tempted to say yes. After all, it would help many other people as well. But it would be only a part of the solution. It would work in many cases but certainly not all of them. And, more important : It wouldn't be clear to users where the limit is (I mean in which cases it works and in which cases it doesn't work). Which would mean to user frustation again.

My policy is to say no to such requests, or if applicable to say 'please wait until appTranslator has big feature X'. But I admit it's not always easy. And I sometimes wonder if it's the right choice.

A couple of days ago, I worked several hours to fix a bug that very few people would encounter (one so far) and for which I have a workaround. I fixed it because of consistency: 'appTranslator supports ActiveX controls in dialogs (an MFC feature)' does not have to read 'appTranslator supports ActiveX controls in dialogs (an MFC feature) EXCEPT if the control is first in tab order'

But of course, while I was fixing this bug (more difficult than it looks :-( ), no important feature was coded...