Zwei Affichen

This is only for my fellow readers from the german part of switzerland. I’m presenting it without further comments as those knowing about the two newspapers and capable of understanding german will certainly get my point.

I took the pictures with my cellphone, so the quality is kind of bad which is why I do not provide an enlarged version

Tagesanzeiger NZZ

Productive with Delphi 2005

Yesterday and today, I finally had the opportunity to do some real work on PopScan with Delphi 2005. Here’s what I really like besides the obvious:

  • Those .bdsproj-Files are incredibly useful. They replace the old DSK and DOF-Files, have a convenient XML-format and are the new project file, you open with in Delphi. This is very nice as the old project file (.dpr) is actually program code and does not contain any project metadata. This is what those .dof and .dsk-Files where used for, but I never understood which setting is in which and the format has not been XML either. So this consolidation really is convinient.
  • The history-feature really saved my day. With me hitting Ctrl-S on nearly every line I write, the older .~pas-approach wasn’t very useful and CVS was no help either because I don’t commit as often as something could go wrong in the code.
  • The new exception catching-dialog of the debugger is really nice. I like this “Dont halt on this exception again”-Checkbox.
  • While it makes the application significantly slower under the debugger, the new “event log” is great.
  • Speaking of debugging: The “Local Variables”-Window is great too.
  • Delphi now distinguishes between a “Default Layout” and a “Debug Layout”. You can configure both of them as you like and Delphi automatically switches between them. This is much more intuitive than before.
  • Maybe I’m the only person on earth, but I like the single-window-approch: It’s much cleaner than before. No more tons of clutter on the screen and the important screens are always wisible. No more Ctrl-Alt-F11 either.

Additionally, I don’t have as much speed problems as others seem to have: While starting the IDE takes it’s time, working with Delphi when it’s open goes quite smoothly.

My only problem is opening the form designer. This definitely takes too long, but not long enough for me to switch back to the undocked layout.

Memory usage is of no concern to me. I have 1 GB of RAM and even after a day of using delphi, my Thinkpad remains responsive even though not only delphi, but also eclipse, Zend Studio, Firefox and many other programs are running. For me the figure the task manager tells me is not nearly as important as the responsiveness. If delphi uses 500 MB of RAM, fine – as long as my PC stays responsive.

All in all, I really like this new Delphi and I already have uninstalled D7 (thus breaking FeedDaemon).

Tales of Symphonia

Now that the project I’m currently working on for which I didn’t really have much time to complete it and which I insisted in doing cleanly despite the time constraints (beleive me: It’s worth it. Read about that later) is coming along very nicely, I actually had some time to do a little gameing yesterday.

About two weeks ago, I bought Tales of Symphonia for my gamecube, but only yesterday, I played it for the first time (while still waiting for Mario 64 to arrive for my DS I’ve imported and actually got last week). Read about my more-than-plesant experience:

First of all, I actually could buy a legal european version. Relying on grey import was – for once – not necessary despite Tales of Symponia (just “tales” from now on) being quite a hardcode RPG. A really big THANK YOU! for that, Nintendo.

Additionally, while I would have preferred playing it in english, the german translation is really good (completly unlike the miserable translation of Pokémon, for example) and thankfully, the voice actors where not synchronized and the english actors did a very good job on this one.

One thing is stupid though: You cannot turn off the german subtitles and they do not vanish automatically. So it’s necessary for me to hit the A-button in just the right time not to create unnatural sounding cutoff sentences. This was a problem in the first 15 minutes. After that I got quite used to it, maybe also because the german translation really is good (I’d translate most of the sentences like they did).

The next thing I did not like at first was the story: First, you have this “Wake the goddess to save the world by unsealing four seals” which sound kind of silly for a hardcore RPG. And then there are the two other main themes: “Girl on a pilgrimage to save the world” and “Boy brings destruction to his own village because of an accident and gets banished for that. His first station on the journey is a desert”.

Both of those themes should sound familiar to you, the first one being a FFX-ripoff, the second one being from the best RPG of all-time, Xenogears.

Fortunately, this feeling of “seen-that” quickly begins to wear off after about two hours where the party crosses the sea and lifes (hopefully) through the Governour Dorr-sidequest. Now, that’s something new (and great too).

As I’m just about ending said quest, I don’t know anything further to say about the story, but I’ve read great things about it.

