Car servicing costs

Debra’s car failed it’s MOT last week, this wasn’t unexpected, the garage told us to expect some problems the last time it was serviced. The main points of failure were the exhaust and catalytic converter, headlights and brake pads. There were a couple of warnings as well.

The main Skoda dealer we have been using since we bought the car ten years ago quoted us £2,500 for all the work and a service. Although it is in great condition this is way more than the car is worth. I was a little suspicious of the dealers motives. They told us the car is worth £80 which makes me wonder if they were hoping to get a bargain and sell a new car at the same time.

I had been hoping to keep the car for another couple of years, at least until the boys are at Uni, so I decided to shop around for the parts and see what I could do myself. In the end I got our local garage to fit an exhaust and catalyst for £300 and spent another £150 on parts. I still have the service and advisories to do but will probably end up saving £1800.

Xcode: Linking to different libraries depending on configuration

I’ve just started a cross platform project in Xcode and one of the problems I came across is it doesn’t seem possible to link to different libraries depending on whether you are building the Debug or Release configuration.

I did find an old message on the Apple developer forums that indicates you can do this with dependent projects, the trouble with this is when you clean your target all the dependent projects will clean as well.

In the end I did find a method that works for my project. The trick is to add a “Library Search Path” with the BUILD_STYLE environment variable:

/path/to/mylibrary/build/$(BUILD_STYLE)/x86_64

The $(BUILD_STYLE) macro gets expanded to Debug or Release depending on which configuration I am using, I just need to make sure the libraries are created in the appropriate folders.

I can then add the libraries using the setting “Other linker flags” with the -l option:

-l mylibraryname

Not as nice as the Visual Studio solution but it does seem to work.

Implementing the Light Box effect

I’m sure you have seen the effect by now, clicking on an image thumbnail dims the page you are looking at and opens the full size version of the image in the middle of the browser window. The original implementation of this was Lightbox, now we seem to be overrun with clones doing very similar things.

The trouble with including one of these clones in your site is you don’t really know what the quality of code is like and most seem to be groaning under the weight of all their features. All I needed was a short script to dim the page and display an image, the rest is overkill for me.

So rather than writing another clone and getting dragged down the same path I thought I’d show you the steps to adding the lightbox effect to your own site.

Most of the work is handled in JavaScript, there isn’t anything too demanding but if you haven’t used JavaScript before you are probably better off elsewhere. I will also use JQuery simply because scripting the browser is unbearable without it, if you haven’t used JQuery before read the introduction before you continue.

So the first stage is to dim the whole page, we do this by adding a <div> element to the end of the body. The div is styled with absolute positioning, fixed to the top left corner and with the width and height set to 100% so it fills the whole browser window. The opacity is set to 0.5, the background colour to black and it is hidden for now.

#bl-curtain {
    position:absolute;
    top:0;
    left:0;
    bottom: 0;
    right: 0;
    width: 100%;
    height:100%;
    background:black;
    opacity: .5;
    display:none;
}

In our HTML we need an image thumbnail enclosed in an anchor tag, with the class set to boxlight:

<a href="image.png">
    <img class="boxlight" src="thumb.png"
        alt="Screenshot thumbnail" border="0">
</a>

JQuery lets us capture a click on any images marked with the boxlight class:

$(document).ready(function() {
    $('.boxlight').click(function() {

We will drop out for IE6 or earlier, I think you can probably get this to work with IE6 but I just don’t care:

if ($.browser.msie && parseInt($.browser.version) <= 6) {
    return true;
}

It’s probably a good idea to fetch the url from the parent anchor early on and drop out if we can’t find it:

url = $(this).parents('a').attr('href');
if (!url) return true;

Now we add our new <div> to the end of the current body:

$('body').append('<div id="bl-curtain"></div>');

This will pick up the style from the earlier style sheet but for IE we need to add the opacity filter after the element is in the page:

if ($.browser.msie) {
    $('#bl-curtain').css('filter', 'alpha(opacity=50)');
}

If the user clicks on the background we need to clear the image and curtain:

$('#bl-curtain').click(function() {
    fadeOut();
});

Finally we can get around to producing an effect, start by fading in the curtain to cover the existing page:

$('#bl-curtain').fadeIn();

With the background in place we need to start loading the main image:

var img = new Image();
$(img)
    .attr('src', url)
    .attr('id', 'bl-image')
    .click(fadeOut)
    .one('load', function() {
        onImageLoad(this);
    });

If the image is in the browsers cache then IE doesn’t fire the event so we need to do this manually, this might be the same for Opera, I haven’t checked:

if ($.browser.msie && !$(img).complete) {
    $(img).trigger('load');
}

We return false so the browser doesn’t try and follow the link in the anchor tag as we have done everything here:

    return false;
    });
});

The onLoad function has a fair amount of work to do, mostly checking if the image is too big for the browser window and if it is resizing it accordingly:

function onImageLoad(image) {
    // Once the image has loaded we can add it to the document
    $('body').append(image);

    imageWidth = $(image).width();
    imageHeight = $(image).height();

    // Resize the image if it is too big for the browser window
    viewPortWidth = $(window).width();
    viewPortHeight = $(window).height();

    if (viewPortWidth < imageWidth || viewPortHeight < imageHeight) {
        horizontalScalingFactor = imageWidth / viewPortWidth;
        verticalScalingFactor = imageHeight / viewPortHeight;

        scaling = Math.max(horizontalScalingFactor, verticalScalingFactor);

        imageHeight = imageHeight / scaling;
        imageWidth = imageWidth / scaling;

        $(image).css('height', imageHeight);
        $(image).css('width', imageWidth);

    }

    // Centre the image in the page
    $(image).css('margin-top', -imageHeight / 2);
    $(image).css('margin-left', -imageWidth / 2);

    // Finally we can fade it in
    $(image).fadeIn();
}

