Who needs Photoshop? I have Paint.NET!

Granted, I’m no graphics designer, so my graphic editing needs are pretty mundane. Still, I need to crop, resize, recolor, reformat, enhance, distort, and do all those other fun things to images from time to time. I also need to mock up web pages and graphics. I could buy Photoshop to do this, but I don’t have to, because I have Paint.NET — and it’s free!

Paint.NET: free, open-source image editingPaint.NET is a free, open source image editing application for Windows. It has a fantastic feature set and is rock solid — I have never had it crash, become unresponsive, or otherwise trash anything on my system, and that’s after using it for months (and using it on my 4 1/2-year-old underpowered home PC to do some image editing for Christmas cards).

If Paint.NET can’t do what you want out-of-the-box, then you can extend it. It offers a plug-in architecture, and there’s a nice collection of community-written plugins available to download.

Hats off to Rick Brewster and others for this fantastic product. It’s so nice that I’m going to donate as part of my drive to donate $5 per month to a free software product. Since I’m two months behind, the Paint.NET team get ten samoleans. Well worth it, considering Photoshop costs just a bit more than that.

My donation history to date far is as follows.

The ultimate launcher: Launchy

William of Bug this! Technie Journal writes about how he likes Vista’s start menu search feature, which lets you quickly find programs in the start menu (Tools that save you headache on trying to find your program in 100+ items start menu). I also liked the feature, and I agree with him in that the feature is not good enough to warrant a Vista upgrade. However, while he found a solution in Colibri, I prefer Launchy.

What does Launchy let you do? To understand, let’s look at some ways to open Remote Desktop Connection:

  1. Click Start, then All Programs, then Accessories, then Remote Desktop Connection.
  2. Press Windows-R to open a command prompt, then type mstsc, then press enter.
  3. Press ALT-Enter, type rem, then press enter.

Launchy screenshot#3 is Launchy in action. You can mistype commands, and it’ll still find reasonable matches — type reno and you’ll still likely find Remote Desktop Connection. Multiple matches? Choose from a drop-down list that puts the most recently used and best matches at the top. It’s super-productive.

With Launchy, here’s how I open Mozilla: ALT-Enter, moz, enter. Visual Studio? ALT-Enter, vis, enter. Cisco VPN Client: ALT-Enter, vpn, enter. This is very cool.

Thinking of how much I love Launchy reminds me that I’ve totally skipped the month of September in my drive to donate $5 per month to a free software product, so I’m going to donate $10 to Launchy — because it is that cool. My donation history to date far is as follows.

Thanks to Josh Karlin for writing such a great utility!

Wilson’s O/R Mapper going open source

I’ve been a fan (and user) of Paul Wilson‘s O/R mapper for some time now, having contributed to code generation templates, a service library, and a private Subversion repository for registered owners. I’m happy to say that, as of today, Paul has decided to release his O/R mapper as open source, and I’ve been given the honor of being its caretaker in the process.

The open source release of WilsonORMapper will be hosted on Google Code at http://code.google.com/p/wilsonormapper/. I expect to check-in the first official open source release over the next few days, once I clean up a few things and make the necessary license changes to the source. The code will be released under the New BSD License, which is one of the most permissive open source licenses out there.

Thanks to Paul for all his work over the years and for releasing this wonderful product to the community, and for giving me the go-ahead to make it happen.

And for those keeping score… this is the second product I’ve coerced into full public open source in 2007 (the ASP.Net CSS Adapters, back in March, and now WilsonORMapper). Not bad for a hack like me. 🙂

FileHelpers: the .Net way to import text files

I am working on a project where I have to import data from thousands of text files. These text files vary in formats: they use different delimiters; they use quoted identifiers never, sometimes, or always; they sometimes have missing end-of-row columns. Importing these took a combination of custom scripts (to clean up and reformat) and XML format files for SQL’s BCP (bulk copy) command… until I found FileHelpers.

FileHelpers by Marcos Meli is a .Net library which provides services to import and export text in delimited and fixed-length file formats. It takes a unique approach to the file import problem:

  • You write a class, giving it properties to store the data in the text file.
  • You apply attributes to the class and properties, describing the format of the file and applying import rules.
  • You import the file using a single command, which creates an array of objects populated with the data from the text file.

With support for custom converters, null types, optional fields, before/after import events, extensive parsing rules, and so much more — not to mention a web site with gobs of examples and documentation — FileHelpers has single-handedly driven me away from the script and batch file approach to a much more powerful .Net application to import my files.

The fact that FileHelpers uses regular .Net classes allows you to use the same class to both import data from a file and persist it to a database. For example, consider the following sample text file:

1,Chris,Smith
2,Bob,Jones
3,"Mary Jane",Brown

Clearly we have three fields in this comma-delimited file, so we write the following class to hold the data. Attributes provide instructions to FileHelpers — specifying that it is a comma-delimited file, and that the quotes in the first and last name fields are optional. (Note that you can use fields or properties; I use fields below for brevity.)

[DelimitedRecord(",")]
public class Person
{
	public int PersonID;
	[FieldQuoted('"', QuoteMode.OptionalForRead)]
	public string FirstName;
	[FieldQuoted('"', QuoteMode.OptionalForRead)]
	public string LastName;
}

Importing this file now becomes as easy as writing two lines of code.

FileHelperEngine<Person> engine = new FileHelperEngine<Person>();
Person[] records = engine.ReadFile(@"c:\myfile.csv");

You now have an array of Person objects loaded with data from the text file. Now, let’s say you wanted to persist these objects to a database. You can use the same Person object to persist to your database with an O/R mapper. If you were using Paul Wilson’s O/R Mapper and the WilsonORWrapper, you would decorate your class as follows:

[DelimitedRecord(","), IgnoreInheritedClass]
public class Person : WilsonORWrapper.Entities.EntityBase<Person>
{
	public int PersonID;
	[FieldQuoted('"', QuoteMode.OptionalForRead)]
	public string FirstName;
	[FieldQuoted('"', QuoteMode.OptionalForRead)]
	public string LastName;
}

Note I added the base class and the IgnoreInheritedClass attribute, which tells FileHelpers to ignore any inherited fields and properties (otherwise, the IsReadOnly property from EntityBase would be included).

With that, I can now persist all the records I read using FileHelpers back to my database using the O/R mapper.

FileHelperEngine<Person> engine = new FileHelperEngine<Person>();
Person[] records = engine.ReadFile(@"c:\myfile.csv");
foreach ( Person p in records )
{
	Data<Person>.Track(p);
}
Data<Person>.Save(records);

Incredible! We can even add supporting logic. Let’s say I wanted to only insert new persons into the database. I could do this.

FileHelperEngine<Person> engine = new FileHelperEngine<Person>();
Person[] records = engine.ReadFile(@"c:\myfile.csv");
foreach ( Person p in records )
{
	Person pers = Data<Person>.Retrieve("PersonID = " + p.PersonID.ToString());
	if (pers == null)
	{
		Data<Person>.Track(p);
		Data<Person>.Insert(p);
	}
}

FileHelpers makes this and so much more possible. It’s the backbone of a project I’m writing, and it’s making some heavy data-parsing much easier. To top it all off, FileHelpers is open source — you can download the code from their Subversion repository, and post patches on their support forums. Patches are well-received — I’ve already had two (1, 2) I’ve sent and had applied.

Thanks again to Marcos (and recently-added co-developer, Matt Campbell) for providing this fantastic library. For regular updates, be sure to read the FileHelpers Library Blog.