Older blog entries for JoeNotCharles (starting at number 27)

How’s Gimp doing these days?


I’ve always heard two opinions about Gimp: “It’s just like Photoshop, an incredibly complex and expensive piece of professional software, but it’s free! Behold the power of Open Source!” and “Gimp sucks. It’s better than nothing, I guess, but if you’re using Gimp instead of Photoshop you’re a chump.”

Of course, not having any need for a pro-quality image editor due to lack of artistic talent, it’s been 5 years since I paid any attention to this. My sister gives an update on how Gimp stacks up today.

Syndicated 2009-07-22 02:50:37 from I Am Not Charles

O(log n) continues to beat O(n^2)


Two items:

1. I feel pretty bad about the several months of silence. I swore this time I wouldn’t start a nice professional journal and then let it languish. Oops.

2. I also didn’t want to post links with no original content but, well, this is a pretty cool result and I have nothing more to add to it. So here you go.

(Brief summary: my coworkers found a way to significantly speed up image tiling in Qt, using a simple algorithm that’s easily applicable to other toolkits and environments. Briefer summary: It makes painting faster, which is always good.)

Syndicated 2009-03-03 05:30:47 from I Am Not Charles

Fresh data


So what runs better - OpenOffice or KOffice? Anecdotal evidence says KOffice is slimmer but OpenOffice works better, but it’s very hard to find actual hard numbers on memory and resource usage. And when you do find somebody who’s done a comparison, it invariably dates back to 1995 and it’s totally obsolete.

How about Evolution vs. KMail? Evolution’s much more popular, but there are a few blog posts that offhandedly mention it’s a huge hog compared to Kontact. Which is odd, because there are actual filed bug reports that claim Kontact leaks memory like a sieve. How can I find the truth without installing both and painstakingly testing them in a wide variety of common use cases?

Well, we know that Evolution’s more popular because of the Debian Popularity Contest, where Evolution has a commanding lead. (The “Vote” column is the useful one.) popularity-contest is a Debian (and Ubuntu) package which automatically collects stats on what software is installed and how often it’s used, and I urge everyone to install and enable it now so that it can give a more accurate picture of what’s popular and where developer resources are best spent.

It would be great to have a similar program that automatically collects resource usage statistics for all running programs. Suddenly we’ll have actual hard, fresh data to settle arguments about whether your favourite app is a bloated hog or no worse than everything else! This info would be invaluable for both developers and packagers.

      

Syndicated 2008-09-26 23:28:42 from I Am Not Charles

Your clipboard isn’t broken, just confused


This is kind of trivial, but it’s good to have it documented somewhere.

If you ever have to work with the Windows clipboard API directly (and it’s not too bad, as Windows API’s go) this might save you a lot of time: don’t try and step through any clipboard-related code in the debugger.

I was trying to figure out why pasting an image into my app didn’t work, so obviously the first thing to check is that the data is actually being retrieved from the clipboard correctly. I suspected it wasn’t being saved in the format I thought it was.

BOOL clipboardOpen = ::OpenClipboard(NULL);
if (clipboardOpen) {
    qDebug() << "Clipboard open";
} else {
    qDebug() << "Couldn't open clipboard: error" << ::GetLastError();
    return;
}