You might have noticed the negative margins applied to the image in the last piece of code, that is because the styling for the image places the top left corner in the centre of the page:

#bl-image {
    position:absolute;
    top:50%;
    left:50%;
    display:none;
}

The last piece of code fades out the image and background then removes them from the page:

function fadeOut() {
    $('#bl-curtain,#bl-image').fadeOut(function() {
        $(this).remove();
    });
}

Two weeks in Italy

We usually spend our summer holidays camping, either in the UK or northern Europe. This is a great way to keep the costs down and the kids have always enjoyed the open space you get at a good camp site. Unfortunately our folding camper had been showing its age so we sold earlier in the year to a couple who planned to take it to Glastonbury.

I’ve always loved Italy, the food, the cars and the people. I’ve travelled there on business many times and we spent our honeymoon there twenty years ago so we decided to go back.

As I stopped flying quite a few years ago we took the train, travelling from St Pancras, London to Paris on the Eurostar then Paris to Turin by SNCF. St Pancras is a splendid station completely spoilt by the shopping centre built underneath it, you are out of luck if you want to sit down before you enter the terminal. Travelling by Eurostar turned out to be much better than SNCF, the food on the SNCF train was appalling for a six hour journey.

We spent a night in Turin, a rather eventful night in Verona then travelled on to Colfosco in the Dolomites. Colfosco is a quite village, mostly geared to skiing although there is plenty to do in the summer. We stayed at the Garni Delta, a lovely warm and welcoming B&B at the top of the village.

From there we travelled over to Venice for a couple of days. Venice is very popular and they clearly don’t have to try very hard to keep their customers. It was over priced with poor food, lots of graffiti and rubbish everywhere. I don’t remember it being this bad last time we visited, perhaps they are getting too many visitors.

For the last few days we stayed in Bergamo, a town in Lombardy about 40 km from Milan. We stayed in the Cillà alta, the 17th century old town on the hill. The old town is largely pedestrianised, very quite and pleasant, a complete contrast to Venice. We stayed in A casa mia, a small friendly B&B run by Cristina Gherlinzoni.

It was a lovely holiday, travelling by train was fine although I will spend a bit more for hotels closer to the station next time and take my own food onto the SNCF trains.

New front door

New front door

I’ve just about finished fitting new composite doors to the front and rear of my house. The old doors have never really fitted well, in the winter the wind blew straight through the house. We bought the doors online and I fitted them myself, this is the most difficult diy job I would tackle.

I made a few mistakes on the first door but the second went in easily. We originally had a quote for £5,500 for replacement solid wood doors, by switching to composite and fitting them myself the cost came down to about £1,300. The finish is very good, you wouldn’t know they aren’t wood and they have the big advantage of stability when the weather changes. I’m looking forward to a draft free winter.

Which camera to take

We just got back from our summer holidays in northern Italy, as we were travelling around quite a bit I wanted to travel as light as possible so didn’t take my SLR. This time we made do with a Canon G9 and the camera in my iPhone 3GS.

I have been pleasantly surprised by the camera in the phone, obviously it isn’t near the G9 but it can take remarkably good photographs. It took my a little while to figure out that you can specify what part of the photograph to meter on, just touch the display on the subject of the image. There is a reasonable amount of noise in poorly lit photos but on the whole it is very good for a phone.

There is an iPhone app called Best Camera which is good at editing and uploading photos to Flickr although it does seem to loose some EXIF data.

My photos tagged with iPhone on Flickr

Allotment strawberries

Our allotment strawberries have been really productive this year, we have been pick ten or twelve pounds every two or three days:

Allotment strawberries

Creating a null printer in Windows

I get quite a lot of requests for support on how to set-up Print Distributor to create a null printer that discards any documents. It seems there are applications which produce regular unwanted reports that can’t be turned off.

Actually you don’t need Print Distributor to do this, everything is already available in Windows.

Start by opening the Printers folder and launch the add printer wizard.

Choose a local printer and create a new port selecting local port for the type.

Enter NUL: for the port name and then select a driver, any one will do although I tend to select the HP LaserJet 5.

Name your printer and finish the wizard, now anything you print to this printer will just disappear.

The trouble with C++

I have been using C++ for quite a few years now, both Mail Print and Print Distributor are written in it and I consider myself reasonable competent with it.

However I loathe it deeply. It really is a complete mess, there are so many gotcha’s and even the simplest of tasks can run to dozens of lines of code. Take a look at stackoverflow.com/questions/536148/c-string-parsing-python-style for example. The C++ code presented is appropriate but virtually unreadable at a quick glance. On the other hand the Python code is simple and easily read.

Product Road Maps

Why I don’t publish product road maps

I have rough maps of where my development effort is going to go on both Mail Print and Print Distributor so why don’t I make them public? I certainly get enough requests for new features, many of the requests are followed by demands for when they will be implemented.

The problem is development is pretty unpredictable, especially if you are working in area you are unfamiliar with. Setting an expectation that a new feature will be available in March then not delivering until November isn’t going to win you many friends. Promising a feature then cancelling it is even worse.

There is also the problem of letting your competitors know what you are planning, there are a few products which are obviously inspired by my software. The problem these people have, is they are always a step behind, this is where I want them to be.

So my response to questions about future features and roadmaps is please buy the product on its current capabilities, if it doesn’t do what you want then look elsewhere. If you have bought and aren’t satisfied then let me know and I will refund your order.