I really like the battle-system. It’s a bit like “Star Ocean”, fast-paced and doable none-the-less. In the desert just at the beginning after being abducted by those maybe-desians (the enemy race opressing the humans, strangely equipped with technology well beyond that of the humans), I was hopelessly under-leveled: Those visible enemies on the world map invite you to skip instead of fight them. In the end, I got around, but it was not easy there.

On a side-note: Speaking of advanced technology: Why the heck does Raine seem to know all that stuff? What is it about her? If she has something to hide it’s much better done than Citan in Xenogears where this is clear from the beginning. Besides: I really like her character. She is very likeable.

Another thing I really, really like is the graphics: I love this cell-shading technology – especially if it’s done as well as in tales. It’s like watching an animee – just interactive.

On and talking about “interactive”: In contrast to what I had to rant about in Xenosaga, in tales, the balance between interactive and non-interactive sequences is done very well. It’s never boring and the story is always developping. Very nice.

All in all, tales certainly is the best I’ve seen RPG-wise on the gamecube and it even matches some of the better-known Squaresoft titles. I really hope, the story continues as it is now and does not fall back to re-telling things already told by other games.

If you have a cube and are longing to good RPGs on it, go and buy tales. You will not regret it.

So, now I’m just going to recompile and upload my little Java-Applet and then I’m off home to play another round of tales…

ALTER TABLE in PostgreSQL 8.0

I’ve just discovered my new favourite feature of the upcoming PostgreSQL 8.0: Let’s say, you have forgotten a column when creating the schema of a table. Let’s also say there already exist foreign kays referencing this table, so dropping and recreating it with the updated schema from your text-editor won’t work (or force you to recreate all other tables too).

So, you need alter table

Here’s what Postgres < 8 needs to add a column cdate which must be not null and have a default-value of current_timestamp:

alter table extart_prods add cdate timestamp;
update extart_prods set cdate = current_timestamp;
alter table extart_prods alter column cdate set not null;
alter table extart_prods alter column cdate set default current_timestamp;

And here’s what it takes to do it in PostgreSQL 8:

alter table extart_prods add cdate timestamp not null
    default current_timestamp;

When typing this into psql, you’re so much faster. This is actually the only feature I really missed when going from MySQL to PostgreSQL for all bigger work

Oh and did I mention that in Postgres 8 (currently running Beta 4) the statement is executed noticably faster than in Postgres 7.4 (though this doesn’t really matter – you should not be altering production tables anyway)

Internet Explorer, File Downloads, PHP

Have you ever tried sending a file to Internet Explorer, for which an internal displaying plugin is installed? Take a .CSV-File for example (or a PDF for that matter).

If so, then maybe you have noticed that IE in some versions just displays an error-message about not being able to find the file just downloaded whenever you have a call to session_start() in your script.

The problem is with the Headers PHPs session management sends to the browser: It disallows any cahing and tells that the document expired somewhere around my year of birth (1981). It seems like IE takes that literaly and really does not cache the doument, but then naturally is unable to forward it to the plugin (or activex-control or whatever).

Fortunately, you may change PHPs default headers by just emitting some additional header()-calls:

    header('Content-Type:  application/csv');
    header('Pragma: cache');
    header('Cache-Control: public, must-revalidate, max-age=0');
    header('Connection: close');
    header('Expires: '.date('r', time()+60*60));
    header('Last-Modified: '.date('r', time()));

A short explanation of the headers sent:

  1. The content-type tells the browser that there’s a CSV file coming
  2. Pragma is an old HTTP/1.0-Header. This one allows caching of the resource
  3. Cache-Control is the new HTTP/1.1 header to replace Pragma. “public” means: Public proxies may cache the document (private would also work and would mean: Cache in the Browsers cache). must-revalidate advises proxy servers (and browsers) to check if the resource is modified whenever the document is older than max_age seconds.
  4. The connection-header tells the server and browser what to do with the connection when the resource has been transmitted. The old HTTP/1.0 behaviour is close. keep-alive would be the newer behaviour. I’m not sure whether this really is necessary here, but with this header, it definitely works.
  5. The Expires-Header tells the browser when the document is going to expire. PHP default this to somewhere in 1981 and I think this is what causes the problem for IE. I set it to one hour in the future. If it were possible to just turn off those default-headers, I would simply send no Expires-header at all.
  6. Last-Modified tells the browser when the resource was last modified. I could actually get a timestamp of the underlying data representation and output that so the browser would not have to redownload the resource when the data has not changed, but it’s changing that often that this optimization is not worth the trouble, so I’m telling it just changed.