UINT format = 0;
while ((format = ::EnumClipboardFormats(format) != 0) {
    qDebug() << "Clipboard contains format" << format;
}

qDebug() << "Last EnumClipboardFormat status was" << ::GetLastError();
::CloseClipboard();

MSDN is pretty clear on how these two functions work: OpenClipboard returns true if the clipboard’s open, and EnumClipboardFormats returns 0 when there’s an error (in which case GetLastError returns the error code) or if it’s out of formats (in which case GetLastError returns 0, SUCCESS).

Since I was too lazy to actually hook up the Qt debug logger I was just stepping through this in the Visual Studio debugger to examine the results. And the results were basically:

Clipboard open
Last EnumClipboardFormat status was 1418

Since my app is emphatically not multithreaded, I was pretty baffled about how “Clipboard open” could be immediately followed by 1418: ERROR_CLIPBOARD_NOT_OPEN. I thought my paste problem was because my clipboard was seriously broken (on any OS but Windows I’d have thought something that fundamental was impossible, but on Windows I never assume anything). Took me ages to realize that it worked fine if it wasn’t in the debugger.

The problem, I think, is that when you pass NULL to OpenClipboard it associates the clipboard with the current process, and when you’re stepping through in the debugger it’s switching back and forth between the application and Visual Studio. Somehow the system is getting confused about which process has the clipboard open. This example seemed to work if you pass an HWND to associate it with a specific window instead of a process, but I wouldn’t want to place any bets that more complicated code would keep working. On Windows I never assume anything.

Syndicated 2008-07-04 05:27:15 from I Am Not Charles

Joel gives bad advice: details at 11:00


Am I blind, or does Joel on Software not allow comments any more? (Or did it ever?) Well, I guess I’ll respond to his latest article on disabling unusable menu items right here, even though that means he’ll never see it.

Don’t do this… Instead, leave the menu item enabled. If there’s some reason you can’t complete the action, the menu item can display a message telling the user why.

That would be incredibly annoying - I’d be constantly clicking on items I expect to work and getting a popup saying, “Sorry.” In an app I use often, I use the menus mostly by feel, so I’m not going to notice that now there’s a message saying, “Disabled because the moon is in th’e fourth quarter and you haven’t paid your phone bill.” Or if I do it’ll be in the instant before my finger clicks the button, so now I’ll just have time to realize I screwed up before it pops up the Box of Aggravation.

A better thing to do would be to disable the option, so if I click on it nothing will happen instead of the app yelling at me, and have feedback on why it’s disabled.

Syndicated 2008-07-02 03:09:40 from I Am Not Charles

I’m a greasy little monkey


Wow, work’s really been kicking my ass lately. I’ve been meaning to update this blog for ages, but I’ve had no time. Finally got the day off and spent an hour or so learning to use Javascript and Greasemonkey. While we’re waiting for something more substantial, here’s my first script. You might even find it useful:

// ==UserScript==
// @name           Include Linked Images
// @namespace      ca.notcharles.greasemonkey
// @description    Add linked images to the end of a webpage.
// @include        http://www.wizards.com/*&pf=true
// ==/UserScript==

/*
Copyright (c) 2008 Joe Mason 

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

var body = document.getElementsByTagName('body')[0];
var anchors = document.getElementsByTagName(’a');

for (var i = 0; i < anchors.length; i++)
{
	var anchor = anchors[i];

	// only process anchors containing images
	if (anchor.getElementsByTagName(’img’).length == 0) continue;

	// add the target of the image to the end of the document
	var href = anchor.getAttribute(’href’);
	var hr = document.createElement(’hr’);
	body.appendChild(hr);
	var img = document.createElement(’img’);
	img.setAttribute(’src’, href);
	body.appendChild(img);
}

I won’t bother going through it because there are a million Javascript tutorials out there.

So what’s it useful for? Well, Wizards of the Coast have been releasing Dragon and Dungeon magazine articles online - free, for the time being. Sooner or later they’ll start charging for them so I’ve been downloading as many as I can and saving them as PDF’s. (The best way to do this is to click on the “Printer Friendly” link at the bottom of an article, and then print to PDF. On Windows you’ll have to install an add-on for this - I like PDFCreator.)

The problem is that some of them have thumbnailed images which link to a full-sized version, and I’d really like the full images to end up in the PDF. So this script just finds every image which is a link, and appends that image to the end of the page. It only runs on the printable format page (the “pf=true” at the end of the @include line). It just occurred to me it should really be checking that the link actually leads to an image, but meh - that’s not very likely for these articles, and if it happens I’ll deal with it then.

This article is a nice simple example to try it on.

Syndicated 2008-07-02 02:37:32 from I Am Not Charles

Blog of the trivial


This is the second time in the past two weeks I sat down to post about an ingenious workaround I found, only to find out it wasn’t necessary. I like to post a code sample saying, “This should work, but it turns out to be more complicated than that,” and then build up the less obvious solution. But both of my simple test cases worked just fine, leaving me without an entry. “Hey, this really obvious thing should work - and it does! Good night!”

This is leaving this blog a little thin.

Syndicated 2008-06-09 01:37:14 from I Am Not Charles

Wild Zebras


Christian at Design Desires posted some simple Javascript to make dynamic zebra-striped tables. He asked for comments to be mailed to him - in keeping with last month’s rant about open discussion, I’m posting my response here instead:

No sir, I don’t like it.

I don’t find it adds anything. I’m perfectly able to read across the lines of a plain old static table, so highlight one line doesn’t make it any faster to read that line. It also doesn’t help me pick out a line when scanning with the mouse, because I’m already looking at the line that gets highlighted - I put the mouse there myself!

I don’t know if it’s just my browser, but highlighting the line causes a lot of flicker. (The “more extreme” example from Neil Roberts is even worse - it actually resizes things while I’m mousing over them, jerkily. That’s terrible!) So I’d really hesitate to use this until it’s been tested on a lot of browsers and setups to make sure it’s smooth everywhere.

The only advantage I could see is if I look away and come back later. There might be some value in highlighting the line after the mouse has stopped there for a few seconds, which wouldn’t cause flicker when scanning quickly. It still might be more annoying than useful, though.

Syndicated 2008-05-10 15:31:49 from I Am Not Charles

Advogato vs. the world


Now that I’m not using Advogato any more, I’ve taken a little time to think about what made me dislike it. Mostly it’s that the user interface is bland, but there’s also a bit of clunkiness that really annoyed me:

90% of the world’s blogs are laid out in the same way: if you have something to say about a post, you make a comment on it. If you have something to say that you think deserves a post of its own, you post in your own blog and make a trackback to the post you’re referencing.

Advogato works a bit differently: you can post, and that’s it. There are no comments and no trackbacks. On the surface, that’s because it’s more primitive, but the community’s had plenty of time to add these features. Either they just don’t care or they think their system’s actually better.

(Wait, that’s a misuse of worse-is-better - I should have linked to less is more.)

The advantage of the Advogato system is that people do comment on each others’ posts, but they do it in their own journals. You just start out with a link to the post you’re commenting on, in this format:

shlomif: did you actually read the Nichomachean Ethics? The thing is repulsive…

On most blogs, when referencing a post somewhere else the standard is to quote copiously - quote the parts you are replying to directly, quote the parts you find especially interesting, quote the parts that give the argument’s main points. Since you found the subject interesting enough to go to all this effort, you want to give your readers a good overview. But this gives the reader very little incentive to actually go back and read the original post you’re quoting, since they already have the hilights. The Advogato style gives no context, but readers can always click the link to find it. That means that, on Advogato, people who are hooked in by a post are actually more likely to go back and read the entire context, because there’s no other way to get it.

The other advantage of Advogato’s style is that I can find interesting discussions no matter who starts them as long as someone I know takes part. When a discussion starts on one blog and unfolds entirely in the comments there, it can’t draw in anyone who isn’t already a reader. I only find new blogs when they’re widely linked to, which only happens when lots of different people have a lot to say on a subject, or when they feel that a post is so insightful that it needs to be shared. I miss out on the smaller, more specialized posts which may attract comments and observations by not wide dissemination.

On the other hand, the Advogato style discourages casual commenting, since it’s so much work to make a link - nobody comments unless they have something substantial enough to make a full post. Discussions tend to peter out after a few exchanges. And unless you already have a strong relationship with the person you’re replying to, how do you know they’ll even read your reply? There’s a list of recent posts throughout the entire site on the front page, but this doesn’t scale well at all.

So, no, the Advogato system doesn’t really work as-is. It’s pretty good for building a sense of community, but the poor scalability and lack of features in the interface it makes it unattractive for serious blogging, so many writers migrate elsewhere. (Take a look at the Advogato recent blog entries list and see how many are syndicated from other sites.) In fact, the community feeling is exactly the reason I switched to Wordpress - I wanted more control over the layout, the name, and the style. I wanted a blog that I felt like I owned. But here I am complaining about how blogs are fragmented when everybody owns their own instead of participating in a communal site.

So what’s the solution? Act like a writer, not a reader. Unless what you want to say is really inconsequential, do it Advogato-style, in your own blog, with a simple link back to the post you’re referring to. That way more people will see what’s going on, and the whole community will grow. Just commenting on other people’s blogs is easier and faster, but it’s also less effective. Unfortunately, it’s what’s most encouraged by most interfaces.

(Now - should I disable comments, just for irony?)

Syndicated 2008-04-30 05:35:21 from I Am Not Charles

18 older entries...

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!