Crystal and #Develop

It's report time in my current .NET project at work. By that, I mean it's time to write the code to generate paper reports on the data. And yes, they will be paper. For some reason, nobody around here ever wants to read anything off their monitor.

Currently, my plan is to push the data into a Crystal Report. I prefer the push model because I think it cuts down slightly on the deployment headaches. I prefer Crystal because ... - OK, I don't actually like Crystal Reports that much, but it's basically all we've got. There are other options, but they all suck a lot worse than Crystal Reports.

Actually, I should correct that last statement. As a matter of fact, we don't have Crystal Reports - we have Visual Studio .NET 2002, which comes with a version of Crystal Reports. This means that I'm now back to using VS.NET to write my reports and SharpDevelop to write my code.

Probably as a result of this, I'm having some problems with adding a CrystalReportViewer to a form in the SharpDevelop forms designer. I'm able to customize the sidebar to add the Crystal controls, but when I drop a CrystalReportViewer on the form, it doesn't work properly. In particular, SharpDevelop isn't displaying it - it shows up at the bottom of the form designer, but not on the actual form.

The fix for this is to simply add the following to the form's designer file:
Me.Controls.Add(Me.myCRViewerName)
That at least shows the control on the form, but it still doesn't function properly. I can't resize the control or even select it on the form. However, I can still access all the properties by clicking the object's icon at the bottom of the designer (what the hell is that area called, anyway?).

I guess we'll see how this goes. Perhaps it's due to using the .NET 1.0 Crystal libraries with the .NET 2.0 application. Or maybe SharpDevelop just doesn't like the Crystal controls. Or maybe I just screwed something up. Hopefully I'll figure it out relatively soon.

Bindings are fun

I can't believe it: I'm actually using data bound controls. Will wonders never cease?

This is a surprise because I always hated data bound controls in VB6. They worked well enough for simple things, but they just didn't have a lot of flexibility. I always found them to be one of those features that's great if you're willing to buy into the one true method of application development described in Microsoft's tutorials, but not to nice otherwise. Thus I tended not to use them too much. In fact, I pretty much only used data controls bound to data grids as a way of browsing data sets. I handled everything else in code.

However, I was pleasantly surprised by data binding with ADO.NET. For starters, the fact that ADO.NET data sets are disconnected eliminates the inflexibility over control of updates. This was a big improvement in and of itself.

The big one, though, was when I discovered the System.Windows.Forms.Binding class, which is what actually handles binding a control property to a data set field. It turns out that this class has two handy events: Format and Parse. These are raised when a control is populated from the data set and when the control value is propogated back to the data respectively.

Using these two events allowed me to do one of my favorite tricks with bound controls: condensing an object into a combo box. So, for example, I can have an EmployeeID field and bind a combo box to that, but have the box display the employee's full name, department, etc. It's actually quite nice. Things weren't nearly this nice in the bad old days of VB6, and so I am once again a happy Windows programmer.

Those who forget the past

Why, why, why can I not remember that TIMESTAMP is a reserved work in SQL?

I've done this several times, and it's just getting stupid. At this point I feel like a complete idiot.

What happened was making up a database schema this morning and I needed a record timestamp. So I put in a column named "Timestamp". An obvious enough name. The table designer didn't complain and I didn't even think about it until ADO.NET raised a "syntax error in INSERT statement" exception when I tested my input form. So then I messed around for a while until I thought to check my column names and ended up smacking myself in the head.

The problem, of course, is twofold. First, most of the SQL I do is select queries, so I don't use the TIMESTAMP keyword very often, and hence don't think of it. Second, lots of the databases I do at work are simple, stand-alone MS-Access databases, so the easy way to design the tables is in the Access table designer. And, in the spirit of helping clueless people do blindingly stupid things, Access doesn't complain when you enter a reserved word as a column name.

Of course there's always that thing where you enclose the column name in brackets (does ADO.NET still allow that?), but I always found that sort of nonsense was best avoided. It never seemed to work the way I expected anyhow.

Corollary: Be careful about Form.Load

A corollary to yesterday's abstract base class problem: be careful what you put in the Form.Load event. Apparently the form designer raises that too.

Basically, I had a VB.NET data input form and I wanted to create a specialized version of it, so I subclassed it. The problem is, I added some code to the base class's Load event handler. The code just retreived some comfiguration data from an XML file and used it to populate some combo boxes from a database. The intention was to just let the child class inherit this, since the boxes are all the same.

But, of course, it couldn't be that easy. As soon as I switched over to the child class and tried the form designer, SharpDevelop showed me a nice error message and backtrace. Apparently it was trying to open the XML file and couldn't find it. The path was relative to the application's directory, and at design time, "the application" is apparently the IDE.

I ended up just moving this code to a method that's only called in the child class's Load event handler. That seemed to fix the problem.