I have confirmation that this solves the problems some clients where expecting before. Very nice.

Any Eclipse users out there?

Usually I’m not here to ask questions, but today I have two for my readers. Maybe someone can help?

It’s about Eclipse:

  • Is there a way to automatically switch back to the Java-perspective after a debugging-session ended?
  • Can the complete JDK-Documentation somehow be integrated into the help system? While I know there is Javadoc everywhere while writing code, using the full-text search capabilities of the help-system would be really nice here and then…

I’m quite sure, both problems can be solved. I’m just not seeing where. And additionally I’ve quite some problems devising useful google keywords to find a solution.

So, I thought: Maybe some of my readers know Eclipse better than I do.

Any help is appreciated..

Found on my iMac

Today, I found a residual registration link lingering around in my home-directory of my iMac. Looking at it’s contents with cat reveals quite an ordinary .plist-XML-file.

What’s interesting is what the engineers at Apple obviously thought of the newsletters the user is given a chance to subscribe to:

        <key>RegistrationInfo</key>
        <dict>
                <key>AppleSpam</key>
                <string>NO</string>
                <key>Location</key>
                <string>B</string>
                <key>Occupation</key>
                <string>5</string>
                <key>OthersSpam</key>
                <string>NO</string>
        </dict>

(the emphasis is mine)

Oh… how I agree with them!

Delphi 2005

I got my hands on the demo-version of Delphi 2005 (download it here), and I actually have configured the beast already, so I have my usual environement to work on PopScan with it. These are my first impressions (I won’t talk about this File-Download-Window-Popping-Up Problem as all know it’s a nasty problem with a security-patch from Microsoft which will soon be fixed. Read about it here on Steves blog

  • It takes quite some time to start up. After removing the Delphi.NET and c# personalities (don’t need them), it starts about as fast, als my Delphi 7 did. Just a little bit slower
  • The compiler got faster, if you ask me.
  • Besides the great new features Borland is talking about, there are very nice usability-tunings everywhere which make working quite a bit easier.
  • The VCL form designer is extremely slow on my machine. Just displaying the PopScan Main Form within the designer takes nearly 10 Seconds. Delphi 7 does that instantly.
  • The debugger is slower too, which certainly has to do with the many great feature additions. I can live with that.
  • It’s extremely compatible to Delphi 7: I could install every single third party component without any problems. This is quite impressive considering Delphi 2005 is quite a rewrite.
  • While I like the new docked form designer, there’s one usability-problem with it: When you have components that use their own property editors (like Toolbar 2000), those editors are opened in their own window (understandable). Now, if you select a button in the component editor and then click the Project inspector to change a property, the Delphi Main Window will cover the property editor rendring it invisible. An easy fix would be to define the property editor always-on-top – a better fix would be integrating it somewhere in the IDE
  • Even JCLDebug could be compiled and installed (even the IDE Expert did work, though you have to manually install it)

All in all, this release of Delphi is a very great release providing the user with a ton of new features and fixes to long-standing usability problems (so long that you got used to them and now are missing them…). I have not expirienced any crashes so far (besides the one where the expat-parser of a debugged application took all the ram on my system, but I don’t blame Delphi for that), which is very nice.

Now, if only the beast could be made to run a bit faster (which will be done, I’d say, it’s the best Delphi since Delphi 2 which means quite a lot…

Thanks Borland.

PS: I know that it’s currently more in fashion to bash Borland and to whine about everything they do. And for the fourth consecutive year now I read posting about Delphi’s impending doom everywhere on the net. But consider this: Delphi still is the only RAD tool out there producing 100% native windows executables. And it still has one of the most lively communities I know of in the Windows-world. Even if Borland would kill off delphi, I’m quite certain, it will not go so easily. Not with this community.

On and speaking of killing off delphi: Seeing this great release of Delphi 2005, I am quite assured that Borland will continue supporting us.

So: Quit whining around!

XMLHTTP

Imagine, you are working on a webshop.

Imagine further, that you have a page displaying the users shoppingcart. Left of each entry, there’s an <input type="text"> for letting the use change the quantity of the article. Till now quite a common scenario, isn’t it?

Now in the time of DHTML and all that, you write some JavaScript to automatically recalculate the grand total of your shoppingcart on-the-fly, as the user is changing the quantities. This is very nice, as the user gets immediate response to her actions. No reloading the page is involved.

Now imagine further that the user has changed quite some quantities. The new cart is nothing like the old one was. The user is very happy with the total recalulating itself on every key she presses while the focus is in one of those editfieds. Very nice.

Now the user realizes that she needs another product. She clicks on the “Browse”-Link and …

What happens?

Well,… the link certainly works and she browses around in the shop looking for another product to order. But there’s a serious problem lurking around: As all the calculations were done on the client when the user changed the quantities, the server knows nothing about the changes. The server still thinks (provided something like a HTTP-Session-Emulation being at work – but how would you implement a shopping-cart without it?) the quantities are unchanged. When the user looks at the cart the next time (even after reloading the cart-page), she will see all the old values.

How to fix this? (Jonas, if you read this entry: This is about the solution to a problem we faced about a year ago while working on PopScan SMB). Most common today is one of the following:

  • Post the form on every change of the quantity. While this fixes the problem, it’s not very convinient for the user – especially if she uses a slow modem link. And even if the link is fast: Reloading the page whenever I’m tabbing out of an edit-field is very disturbing (though I’ve seen sites where the page even reloads on every key press).
  • Don’t recalculate anything, but provide an “Update values”-Button. This is what most users are used to as this is how the web worked so far: You enter something, you submit it to the server or you lose it.

Now this is where XMLHTTP comes to play.

While it has XML in it’s name, it has very less to do with XML. It’s a technology to send HTTP-Requests from JavaScript. And not only that: The requests are sent completely transparent to the end-user in the background. She doesn’t notice the slightest thing while the script is posting requests. As the API is asynchronous, there even is no waiting involved – not even over slow lines.

So.. how does it work?

I used this function to post back quantity-changes from my shoppingcart:

function updateToServer(quant,art){
    var xmlhttp=false;
    /*@cc_on @*/
    /*@if (@_jscript_version >= 5)
    // JScript gives us Conditional compilation, we can cope
    // with old IE versions and security blocked creation of
    // the objects.
     try {
      xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
     } catch (e) {
      try {
       xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (E) {
       xmlhttp = false;
      }
     }
    @end @*/
    if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
      xmlhttp = new XMLHttpRequest();
    }

    xmlhttp.open("GET", "/index.php/order/qchg?a="+encodeURI(art)+
           "&q="+encodeURI(quant),true);

    /* not interested in feedback. if it doesn't work, too bad. other
       methods provide fallback
    xmlhttp.onreadystatechange=function() {
      if (xmlhttp.readyState==4) {
        alert(xmlhttp.responseText)
      }

    }*/
 xmlhttp.send(null)
}

(disclaimer: much of the code comes from this page. If you know, what you are doing, copy&paste really is a timesaver.)

What does it do?

  1. It uses some IE-trickery with conditional code to instantiate the object.
  2. If the IE-code does not get run (on every standards-compliant browser), it uses the common way to instantiate the thing
  3. It prepares the request
  4. It sets up some event-handlers. As I’m not interested in the outcome, I’m not setting up anything.

As you can see, I created a special url for accessing my shop-system, just for updating the quantities.

This function is called from the onChange-event of the quantity-change-input-boxes. Now, whenever the user changes a quantity, /index.php/order/qchg is called, advising the server to update the quantity (if you find the URL strange – using PATH_INFO and all that: I will post something about a PHP-design-pattern that I’m using that has proven to be the most powerful in all those years I’ve been working with PHP).

Problem solved.

And just 30 minutes after implementing this method, I found out that for the purpose I’m using it, this whole XMLHTTP-thing would not be necessary:

While some trickery with FRAMEs could do the same thing, the really best method that even works with Netscape 4.x (even 3.x, if I remember correctly) would be to conditionally change the URL of a (transparent 1px2) image. This works always if no feedback from the script must be evaluated:

Pseudocode:

function updateToServer(quant, art){
 document.images['qposter'].src="/index.php/order/qchg?a="+encodeURI(art)+
             "&q="+encodeURI(quant);
}

A one-liner, no frame-trickery (frames are bad – even for such things), no finding out what object to instantiate, no problems with near-browsers,… very nice, but nowhere near structural markup, which is why I prefer the less hacky solution.

I hope, this was helpful for you. And as I’m progressing with this very interesting project I’m working on, I certianly will have more of such things to post.