Seems like a bit of a hack, though. I would think that if it works at run-time, then it shouldn't give you problems at design-time. But apparently I'm alone on that.

Abstract classes and visual inheritance

You know what sucks? In .NET IDEs, including Visual Studio and SharpDevelop, the IDE needs to create an instance of a class to edit it in the form designer. The upshot of this is that you can't have both an abstract base class and visual inheritance.

By way of overview, the situation is basically this: I have a bunch of VB.NET data entry/update forms that are essentially all the same. They edit different database tables and so have different fields, but the underlying data access code is almost exactly the same. So, being an object-oriented kind of person, I figured I'd create a generic data entry form and inherit from that. That saves me having to do a copy-and-paste job for all the boiler-plate ADO.NET code.

Since this class only exists for other classes to inherit from it, it only makes sense mark it as abstract. Since VB.NET doesn't support multiple inheritance, if I want the derived classes to inherit from Windows.Forms.Form (which I do), then my abstract class has to inherit from it. But that breaks the forms designer because you can't create an instance of an abstract class.

The solution? Well, don't make the class abstract. Just keep it as a regular class and don't ever instantiate it in code. It's not "pure" object-oriented solution, but as far as I can tell, it's the only one that works.

It's phone upgrade time

It's been a very cell phone kind of evening. First, research for our pending upgrade, then problems with BitPIM.

I'll go in reverse order and start with my BitPIM problem. As you may already know, I have problems using BitPIM due to a buggy USB/serial driver. Basically, every time I disconnect the cell phone from my PC, the driver for the data cable crashes and I have to reboot to use it again. Thus I don't tend to use it very often.

It seems that the upgrade to Edgy added another bug to the process. Previously, Ubuntu hadn't had BitPIM in the APT repositories, so I converted the official RPM with alien and used that. Well, apparently BitPIM 0.9.04 is now in the universe repository. The package version is 0.9.04.dfsg.1-1. The problem with this is that the package is totally broken.

And when I say "broken," I don't mean "doesn't work," I mean brings my system to its knees. Basically, this version of BitPIM leaks memory like a seive. In less than 30 seconds after attempting to pull data off my phone, Python had eaten up 85% of my system memory, causing the system to thrash so badly I couldn't even switch to a terminal to kill the process. How it managed to eat up that much memory, I have no idea.

The good news is that the fix was simple: install the "alienized" RPM of version 0.9.08 from the official BitPIM site. Now everything is back to normal.

Now, the whole reason I was pulling the data off my phone is because I'm planning to go to the Verizon Wireless office tomorrow and see about renewing our contract and getting some new phones. However, this time I decided to do my homework first.

After checking out what Verizon offers, it looks like it's down to a Motorola RAZR V3m or a Samsung SCH-a930. The RAZR looks nice, but the a930 seems a bit more utilitarian. I'll have to take a look at each of them before making my decision.

I was initially leaning toward the RAZR because I'd read it could play MP3s, but further research suggests that the model Verizon sells can only do WMA. Apparently the MP3 thing varies from carrier to carrier. I'll have to check with the salesman, but I don't hold out much hope (of the phone doing MP3s or of the salesman knowing anything).

What really irks me is that I'm 99% sure the only reason they disable MP3 support is to promote the use of their VCast service. That's the one where they charges you an obscene amount ($1.99/song) to download music and other content that I don't care about. As if it wasn't bad enough that they nickle and dime you to death with everything else, now they won't even let you use your own data on the phone.

Playing with XSL

Today I finally got around to learning a bit of XSLT. It's one of those things that's been on my list for a while, but I just never really had need for it before.

Well, since I converted LnBlog's data files to actual XML last week (it's about freaking time), I figured I'd experiment with displaying the entries without any server-side processing. To that end, I went through the W3 Schools tutorial and tested out a couple of XSL stylesheets to see how it works. I probably won't actually do entry display that way, but it seemed like an interesting experiment.

What I may actually use XSL for is RSS feeds. You know, so I can get that cool "my feed is a web page" thing like FeedBurner has. The only problem I had on that was getting my entry text to display as HTML. For some reason, when I try to loop through the channel items, Opera displays the HTML is the descriptions shows as raw HTML code. Doesn't seem to matter whether the entities are escaped or the whole thing is enclosed in a CDATA block. I guess I'll need to do some actual studying to figure that one out. Who'd have guessed?

Card reader and flash drive

I got the rest of my order from NewEgg today. I ordered an internal multi-card reader and two of the 1GB SD card/mini USB card reader combos. Oddly enough, I got the two SD cards last week, but the three card readers shipped separately from the cards, despite the combo deal.

Anyway, there is good news here. First, the multi-reader, a RosewillRCR-100/101, works flawlessly with Kubuntu. Card inserts are detected correctly and writing is fairly fast, unlike with the reader built into my printer. Now I can fill up that 1GB card for my MP3 player without having to wait forever! This reader also gives me a front USB port, which I had been missing. (Due to an oversight in ordering the parts for my PC, my case has no front USB.)

In fact, it's even better than that. It turns out that my Edgy USB drive problem no longer occurs when I use the new front USB port. Apparently it only happens when I plug the pen drive into my Walmart-special Belkin external hub. I'm not sure why, but it was the cheapest USB hub they had on the shelf when I bought it, so I guess I can't be too surprised.

Edgy swap bug

Hey, I found another Edgy bug! This one only happened on the laptop. I didn't notice it until today because it happens during boot, and until an fsck ran this morning, it was hidden behind the "user-friendly" startup screen.

Aside: am I the only one who thinks the new boot screen really sucks? Sure, it looks nice, but I kind of like knowing what's actually going on when the system boots. I don't need to see all the gory details, but when the progress bar stalls for a really long time, I'd like to at least know what subsystem it stalled on.

This particular problem was simple: my swap partition wasn't getting turned on. A manual sudo swapon -a resulted in an error that said my lond-uuid-for-device was an invalid parameter.

Second aside: What's with the device UUIDs in Edgy? Where did that come from and why did they switch to it? I don't necessarily think it's a bad thing - in fact, it seems like a good idea. I just wonder where it came from.

Anyway, the solution was simple. Just run sudo mkswap /dev/some-long-uuid followed by sudo swapon -a and everything was great. I still don't know what caused the problem, though. My initial guess was the UUID symlink, but that turned out to be correct. I guess I'll see what happens the next time I boot it.

Wesnoth improvements

After upgrading to Kubuntu Edgy, I see that I've got a new version of Battle for Wesnoth. The upgrade installed version 1.1.8, which is a significant improvement over the 1.0.x version I was running before. I have to say, Wesnoth has really gotten good since i got hooked on it three years ago.

The graphic improvements are nice, but those aren't really the best changes. What really helps it is the improved music, sound, and dialog. I'm in the middle of the Heir to the Throne campaign right now, and it feels a lot more polished than the last time I played it. In fact, the sound and music are now good enough that it feels like you're actually losing something when you turn them off!

I was particularly pleased the dialog is getting better. Portions of it were really kind of corny and stilted. They've also fleshed out the characters a bit, giving them more than one dimension. For example, Li'sar now actually has some motivation for betraying her mother, rather than just turning on a dime when the good-guys fill her in. They've also started giving Konrad a little sense of reality, as opposed to just making him a caricature of the innocent young hero. It's really quite refreshing.

People may complain about the open-source community being unable to produce decent games, but you konw what? I'll take Battle for Wesnoth over some crappy 3-D "kill everything in site" game any day. Snazzy visuals is not synonymous with quality, regardless of what the people at nVidia and ATI might like you to think.

Reality check

Dennis Forbes posted a good article on the topic of programmer compensation the other day. It's an interesting counter-balance out the latest incarnation of the "programmers are unique and special people" meme, which is that programmers really aren't all that interested in money.

Am I the only one who's getting sick of this meme? I mean, do you see this sort of thing in other professions too, or is it just in the computer industry? Do doctors and lawyers sit around talking about how they're fundamentally different from people who do other types of work? It's kind of hard to imagine that.

We've come a long way

If you subscribe to the same RSS feeds I do, you've probably come across this ZDnet blog by now. It was plastered all over the net a couple of days ago.

I don't know why everyone picked it up. It's really not that interesting or insightful. It's not blindingly stupid, but it doesn't say anything that hasn't been well known for years.

What I find interesting is that, for 90% of the desktop Linux problems the author mentions, there's not a damned thing anybody in the community can do to solve them. Believe it or not, this is actually a very, very good thing. Why? Because it means desktop Linux has come so far that we've solved all of the big problems that we can.

Just consider the big three problems Kingsley-Hughes mentions: software, hardware, and games. Aside from half-solutions like emulation and virtualization, there's not a thing we in the community can do about support for proprietary software and games. If the vendors don't want to support Linux, we're out of luck.

This is less true of hardware, as we can always write our own drivers. However, there's no way the community can keep up with every exotic, no-name device on the market (though we're doing a good job on the more common devices). The vendors are the ones with all the knowledge of these devices, and if we don't have their support, we can't help but spend our time playing catch-up.

Of course, the lack of hardware support extends to the point about hardware being difficult to install. I'm sure configuring hardware could be easier, but when it comes to devices that are only experimentally supported, what can you expect? When the device itself is just barely working, it's not reasonable to expect that the developers will have a nice, polished, newbie-friendly configuration GUI. Again, this wouldn't be a problem if we had vendor support.

The last two "problems" listed are simply "grin and bear it" type problems. You can't shut up the zealots and you can't make everyone agree on a single distribution (nor can you make people stop coming out with new ones, what with that whole "free software" thing). It's the price of freedom. It's unfortunate that some people find that a turn-off, but we'll just have to show them other reasons to join the community. If we keep making progress like we have been since I started using Linux about seven years ago, that shouldn't be hard.

It's funny 'cause it's true

Here's some Friday humor for you: If Architects Had To Work Like Web Designers.... Quite the humorous little piece. It comes from a web developer's point of view, but much of it applies to any kind of custom development.

It wasn't complete, though. One thing I missed was the requirement for psychic ability.
Customer: "Why doesn't it do X? It absolutely, positively has to do X or it's useless to us!"
Developer: "X? What's X? Nobody ever even mentioned X until just now!"
I guess that wouldn't fit into that piece, though, since it's set at the beginning of a project and the psychic ability conversation doesn't happen until you're in the middle of delivering.

SharpDevelop SDK help

It figures. After being so happy with SharpDevelop yesterday, I spent the better part of the morning fighting with it.

My problem was getting the context-sensitive help system to work with the .NET 2.0 SDK help files. To do this, you have to install the .NET 2.0 SDK, which is a 350MB download and over 600MB installed. Then you have to configure which help collection you want SharpDevelop to use.

Well, I did all that, but something wasn't right, because the dynamic help kept searching MSDN online instead of using the local files. I tried configuring it for some different help collections, hoping that maybe I just had the wrong one. But in the process, I somehow managed to break the help system completely. Not only was the dynamic help not using the local files, now the help index, contents, and everything else was gone too!

To cut a long story short, after spending way to much time searching and reinstalling, I finally stumbled upon this SharpDevelop forum thread, which clued me in to the solution. Apparently all I needed to do was open up "C:\Documents and Settings\USERNAME\Application Data\.ICSharpCode\SharpDevelop2\help2environment.xml" and clear out the contents of the <collection> tag. After that, I restarted #Develop and the help was fine.

SharpDevelop beats VS.NET

I tried something new at work today: SharpDevelop. I've been doing some more VB.NET work and, frankly, Visual Studio was starting to piss me off.

Part of the problem is probably that we're still in the stone age. We're using VS.NET 2002, which is two versions out of date. It's not really a bad IDE, but every time I use it it just feels really clunky. It just seems to get in my way as much as it helps.

I've only used it for a couple of hours so far, but SharpDevelop seems much nicer. The interface is cleaner and easier to manage. The editor is also nicer than VS.NET 2002's, with parenthesis matching, none of that crumby code reformatting, and that nifty automatic type addition shortcut.

And the best part? SharpDevelop is free, both as-in-beer and as-in-speech. It also allows me to develop for .NET 2.0 without having to waste time convincing my boss to buy VS.NET 2005 for whatever absurd amount of money it would cost. For the first time in a while, I'm a happy Windows developer. Yay!

Edgy and NDISwrapper

Another Edgy problem popped up the other day. In upgraded my laptop and suddenly NDISwrapper no longer worked. The driver wasn't getting loaded and attempting to do it manually with modprobe resulted in an error about an invalid parameter to the driver.

For some reason, just as with theflash drive thing, this problem went away when I booted into an older kernel. (Side note: the USB drive does work normally with the 2.6.17 kernel on the laptop.) Strangely enough, booting with kernel 2.6.15-25 worked perfectly, but 2.6.15-23 gave me the old boot screen and hung on "waiting for root filesystem."

The problem seemed to be that, somewhere in the process, my ndiswrapper-utils package got seriously screwed up. I had the ndiswrapper-utils package, but it seems that this actually depends on ndiswrapper-utils-1.1, which wasn't installed. After looking at the available packages, I actually ended up removing ndiswrapper-utils and installing ndiswrapper-utils-1.8. (I don't know why the default is ndiswrapper-utils-1.1 - you'd think the newer version would be the one to use.) This did the trick and my network card is now working normally.

Filters suck

You know what sucks? Internet filters. In particular, my employer's internet filters.

You know why they suck? One word: Wikipedia. About a month or so ago, our filters started blocking freakin' Wikipedia. Sure, it has it's pointless side, like the 13 page Chocobo article. Honestly, who needs 13 pages on an imaginary bird from a video game series, even if it is the best game series ever (rivaled only by Wing Commander)?

But there's actually lots of useful information on Wikipedia, particularly on technical topics. For instance, I've found it quite useful for explaining some of the telecom lingo I have to deal with on occasion. It might not be the most definitive reference in the world, but it's very good for quick explanations of unfamiliar topics.

I guess I shouldn't be surprised, though. We also blocked about.com for quite a while. The blacklist seems to be kind of off sometimes.