<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Chris Miller</title>
	<atom:link href="http://chris-miller.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://chris-miller.org</link>
	<description>Life, and how to live it!</description>
	<lastBuildDate>Tue, 24 Jan 2012 14:41:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>LittleIpsum</title>
		<link>http://chris-miller.org/archives/2012/01/24/littleipsum/</link>
		<comments>http://chris-miller.org/archives/2012/01/24/littleipsum/#comments</comments>
		<pubDate>Tue, 24 Jan 2012 14:38:01 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Essential Apps]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[app]]></category>
		<category><![CDATA[ipsum]]></category>
		<category><![CDATA[littleipsum]]></category>
		<category><![CDATA[lorem]]></category>

		<guid isPermaLink="false">http://chris-miller.org/?p=3270</guid>
		<description><![CDATA[LittleIpsum by Dustin Senos is a handy little tool for anyone doing design or programming work who&#8217;s constantly in need of some lorem ipsum to pad out visuals. I usually use lipsum.com which has a decent background on Lorem Ipsum as well as a configurable generator. LittleIpsum on the other hand is a nifty little [...]]]></description>
			<content:encoded><![CDATA[<p><a target="_blank" href="http://littleipsum.com/" title="LittleIpsum"><img src="http://chris-miller.org/wp-content/uploads/2012/01/icon_littleipsum.png" alt="" title="LittleIpsum" width="294" height="291" class="alignright size-full wp-image-3272" /></a></p>
<p><a target="_blank" href="http://littleipsum.com/" title="LittleIpsum">LittleIpsum</a> by <a target="_blank" href="https://twitter.com/dustin" title="Dustin Senos">Dustin Senos</a> is a handy little tool for anyone doing design or programming work who&#8217;s constantly in need of some lorem ipsum to pad out visuals.</p>
<p>I usually use <a href="http://www.lipsum.com/" title="Lipsum">lipsum.com</a> which has a decent background on Lorem Ipsum as well as a configurable generator.</p>
<p>LittleIpsum on the other hand is a nifty little Mac OS X menu bar app that allows you to quickly grab a couple of words, sentences or paragraphs of lorem ipsum.</p>
<p><span id="more-3270"></span>Clicking on the menu drops out a quite straightforward interface which you roll over to select the appropriate length of text you want. Once you&#8217;ve made your selection the text is then copied to your clipboard so you can paste it wherever you&#8217;d like.</p>
<p><div id="attachment_3271" class="wp-caption aligncenter" style="width: 639px"><img src="http://chris-miller.org/wp-content/uploads/2012/01/lipsum.png" alt="Selecting a range of lengths of Lorem Ipsum from the menu bar icon." title="LittleIpsum " width="629" height="305" class="size-full wp-image-3271" /><p class="wp-caption-text">Selecting a range of lengths of Lorem Ipsum from the menu bar icon.</p></div><br/>If you&#8217;re sticking together some HTML templates, LittleIpsum is handy for that too, just Ctrl+Click the menubar icon and the text copied to your clipboard will be wrapped in a <code>p</code> tag.</p>
<p>Handy little thing,<br />
- Chris</p>
]]></content:encoded>
			<wfw:commentRss>http://chris-miller.org/archives/2012/01/24/littleipsum/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Copying Mail settings between Mac OS X installations</title>
		<link>http://chris-miller.org/archives/2012/01/18/copying-mail-rules-between-mac-os-x-installations/</link>
		<comments>http://chris-miller.org/archives/2012/01/18/copying-mail-rules-between-mac-os-x-installations/#comments</comments>
		<pubDate>Wed, 18 Jan 2012 15:50:01 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://chris-miller.org/?p=3265</guid>
		<description><![CDATA[I&#8217;ve just installed a fresh copy of Lion on my machine and much to my dismay I have to set up all of my many mail filtering rules again! Bugger that, instead I had a dig around and decided to copy across the rules from my previous installation. All the rules you&#8217;ve set up are [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just installed a fresh copy of Lion on my machine and much to my dismay I have to set up all of my <em>many</em> mail filtering rules again!</p>
<p>Bugger that, instead I had a dig around and decided to copy across the rules from my previous installation.  All the rules you&#8217;ve set up are stored in a <code>.plist</code> file within Mail&#8217;s data stored in your Library folder.</p>
<p>In Lion you&#8217;ll find the rules at:</p>
<blockquote><p>~/Library/Mail/V2/MailData/MessageRules.plist</p></blockquote>
<p>Under Snow Leopard:</p>
<blockquote><p>~/Library/Mail/MessageRules.plist</p></blockquote>
<p>So all you need to do is copy/paste the relevant file from your old machine to the new one.</p>
<h3>Edit</h3>
<p>It&#8217;s worth noting that you can copy Smart Mailboxes and RSS feeds across as well.</p>
<p>Smart Mailboxes:</p>
<blockquote><p>
Lion: ~/Library/Mail/V2/MailData/SmartMailboxes.plist<br />
Snow Leopard: ~/Library/Mail/SmartMailboxes.plist
</p></blockquote>
<p>RSS Feeds (both OSes):</p>
<blockquote><p>
~/Library/Mail/RSS/
</p></blockquote>
<p>- Chris</p>
]]></content:encoded>
			<wfw:commentRss>http://chris-miller.org/archives/2012/01/18/copying-mail-rules-between-mac-os-x-installations/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Password Schemes</title>
		<link>http://chris-miller.org/archives/2012/01/11/password-schemes/</link>
		<comments>http://chris-miller.org/archives/2012/01/11/password-schemes/#comments</comments>
		<pubDate>Wed, 11 Jan 2012 15:53:25 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://chris-miller.org/?p=3241</guid>
		<description><![CDATA[Something that really annoys me, annoys me to anger, is brain-dead password schemes for websites where I&#8217;m forced to adhere to some moronic schema for my password to &#8220;enhance&#8221; security. Upper bounds on password length The most common issue I see across the plethora of inept schemes for passwords is bounds on length. I&#8217;m all [...]]]></description>
			<content:encoded><![CDATA[<p>Something that really annoys me, annoys me to anger, is brain-dead password schemes for websites where I&#8217;m forced to adhere to some moronic schema for my password to &#8220;enhance&#8221; security.</p>
<h3>Upper bounds on password length</h3>
<p>The most common issue I see across the plethora of inept schemes for passwords is bounds on length.  I&#8217;m all for having passwords with a lower bound, it&#8217;s all about security after all and shorter passwords are much less time constringent to brute-force, 5-6 characters is the most oft seen bound. With that I&#8217;m absolutely fine.</p>
<p>But as soon as you start requiring that my password be 	<em>no more than</em> a certain number of characters a klaxon starts wailing in my head.</p>
<p>The initial suspicion is that if you have an upper bound on the length of my password, you must be storing it in plaintext. If you are storing my password in plaintext then you&#8217;re either an idiot or a complete and utter fucking asshole, you can choose whichever you want.</p>
<p>For god&#8217;s sake, <a href="http://en.wikipedia.org/wiki/Salt_%28cryptography%29" title="Salting &#038; Hashing on Wikipedia" target="_blank">salt and hash passwords</a> before storing them.</p>
<p><span id="more-3241"></span><br />
<h4>Forms that cut off entry</h4>
<p>An even worse offender in this area are sign up forms in which the password fields have a given length. That means that you can type in your 20 character password without realising that you&#8217;ve been clipped at an arbitrary 12 characters.</p>
<p>Then when you visit the login form, which obviously wont have the 12 character limit on the password field, and type in your 20 character password it will throw back errors.</p>
<p>Please stop making my passwords an arbitrary length and you should definitely have a uniform stance on field lengths in your forms.</p>
<h3>Exact password length</h3>
<p>Enforcing an exact password length is the bigger, uglier brother of having an upper bounds on length. Not only have you set the lower and upper limit on how long a password can be, you&#8217;ve also said that they must be the same!</p>
<p>Holy hell, you&#8217;ve completely and utterly missed the point. Aside from the fact that you&#8217;re vastly limiting the number of permutations of passwords available to users, and of course the number of permutations a brute-force attack would be required to cycle through; you&#8217;re making the password much harder for the user to remember.</p>
<p>If I have a 6 character password that I use <em>everywhere</em>, such as I&#8217;d wager most users do, and you enforce a password length of 8 characters then you&#8217;re essentially forcing me to append two erroneous characters to the end of my password usually, I&#8217;d wager, a &#8217;11&#8242; or &#8217;00&#8242;.</p>
<h3>Enforcing the inclusion / exclusion of certain characters</h3>
<p>&#8220;Your password must contain at least one number&#8221;, &#8220;Your password must have one or more non-alphanumeric character&#8221;,  &#8220;You are required to have at least one uppercase letter&#8221;, &#8220;Your password must have&#8211;&#8221; &#8230;fuck right off.</p>
<p>My password should be <em>allowed</em> to contain any alpha, numeric or non-alphanumeric characters; it should not be <em>required</em> to contain them. If you&#8217;re trying to make me adhere to a given structure to my password then you&#8217;re limiting the number of permutations available to me again.</p>
<p>&#8220;But what about the idiots who choose easy passwords?&#8221; They&#8217;re still going to be idiots, just your special brand of idiot, making the password harder to remember just ensures that you end up with either a post-it note with the username and password posted on the side of a monitor or some super-secret-cia-level-symbol-substitution-cypher being used to swap out the characters in their god awful password.</p>
<ul>
<li>
		a = @
	</li>
<li>
		e = 3
	</li>
<li>
		i = !
	</li>
<li>
		o = *
	</li>
<li>
		u = well, still u
	</li>
<li>
		s = $
	</li>
<li>
		l = 1
	</li>
<li>
		t = 7
	</li>
<li>
		&#8230;
	</li>
</ul>
<p>My new super-secret, secure password should probably be <code>p@$$w*rd</code>!</p>
<p>On a side-note, if <a href="http://www.sitepoint.com/worst-passwords-2011/" title="The Worst Passwords of 2011" target="_blank">any of your passwords resembles any of these</a> you are a moron.</p>
<p>Post your password in the comments below and I&#8217;ll tell you if it&#8217;s secure or not!<br />
- Chris</p>
]]></content:encoded>
			<wfw:commentRss>http://chris-miller.org/archives/2012/01/11/password-schemes/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using On The Job 3 with Dropbox</title>
		<link>http://chris-miller.org/archives/2012/01/11/using-on-the-job-3-with-dropbox/</link>
		<comments>http://chris-miller.org/archives/2012/01/11/using-on-the-job-3-with-dropbox/#comments</comments>
		<pubDate>Wed, 11 Jan 2012 08:32:43 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Dropbox]]></category>
		<category><![CDATA[On The Job]]></category>

		<guid isPermaLink="false">http://chris-miller.org/?p=3172</guid>
		<description><![CDATA[I recently grabbed myself an 11&#8243; Macbook Air as I was in dire need of a laptop to use when away from home. The main attraction that I&#8217;d be able to work on any freelance projects when I have downtime regardless of where I am. I use a brilliant piece of software called On The [...]]]></description>
			<content:encoded><![CDATA[<p><img class="size-full wp-image-3173 alignright" title="Dropbox with On The Job 3" src="http://chris-miller.org/wp-content/uploads/2012/01/dropboxPlusOnTheJob.png" alt="Dropbox with On The Job 3" width="380" height="128" /></p>
<p>I recently grabbed myself an <a title="Macbook Air" href="http://www.apple.com/macbookair/" target="_blank">11&#8243; Macbook Air</a> as I was in dire need of a laptop to use when away from home. The main attraction that I&#8217;d be able to work on any freelance projects when I have downtime regardless of where I am.</p>
<p>I use a brilliant piece of software called <a title="On The Job 3" href="http://stuntsoftware.com/onthejob/" target="_blank">On The Job 3</a> to track time spent on jobs as well as generating and managing invoices. On The Job stores all your client and job data locally rather than in the cloud and doesn&#8217;t provide any means to sync data between multiple machines. This provides a bit of a connundrum — how do I keep an in-sync repository of my timings and invoices across the multiple machines I potentially use for my work?</p>
<p>The obvious choice is to use <a title="Dropbox" href="http://www.dropbox.com/" target="_blank">Dropbox</a> to keep the relevant application data in sync across multiple machines. As there&#8217;s no way to specify to On The Job where to look for the data we instead need to move the data store into a shared repository in Dropbox then create a link to this data from where the original used to live.</p>
<p><span id="more-3172"></span>All application data for On The Job is located at:</p>
<blockquote><p>~/Library/Application Support/On The Job 3/</p></blockquote>
<p><div id="attachment_3180" class="wp-caption aligncenter" style="width: 687px"><img class="size-full wp-image-3180" title="Shared Application Data in Dropbox" src="http://chris-miller.org/wp-content/uploads/2012/01/Dropbox.png" alt="Shared Application Data in Dropbox" width="677" height="439" /><p class="wp-caption-text">Shared Application Data in Dropbox</p></div><br/>The first thing we need to do is create a folder for all the shared application data to be stored in, I&#8217;ve aptly named mine &#8220;<code>Shared Application Data</code>&#8220;.  Then we move the On The Job application data from its default location to our new shared folder.</p>
<p>By default the folder which contains all the application data, <code>~/Library/</code>, is initially hidden from the Finder. To get round this we can open the relevant folders via the Terminal application, running the following command will open the folder containing the application data:</p>
<blockquote><p>open ~/Library/Application\ Support/</p></blockquote>
<p>From here you can move the folder named &#8220;<code>On The Job 3</code>&#8221; to your newly created Dropbox folder, at this point you should take a backup of your On The Job application data folder just in case anything goes wrong.</p>
<p>We&#8217;ve essentially now reset On The Job back to its default settings as it wont be able to locate any of the data you&#8217;ve accrued through past use. In order for On The Job to function properly with the appropriate data we need to create a link in the application support folder to our data in the Dropbox folder.</p>
<p><div id="attachment_3181" class="wp-caption aligncenter" style="width: 688px"><img class="size-full wp-image-3181" title="On The Job 3 data shared via Dropbox" src="http://chris-miller.org/wp-content/uploads/2012/01/On-The-Job-3.png" alt="On The Job 3 data shared via Dropbox" width="678" height="439" /><p class="wp-caption-text">On The Job 3 data shared via Dropbox</p></div><br/>Creating a link via the Finder doesn&#8217;t suffice for this, we must create a symbolic link via the Terminal using the following command:</p>
<blockquote><p>ln -s &#8220;~/Dropbox/Shared Application Data/On The Job 3/&#8221; &#8220;~/Library/Application Data/On The Job 3/&#8221;</p></blockquote>
<p>This step must be repeated for each machine you intend to use On The Job on.  If the <code>~/Library/Application Data/On The Job 3/</code> folder exists it should be removed, or perhaps renamed, before creating the symbolic link. Once the link is in place and all data files have been synced via Dropbox you should be able to open On The Job and see all of your clients, jobs and invoices just as you left them.</p>
<p><div id="attachment_3182" class="wp-caption aligncenter" style="width: 688px"><img class="size-large wp-image-3182" title="On The Job Working" src="http://chris-miller.org/wp-content/uploads/2012/01/On-The-Job.png" alt="On The Job Working" width="678" /><p class="wp-caption-text">On The Job Working</p></div><br/>Any changes made on one linked machine will cause the files in the dropbox to be synced to each of the other machines, mirroring any modifications you have made. It&#8217;s worth noting that Stunt Software recommend using Dropbox in order to sync your data across multiple machines and that they offer no support if anything goes wrong. As always it&#8217;s worth taking regular snapshots of your On The Job data from Dropbox ideally using Time Machine to keep regular incremental backups.</p>
<p>Have fun,<br />
- Chris</p>
]]></content:encoded>
			<wfw:commentRss>http://chris-miller.org/archives/2012/01/11/using-on-the-job-3-with-dropbox/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Medieval Sniper</title>
		<link>http://chris-miller.org/archives/2011/12/13/medieval-sniper/</link>
		<comments>http://chris-miller.org/archives/2011/12/13/medieval-sniper/#comments</comments>
		<pubDate>Tue, 13 Dec 2011 15:58:21 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[dream]]></category>
		<category><![CDATA[hero]]></category>
		<category><![CDATA[medieval]]></category>
		<category><![CDATA[Q]]></category>
		<category><![CDATA[sniper]]></category>

		<guid isPermaLink="false">http://chris-miller.org/?p=3164</guid>
		<description><![CDATA[I had an awesome dream last night, really vivid, see what you think: It&#8217;s a medieval time, there&#8217;s a big castle, a king, knights; the whole nine yards. I work a job in or around the castle, nothing too high profile, nothing to do with the court or the knights &#038; standing army. There&#8217;s a [...]]]></description>
			<content:encoded><![CDATA[<p>I had an awesome dream last night, really vivid, see what you think:</p>
<p>It&#8217;s a medieval time, there&#8217;s a big castle, a king, knights; the whole nine yards. I work a job in or around the castle, nothing too high profile, nothing to do with the court or the knights &#038; standing army.</p>
<p>There&#8217;s a strange mix of technology in this world, there are guns and bombs as well as all the comforts of modern living.</p>
<p>I, for some reason, am some sort of anti-hero. On my travels and throughout my work I gain experience and new abilities. Recently I&#8217;ve gained a skill where I can double jump (a frog-skill as it appeared to me in my dream), yet I&#8217;ve not had much of a chance to try it out. I can run, leap, then when in mid-air jump again and get even higher and further.</p>
<p><span id="more-3164"></span>Now, it turns out that there&#8217;s dissent in the air and one of the captains of the palace guard and his son, who is also in the military, are planning a coup and intend to usurp and kill the king!</p>
<p>It&#8217;s probably worthwhile to note at this point, the captain is being played by the <a href="http://en.wikipedia.org/wiki/John_de_Lancie" title="John De Lancie" target="_blank">guy who was Q in Star Trek</a>, not that it&#8217;s really relevant to the story.</p>
<p>I have the pleasure of being invited to court for a celebration of some sort. I&#8217;m in no way a guest of honour but I get to meet the big jobs such as a princess and also the king. This is when the craziness starts to go down.</p>
<p>I&#8217;m on a balcony with the royal court and there&#8217;s a massive explosion in the courtyard below. I push some of the folks, king included, out of the way. This is misconstrued by the loyal royal guards as an attempt on the king&#8217;s life, in their opinion putting me with the separatists.</p>
<p>A chase ensues and I&#8217;m hounded through the castle by the guards.  They chase after me until I reach the end of a, now broken, balcony &#8211; at the unreachable end is a set of stairs leading up into a mountain pass and some caves high up.</p>
<p>Desperate to get away I back up, take a run at the massive gap and leap, I make use of my new frog air-jump skills to jump again and make it all the way across to the stairway &#8211; the guards are obviously left behind.</p>
<p>I make my way up the pass as quickly as I can, it&#8217;s a long climb. I notice that I&#8217;m not alone and there&#8217;s a ghostly woman following me &#8211; there&#8217;s no way she managed to get across the gap after me! She approaches and I recoil, wary of who or what she is.</p>
<p>There is some conversation, nothing specific I remember, but I&#8217;m bestowed with a new skill &#8211; I am granted a sniper skill, I will be amazingly accurate with the sniper rifle which she then gives me. It&#8217;s plastic, long with a strap to stow it over your shoulder. I&#8217;m also furnished with a box of bullets to use with the gun &#8211; they&#8217;re entirely white and apparently they are the only bullets that&#8217;ll work with the gun.</p>
<p>Time goes past, perhaps a musical montage would be appropriate, some lyre music perhaps since it&#8217;s medieval times. I gain some more skills, nothing too interesting; I also form a relationship with the ghostly woman before she moves on telling me that I&#8217;ve been trained and am now ready.</p>
<p>I get some information about the usurper guards and their plan. They have a sniper of their own and intend to have him kill the king from a distance. He&#8217;s just a boy, perhaps 8 or 10 years old, but I know what I have to do: I have to kill the sniper, the head guard and his son to stop the plot against the king.</p>
<p>I&#8217;m also still being pursued by the loyal guards, still thinking me a potential threat to the king; ironic that I could be their only chance to save his life!</p>
<p>I&#8217;m making my way into town to take down those threats to the king when the guards are suddenly on my tail. I&#8217;m moving between high buildings that&#8217;re closely packed together, modern day sized yet somewhat rickety and falling to bits as you&#8217;d expect of medieval buildings.</p>
<p>I&#8217;m in a high floor of a building and have to jump from one window into another building to escape; the guards aren&#8217;t far behind me and can easily, if somewhat timidly, follow me from building to building. I stay ahead of them by recklessly, and if I say so myself, quite heroically, leaping back and forward between buildings, making my way towards the final standoff.</p>
<p>I&#8217;m eventually getting close to where I&#8217;ll be able to take these guys down. I&#8217;m walking along a rickety wooden balcony, high up on the side of a sandstone building. The rooftop of the building across from me is an appropriate place to set up. I have my rifle across my back and I&#8217;m ready to leap across.</p>
<p>Just at that moment the guard leading the chase appears on the balcony, he&#8217;s a friend from the days before this all started. I know he&#8217;s torn between duty and friendship. He looks into my eyes and knows I don&#8217;t intend malice but to correct the problems, I give him a curt nod and sprint to the end of the wooden balcony, it starts to come away from the building as I do. I leap towards the building, again, frog air-jumping to make the final part of the leap across. I land behind a wall on the roof, shielded from the view of the rooftop I&#8217;m going to be shooting towards.</p>
<p>I get behind some crates for cover and I can see across to the roof I need to target, they&#8217;re all there. The leader of the palace guard, his son and my rival the young sniper. There are other guards loyal to their cause there and they have hostages, lots of young children running around on the rooftop, scared.</p>
<p>I set up my rifle but they&#8217;ve spotted me. The young sniper starts rattling off shots but I&#8217;m too well covered. Other guards are firing but there&#8217;s no chance they&#8217;re going to hit me from the other roof.</p>
<p>I line up a shot, I&#8217;m not overly confident of my sniper skills yet. I shoot once, hit one of the guards in the shoulder &#8211; he&#8217;s not my target. The other guards start picking up children and holding them up as shields.</p>
<p>I release a few more rounds, actually hitting one of the kids as a guard moves him into the way of my sights. I&#8217;m getting agitated so I calm myself, take a breath. I line up the shot, squeeze the trigger and a hole erupts in the middle of the captain&#8217;s son&#8217;s forehead, he drops to the floor.</p>
<p>His father looks on to his son aghast at what he&#8217;s seen. He doesn&#8217;t look long, I blow a matching hole into his head, right through. I train my gun onto the young sniper, he&#8217;s lining me in his sights, but he&#8217;s too slow; a third matching hole in his head is his prize.</p>
<p>At this point the guards who were chasing me break through the door to the roof of the building I&#8217;m on and spill out, cutting off my escape. The lead guard, my friend, realises what I&#8217;ve done and that I&#8217;ve saved the king again. Guards at the front of the pack demand that I finish the job and gun down the remaining guards on the opposite roof but I decline. It&#8217;s their mess, they can clean it up.</p>
<p>One guard moves to take me into custody, my friend waves him off and turns to his side. I take a run and a jump off the roof, then another mid-air jump sees me onto the next building and I&#8217;m off into the metropolis never to return to my old life.</p>
<p>The end</p>
]]></content:encoded>
			<wfw:commentRss>http://chris-miller.org/archives/2011/12/13/medieval-sniper/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Get link to currently playing Spotify track via AppleScript</title>
		<link>http://chris-miller.org/archives/2011/10/05/get-link-to-currently-playing-spotify-track-via-applescript/</link>
		<comments>http://chris-miller.org/archives/2011/10/05/get-link-to-currently-playing-spotify-track-via-applescript/#comments</comments>
		<pubDate>Wed, 05 Oct 2011 12:55:01 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[applescript]]></category>
		<category><![CDATA[spotify]]></category>
		<category><![CDATA[track]]></category>

		<guid isPermaLink="false">http://chris-miller.org/?p=3152</guid>
		<description><![CDATA[I was looking around for a means to grab the URL of the currently playing track in Spotify earlier, but couldn&#8217;t find anything. I rattled together an AppleScript to do just that and copy the result, including the track and artist name, to your clipboard. &#8220;Feel Like Makin&#8217; Love &#8211; Bad Company: http://open.spotify.com/track/3HKthdb7Ejnydb74BvmQW0&#8221; I used [...]]]></description>
			<content:encoded><![CDATA[<p>I was looking around for a means to grab the URL of the currently playing track in <a href="http://spotify.com" title="Spotify">Spotify</a> earlier, but couldn&#8217;t find anything.</p>
<p>I rattled together an AppleScript to do just that and copy the result, including the track and artist name, to your clipboard.</p>
<pre class="brush: applescript; title: ; notranslate">
tell application &quot;Spotify&quot;
	set theTrack to name of the current track
	set theArtist to artist of the current track
	set theAlbum to album of the current track
	set track_id to id of current track
end tell

set AppleScript's text item delimiters to &quot;:&quot;
set track_id to third text item of track_id
set AppleScript's text item delimiters to {&quot;&quot;}
set realurl to (&quot;http://open.spotify.com/track/&quot; &amp; track_id)

set theString to theTrack &amp; &quot; - &quot; &amp; theArtist &amp; &quot;: &quot; &amp; realurl
set the clipboard to theString
</pre>
<p>&#8220;Feel Like Makin&#8217; Love &#8211; Bad Company: <a href="http://open.spotify.com/track/3HKthdb7Ejnydb74BvmQW0" title="Feel Like Makin' Love - Bad Company" target="_blank">http://open.spotify.com/track/3HKthdb7Ejnydb74BvmQW0</a>&#8221;</p>
<p>I used a few bits of <a href="http://conceitedsoftware.com/forums/topic/spotify-script" title="Conceited Software forum">this Ceonceited Software forum post</a> for pointers on accessing Spotify details via AppleScript.</p>
<p>Enjoy,<br />
- Chris</p>
]]></content:encoded>
			<wfw:commentRss>http://chris-miller.org/archives/2011/10/05/get-link-to-currently-playing-spotify-track-via-applescript/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Clay pots &amp; kettles</title>
		<link>http://chris-miller.org/archives/2011/09/14/clay-pots-and-kettles/</link>
		<comments>http://chris-miller.org/archives/2011/09/14/clay-pots-and-kettles/#comments</comments>
		<pubDate>Wed, 14 Sep 2011 08:20:11 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://chris-miller.org/archives/2011/09/09/3134/</guid>
		<description><![CDATA[I had a strange dream recently, unlike the strange dreams I usually have &#8211; nobody was a monster and there was no killing involved. Every person in the world is given a clay pot, in my dream there was no notion of where they come from, just that everyone always has one. Inside this pot [...]]]></description>
			<content:encoded><![CDATA[<p>
I had a strange dream recently, unlike the strange dreams I usually have &#8211; nobody was a monster and there was no killing involved.
</p>
<p>
Every person in the world is given a clay pot, in my dream there was no notion of where they come from, just that everyone always has one. Inside this pot is a clay teapot. All of them, pots and teapots, are made of terracotta; some are ornate, some decorated, others are just plain clay; regardless of how they look, they all serve the same purpose.
</p>
<p><span id="more-3134"></span></p>
<p>
The teapot is used to tell if you&#8217;re a compatible match with another person, it distills the feelings you have for each other and indicates if you could fall in love and be happy together.
</p>
<p>
There&#8217;s a museum exhibit showing old pots that&#8217;ve been dug up from centuries old graves. Fossilised remains lie with a pot amongst them, the clay shattered at one side but the teapot inside perfectly intact, preserved through the ages.
</p>
<p>
Children are given smaller, empty pots. This signifies purity and a child&#8217;s ability to love without question; they&#8217;re only given a larger pot containing a teapot when they&#8217;ve come of age.
</p>
<p>
Some strange poetry to the whole thing, god knows how it was supposed to work though!<br />
- Chris</p>
]]></content:encoded>
			<wfw:commentRss>http://chris-miller.org/archives/2011/09/14/clay-pots-and-kettles/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Pretty UK Vehicle registration years</title>
		<link>http://chris-miller.org/archives/2010/10/06/pretty-uk-vehicle-registration-years-2/</link>
		<comments>http://chris-miller.org/archives/2010/10/06/pretty-uk-vehicle-registration-years-2/#comments</comments>
		<pubDate>Wed, 06 Oct 2010 11:34:36 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[pretty]]></category>
		<category><![CDATA[reg]]></category>
		<category><![CDATA[registration]]></category>
		<category><![CDATA[uk]]></category>

		<guid isPermaLink="false">http://chris-miller.org/?p=521</guid>
		<description><![CDATA[If you&#8217;ve ever wanted to convert a date of a UK vehicle into a nice looking representation of the year code then you&#8217;ve came to the right place! I&#8217;ve written a small PHP function to convert a given date to one of the following formats: Dates before Feb 1963 [YEAR] i.e. &#8220;1960&#8243;, &#8220;1962&#8243; Dates from [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve ever wanted to convert a date of a UK vehicle into a nice looking representation of the year code then you&#8217;ve came to the right place!</p>
<p>I&#8217;ve written a small PHP function to convert a given date to one of the following formats:</p>
<ul>
<li>
		Dates before Feb 1963</p>
<ul>
<li>
				[YEAR]
			</li>
<li>
				i.e. &#8220;1960&#8243;, &#8220;1962&#8243;
			</li>
</ul>
</li>
<li>
		Dates from Feb 1963 &#8211; August 2001</p>
<ul>
<li>
				[SUFFIX/PREFIX LETTER] ([YEAR])
			</li>
<li>
				i.e. &#8220;V (1999)&#8221;, &#8220;A (1983)&#8221;
			</li>
</ul>
</li>
<li>
		Dates from September 2001 onwards</p>
<ul>
<li>
				[AGE IDENTIFIER] ([YEAR])
			</li>
<li>
				i.e. &#8220;57 (2007)&#8221;, &#8220;57 (2008)&#8221;, &#8220;60 (2010)&#8221;
			</li>
</ul>
</li>
</ul>
<p><span id="more-521"></span></p>
<pre class="php" name="code" id="pretty-uk-vehicle-registration-years">
/* getRegistrationCode *********************************************
 * Get the age identifier from a UK vehicle registration plate from
 * a given date.  Returns the identifier as a string with the year
 * of registration in brackets.
 *
 * $registrationDate    The date of registration to be converted
 *
 * return                String representation of the registration
 *                         date
 ******************************************************************/
function getRegistrationCode( $registrationDate ) {
    $reg      = $registrationDate;

    $year     = (int) date( "Y", strtotime( $registrationDate ) );
    $month    = (int) date( "n", strtotime( $registrationDate ) );
    $date     = date( "Y-m-d", strtotime( $regestrationDate ) );

    /* < FEBRUARY 1963 *********************************************
     * If the registration year is 1962 or before then just return
     * the year
     **************************************************************/
    if( $date < "1963-02-01" ) {

        $reg    = "".$year;

    /* FEBRUARY 1963 - AUGUST 2001 *********************************
     * For registrations from 1963 to August 2001 look up the
     * appropriate registration letter
     **************************************************************/
    } elseif( $date <= "2001-08-31" ) {

        $yearLetters    = array(
            "1963-02-01"    => 'A',    // 1 Feb 1963 – 31 Dec 1963
            "1964-01-01"    => 'B',    // 1 Jan 1964 – 31 Dec 1964
            "1965-01-01"    => 'C',    // 1 Jan 1965 – 31 Dec 1965
            "1966-01-01"    => 'D',    // 1 Jan 1966 – 31 Dec 1966
            "1967-01-01"    => 'E',    // 1 Jan 1967 – 31 Jul 1967
            "1967-08-01"    => 'F',    // 1 Aug 1967 – 31 Jul 1968
            "1968-08-01"    => 'G',    // 1 Aug 1968 – 31 Jul 1969
            "1969-08-01"    => 'H',    // 1 Aug 1969 – 31 Jul 1970
            "1970-08-01"    => 'J',    // 1 Aug 1970 – 31 Jul 1971
            "1971-08-01"    => 'K',    // 1 Aug 1971 – 31 Jul 1972
            "1972-08-01"    => 'L',    // 1 Aug 1972 – 31 Jul 1973
            "1973-08-01"    => 'M',    // 1 Aug 1973 – 31 Jul 1974
            "1974-08-01"    => 'N',    // 1 Aug 1974 – 31 Jul 1975
            "1975-08-01"    => 'P',    // 1 Aug 1975 – 31 Jul 1976
            "1976-08-01"    => 'R',    // 1 Aug 1976 – 31 Jul 1977
            "1977-08-01"    => 'S',    // 1 Aug 1977 – 31 Jul 1978
            "1978-08-01"    => 'T',    // 1 Aug 1978 – 31 Jul 1979
            "1979-08-01"    => 'V',    // 1 Aug 1979 – 31 Jul 1980
            "1980-08-01"    => 'W',    // 1 Aug 1980 – 31 Jul 1981
            "1981-08-01"    => 'X',    // 1 Aug 1981 – 31 Jul 1982
            "1982-08-01"    => 'Y',    // 1 Aug 1982 – 31 Jul 1983
            "1983-08-01"    => 'A',    // 1 Aug 1983 – 31 Jul 1984
            "1984-08-01"    => 'B',    // 1 Aug 1984 – 31 Jul 1985
            "1985-08-01"    => 'C',    // 1 Aug 1985 – 31 Jul 1986
            "1986-08-01"    => 'D',    // 1 Aug 1986 – 31 Jul 1987
            "1987-08-01"    => 'E',    // 1 Aug 1987 – 31 Jul 1988
            "1988-08-01"    => 'F',    // 1 Aug 1988 – 31 Jul 1989
            "1989-08-01"    => 'G',    // 1 Aug 1989 – 31 Jul 1990
            "1990-08-01"    => 'H',    // 1 Aug 1990 – 31 Jul 1991
            "1991-08-01"    => 'J',    // 1 Aug 1991 – 31 Jul 1992
            "1992-08-01"    => 'K',    // 1 Aug 1992 – 31 Jul 1993
            "1993-08-01"    => 'L',    // 1 Aug 1993 – 31 Jul 1994
            "1994-08-01"    => 'M',    // 1 Aug 1994 – 31 Jul 1995
            "1995-08-01"    => 'N',    // 1 Aug 1995 – 31 Jul 1996
            "1996-08-01"    => 'P',    // 1 Aug 1996 – 31 Jul 1997
            "1997-08-01"    => 'R',    // 1 Aug 1997 – 31 Jul 1998
            "1998-08-01"    => 'S',    // 1 Aug 1998 – 28 Feb 1999
            "1999-03-01"    => 'T',    // 1 Mar 1999 – 31 Aug 1999
            "1999-09-01"    => 'V',    // 1 Sep 1999 – 29 Feb 2000
            "2000-03-01"    => 'W',    // 1 Mar 2000 – 31 Aug 2000
            "2000-09-01"    => 'X',    // 1 Sep 2000 – 28 Feb 2001
            "2001-03-01"    => 'Y',    // 1 Mar 2001 – 31 Aug 2001
        );

        // Loop through the letters until we hit a date that's after
        // our registration date
        foreach( $yearLetters as $key => $letter ) {
            $reg    = $letter." (".$year.")";
            if( $key > $date )
                break;
        }

    /* SEPTEMBER 2001 ONWARDS **************************************
     * For registrations since September 2001 use the current
     * 00 - 99 numbering scheme based on the year.
     **************************************************************/
    } else {

        /* CALCULATE THE REG CODE **********************************
         * New style registration years run from the start of March
         * to the end of February of the next year.
         *
         * The two digit year value represents the March - August
         * identifier (i.e. 09, 10) and 50 is added to the year for
         * the September - February identifier (i.e. 59, 60).
         *
         * To calculate the registration code we must follow the
         * steps below:
         *     - YEAR % 50
         *     - if MONTH < 3 subtract 1
         *     - Add 50 if MONTH > 8 or MONTH < 3
         *
         * Giving us:
         * ( YEAR % 50 ) + ( ( MONTH < 3 ) ? 49 : ( MONTH > 8 ) ? 50 : 0 )
         */
        $reg = ( $year % 50 ) +
        		( ( $month < 3 ) ? 49 : ( ( $month > 8 ) ? 50 : 0 ) );
        $reg = str_pad( $reg, 2, "0", STR_PAD_LEFT )." (".$year.")";

    }

    return $reg;
}
</pre>
<p>The <a href="#pretty-uk-vehicle-registration-years" title="View the code">function above</a> should convert all dates since 1963 to codes.  It should also hold true for the future as the current partern is a 50 year repeating one (lest they change it of course).<br />
- Chris</p>
]]></content:encoded>
			<wfw:commentRss>http://chris-miller.org/archives/2010/10/06/pretty-uk-vehicle-registration-years-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Filtered keystrokes with JavaScript</title>
		<link>http://chris-miller.org/archives/2010/04/14/filtered-keystrokes-with-javascript/</link>
		<comments>http://chris-miller.org/archives/2010/04/14/filtered-keystrokes-with-javascript/#comments</comments>
		<pubDate>Wed, 14 Apr 2010 08:36:45 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[form]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[keystroke]]></category>

		<guid isPermaLink="false">http://chris-miller.org/?p=511</guid>
		<description><![CDATA[This small set of scripts should give you a starting point for filtering the valid input to certain form fields to ensure that you shouldn&#8217;t end up with input that you don&#8217;t want*. Basically you&#8217;d have the following javascript functions defined: function isNumber( evt ) { valid = true; if( evt.which &#124;&#124; ( evt.which != [...]]]></description>
			<content:encoded><![CDATA[<p>This small set of scripts should give you a starting point for filtering the valid input to certain form fields to ensure that you shouldn&#8217;t end up with input that you don&#8217;t want*.</p>
<p>Basically you&#8217;d have the following javascript functions defined:</p>
<pre class="javascript" name="code" id="filtered-keystrokes-with-javascript_functions">
function isNumber( evt ) {
	valid		= true;
	if( evt.which || ( evt.which != 0 &#038;&#038; evt.charCode != 0 ) ) {
		var charCode	= ( evt.which ) ? evt.which : event.keyCode;
		if( charCode > 31 &#038;&#038; ( charCode < 48 || charCode > 57 ) ) {
			valid	= false;
		}
	}
	return valid;
}

function isValidEmailCharacter( evt ) {
	valid	= true;
	if( evt.which == null || ( evt.which != 0 &#038;&#038; evt.charCode != 0 ) ) {
		var charCode	= ( evt.which ) ? evt.which : event.keyCode;
		var char		= String.fromCharCode( charCode );
		var re			= new RegExp( /([0-9A-Za-z-_@.])/ );
		valid			= re.test( char );
	}
	return valid;
}

function isValidPhoneCharacter( evt ) {
	valid	= true;
	if( evt.which == null || ( evt.which != 0 &#038;&#038; evt.charCode != 0 ) ) {
		var charCode	= ( evt.which ) ? evt.which : event.keyCode;
		var char		= String.fromCharCode( charCode );
		var re			= new RegExp( /([0-9+\s\[\]])/ );
		valid			= re.test( char );
	}
	return valid;
}
</pre>
<p><span id="more-511"></span>Then we add an <code>onkeypress</code> event to the relevant form fields to filter out any of the keystrokes you don&#8217;t want.  This would look something like:</p>
<pre class="xhtml" name="code" id="filtered-keystrokes-with-javascript_html">
<input
	type="text" name="num"
	onkeypress="return isNumber( event );"
/>
<input
	type="text" name="year" maxlength="4"
	onkeypress="return isNumber( event );"
/>
<input
	type="text" name="email"
	onkeypress="return isValidEmailCharacter( event );"
/>
<input type="text" name="phone" onkeypress="return isValidPhoneCharacter( event );" />
</pre>
<p>The only problem with this method of filtering input to the form elements is that key combos using filtered characters will not work, i.e. <abbr title="Cmd + A">&#8984;+A</abbr> to select the entire entry in a text field will not work when we&#8217;re applying the isNumber filter to that field.  The solution would be to create a list of key combonations that are allowed.</p>
<p>Not a necessity, but it can&#8217;t hurt.<br />
- Chris</p>
<p>* That&#8217;s not to say you shouldn&#8217;t validate the form when it&#8217;s submitted, the non-JavaScript action will be to allow anything.</p>
]]></content:encoded>
			<wfw:commentRss>http://chris-miller.org/archives/2010/04/14/filtered-keystrokes-with-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting and Setting anchors with JavaScript</title>
		<link>http://chris-miller.org/archives/2010/04/09/getting-and-setting-anchors-with-javascript/</link>
		<comments>http://chris-miller.org/archives/2010/04/09/getting-and-setting-anchors-with-javascript/#comments</comments>
		<pubDate>Fri, 09 Apr 2010 10:10:49 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[anchor]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JS]]></category>
		<category><![CDATA[URL]]></category>

		<guid isPermaLink="false">http://chris-miller.org/?p=504</guid>
		<description><![CDATA[Something I&#8217;ve been playing with recently that&#8217;s not very well documented is using JavaScript to retrieve and to update the current page anchor from a URL. It&#8217;s very simple to do. In order to retrieve the page anchor (i.e. get test from http://chris-miller.org/88#test: var anchor = self.document.location.hash.substring( 1 ); Setting the anchor to update, for [...]]]></description>
			<content:encoded><![CDATA[<p>Something I&#8217;ve been playing with recently that&#8217;s not very well documented is using JavaScript to retrieve and to update the current page anchor from a URL.</p>
<p>It&#8217;s very simple to do.  In order to retrieve the page anchor (i.e. get <code>test</code> from http://chris-miller.org/88#test:</p>
<pre class="javascript" name="code" id="getting-and-setting-anchors-with-javascript_get_snippit">
var anchor = self.document.location.hash.substring( 1 );
</pre>
<p>Setting the anchor to update, for example to http://chris-miller.org/88#newAnchor it can be achived using:</p>
<pre class="javascript" name="code" id="getting-and-setting-anchors-with-javascript_set_snippit">
self.document.location.hash = "newAnchor";
</pre>
<p>Very useful for creating permalinks to AJAX loaded content or JS popups.<br />
- Chris</p>
]]></content:encoded>
			<wfw:commentRss>http://chris-miller.org/archives/2010/04/09/getting-and-setting-anchors-with-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fade between two divs using mootools</title>
		<link>http://chris-miller.org/archives/2010/04/08/fade-between-two-divs-using-mootools/</link>
		<comments>http://chris-miller.org/archives/2010/04/08/fade-between-two-divs-using-mootools/#comments</comments>
		<pubDate>Thu, 08 Apr 2010 14:17:05 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[fade]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[mootools]]></category>

		<guid isPermaLink="false">http://chris-miller.org/?p=488</guid>
		<description><![CDATA[I&#8217;ve been playing with mootools for a while, they&#8217;re very nice, making easy work of some nice visual tweens and effects. One thing I was struggling a bit to do was fade between two divs, having the first one fade out then the second fade in. Rather than grabbing a plugin to do it I [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://chris-miller.org/wp-content/uploads/2010/04/mootools.png" alt="MooTools" width="184" height="46" class="alignright size-full wp-image-491" />I&#8217;ve been playing with mootools for a while, they&#8217;re very nice, making easy work of some nice visual tweens and effects.</p>
<p>One thing I was struggling a bit to do was fade between two divs, having the first one fade out then the second fade in.  Rather than grabbing a plugin to do it I wanted a small bit of JavaScript I could embed in a page, I couldn&#8217;t find one <em>anywhere</em>.</p>
<p>It&#8217;s pretty simple to do, the code below should give you a starting point to set up some JS to fade between 2 or more divs.</p>
<pre class="javascript" name="code" id="fade-between-two-divs-using-mootools_snippit">
function fadeBetweenDivs( div1, div2 ) {
	$$( div1 ).fade( "out" );
	(function(){
		$$( div1 ).setStyles({
			display:	'none',
			opacity:	0
		});
	}).delay( 150 );
	(function(){
		$( div2 ).setStyles({
			display:	'block',
			opacity:	0
		});
	}).delay( 150 );
	$$( div2 ).fade( "in" );
}
</pre>
<p>That is all,<br />
- Chris</p>
]]></content:encoded>
			<wfw:commentRss>http://chris-miller.org/archives/2010/04/08/fade-between-two-divs-using-mootools/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Sequel Pro: Manage MySQL Databases under Mac OS X</title>
		<link>http://chris-miller.org/archives/2010/04/08/sequel-pro-manage-mysql-databases-under-mac-os-x/</link>
		<comments>http://chris-miller.org/archives/2010/04/08/sequel-pro-manage-mysql-databases-under-mac-os-x/#comments</comments>
		<pubDate>Thu, 08 Apr 2010 12:27:41 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Essential Apps]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[DBMS]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHPMyAdmin]]></category>
		<category><![CDATA[Sequel Pro]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://chris-miller.org/?p=378</guid>
		<description><![CDATA[I do a lot of web development; it&#8217;s my full time job, my hobby and a means to potentially earn some money on the side. I need a set of good tools in order to make aspects of the work easier or I&#8217;d spend my entire life at odds with what I do. A good [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://chris-miller.org/wp-content/uploads/2010/02/Sequel-Pro-Icon.png" alt="Sequel Pro Icon" title="Sequel Pro Icon" width="105" height="128" class="alignright size-full wp-image-380" /><br />
I do a lot of web development; it&#8217;s my full time job, my hobby and a means to potentially earn some money on the side.  I need a set of good tools in order to make aspects of the work easier or I&#8217;d spend my entire life at odds with what I do.  A good Database Management System (DBMS) tool is one such tool since database management and manipulation plays such a large part of developing any content managed website, especially for quick modifications, testing and deployment.</p>
<p>MySQL is my DB of choice, due to working mainly on <abbr title="Linux, Apache, MySQL and PHP">LAMP</abbr> architecture systems.  The best tool by far I&#8217;ve found for managing MySQL databases under Mac OS X is <a target="_blank" href="http://www.sequelpro.com/" title="View the Sequel Pro website">Sequel Pro</a> (previously CocoaMySQL).</p>
<p><span id="more-378"></span><br />
<div id="sequel-pro-manage-mysql-databases-under-mac-os-x_image1" class="wp-caption aligncenter" style="width: 560px"><img src="http://chris-miller.org/wp-content/uploads/2009/12/Sequel-Pro-Scaled.png" alt="Sequel Pro interface showing the table editor view" title="Sequel-Pro-Scaled" width="550" height="401" class="size-full wp-image-387" /><p class="wp-caption-text">Sequel Pro interface showing the table editor view</p></div><br />
Sequel Pro is a very streamlined and powerful program for database management, it provides the facility to add, modify and remove entire databases; supports various import and export formats for singular tables, entire databases or selected query results; allowing modification of table properties as well as inline SQL querying.</p>
<p>Before finding Sequel Pro I was a full-time user of PHPMyAdmin, a system which I continue to use in some instances.  Sequel Pro essentially provides a desktop solution that is very similar to PHPMyAdmin, anyone who has experience using PHPMyAdmin should have no problems to adjusting to using Sequel Pro in its stead.</p>
<p><div id="sequel-pro-manage-mysql-databases-under-mac-os-x_image2" class="wp-caption aligncenter" style="width: 560px"><img src="http://chris-miller.org/wp-content/uploads/2009/12/Annotated-Sequel-Pro.png" alt="Caption" title="Annotated Sequel Pro" width="550" height="401" class="size-full wp-image-379" /><p class="wp-caption-text">Annotated Sequel Pro</p></div><br />
<a href="#sequel-pro-manage-mysql-databases-under-mac-os-x_image2" title="Sequel Pro Annotated View" onmouseover="document.getElementById('sequel-pro-manage-mysql-databases-under-mac-os-x_image2').style.borderColor = '#2266aa'; document.getElementById('sequel-pro-manage-mysql-databases-under-mac-os-x_image2').style.borderWidth = '2px'; document.getElementById('sequel-pro-manage-mysql-databases-under-mac-os-x_image2').style.paddingTop = '3px'; document.getElementById('sequel-pro-manage-mysql-databases-under-mac-os-x_image2').style.paddingBottom = '0px';" onmouseout="document.getElementById('sequel-pro-manage-mysql-databases-under-mac-os-x_image2').style.borderColor = '#d6d6d6'; document.getElementById('sequel-pro-manage-mysql-databases-under-mac-os-x_image2').style.borderWidth = '1px'; document.getElementById('sequel-pro-manage-mysql-databases-under-mac-os-x_image2').style.paddingTop = '4px'; document.getElementById('sequel-pro-manage-mysql-databases-under-mac-os-x_image2').style.paddingBottom = '1px';">The image above</a> is an annotated view of the Sequel Pro interface, the main portions of the interface that I use day-to-day are highlighted and numbered, each of the numbered areas correspond to:</p>
<ol>
<li>
<h4>Database Selector</h4>
<p>		A basic drop-down list where you can select a database to work with or add a new database.
	</li>
<li>
<h4>Table Selector</h4>
<p>		The list of tables in the currently selected database.  If the number of tables is large enough a filter field appears at the top of this list allowing you to filter the tables based upon their names.  Below the list of tables is a small section with meta-data on the currently selected table, under this is the controls for the database tables.  From here we can add, remove, duplicate and truncate tables with ease (with conformation on the obviously destructive actions).
	</li>
<li>
<h4>Field Viewer/Editor</h4>
<p>		This portion of the interface is controlled by whichever view is selected from the icons appearing in the application toolbar.
	</li>
<li>
<h4>Keys Viewer/Editor</h4>
<p>		This area allows you to manage keys and indexes of the table you&#8217;re viewing.  The +/- toggle at the bottom left allows you to add and remove keys/indexes.
	</li>
<li>
<h4>Structure View (shown)</h4>
<p>		Changes the view to the structure view as shown and detailed above.
	</li>
<li>
<h4>Table Contents View</h4>
<p>		Switches to the table contents view.
	</li>
<li>
<h4>SQL Query Editor</h4>
<p>		Switches to the SQL query editor view.
	</li>
</ol>
<p>Another of the real selling points for Sequel Pro for me is the ability to easily import and export data.  From the <code>File > Export</code> menu you can export data in various formats, <code>CSV</code> and <code>XML</code> being the most useful.<br />
<img src="http://chris-miller.org/wp-content/uploads/2009/12/sequel_pro_export.png" alt="sequel_pro_export" title="sequel_pro_export" width="107" height="28" class="alignright size-full wp-image-382" /></p>
<p><abbr title="Cmd + Shift + I">&#8984;+&#8679;+I</abbr> invokes the import dialog which allows you to select an SQL dump or CSV of values to import into the selected database.  The SQL import will obviously just run the query and update the various tables as required, the CSV import on the other hand allows you to select the table and marry rows in the CSV file to those in the table you wish to import to.</p>
<h3 style="vertical-align: center; line-height: 38px; background-image: url( 'http://chris-miller.org/wp-content/uploads/2009/12/table_structure.png' ); background-repeat: no-repeat; padding-left: 35px;">
	Table Structure<br />
</h3>
<p>As detailed above the table structure view allows you to define the structure of the tables in the database and to set up the indexing and keys for the fields.</p>
<p>A nice touch available here is the ability to reorder pre-existing fields by dragging and dropping them in the relevant places and the ability to duplicate fields rather than have to re-enter details for virtually identical fields.</p>
<h3 style="vertical-align: center; line-height: 38px; background-image: url( 'http://chris-miller.org/wp-content/uploads/2009/12/table_contents.png' ); background-repeat: no-repeat; padding-left: 35px;">
	Table Contents<br />
</h3>
<p>From there you can add, modify, duplicate and delete rows in the table, all of which you&#8217;d really expect from the table contents view.</p>
<p>Again, like the table structure view, you can duplicate entries to save re-entering similar data.  Inserting <code>NULL</code> values is as simple as hitting <abbr title="Ctrl + Shift + N">^+&#8679;+N</abbr>.  Copying rows as INSERT statements is a big plus (<abbr title="Ctrl + Optn + Cmd + C">^+&#8997;+&#8984;+C</abbr>) and useful when copying singular entries between a development and live database, rather than dumping the data from a custom query.</p>
<h3 style="vertical-align: center; line-height: 38px; background-image: url( 'http://chris-miller.org/wp-content/uploads/2009/12/sql_query.png' ); background-repeat: no-repeat; padding-left: 35px;">
	SQL Query<br />
</h3>
<p>This view allows you to enter queries and run them against the database.  The editor itself has autocompletion and some niceties like smart quoting of field names.</p>
<p>The power here comes from the ability to store previously used queries and access recent queries via a query history.  Any of the generated result sets can be exported in the previously mentioned formats for easy data filtering and export.</p>
<h3>
	In summary<br />
</h3>
<p>It&#8217;s a bloody useful tool and a <em>must</em> for anyone working with MySQL databases under Mac OS X.  It&#8217;s not a silver-bullet solution of course; it doesn&#8217;t do much more than PHPMyAdmin and the things it does can be replicated in PHPMyAdmin with relative ease; but then it can&#8217;t be a bad thing to have lying about, especially since it&#8217;s free!</p>
<ul>
<li>You can <a href="http://www.sequelpro.com/" title="Download Sequel Pro">download a copy of Sequel Pro from their website</a>.</li>
<li>Developed by <a href="http://www.mjmedia.com.au/" title="mjmedia">mjmedia</a>.</li>
</ul>
<p>Go have a play with Sequel Pro <em>now</em>,<br />
- Chris</p>
]]></content:encoded>
			<wfw:commentRss>http://chris-miller.org/archives/2010/04/08/sequel-pro-manage-mysql-databases-under-mac-os-x/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Connectivity in Social Media</title>
		<link>http://chris-miller.org/archives/2009/12/17/connectivity-in-social-media/</link>
		<comments>http://chris-miller.org/archives/2009/12/17/connectivity-in-social-media/#comments</comments>
		<pubDate>Thu, 17 Dec 2009 01:31:15 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[delicious]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[flickr]]></category>
		<category><![CDATA[last.fm]]></category>
		<category><![CDATA[linkedin]]></category>
		<category><![CDATA[media]]></category>
		<category><![CDATA[social]]></category>
		<category><![CDATA[Social Media]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://chris-miller.org/?p=391</guid>
		<description><![CDATA[I&#8217;ve been playing around with various social media sites lately, trying to integrate them so my wealth of assorted knowledge gets to as many of the various places as possible. My Twitter feed now updates my Facebook and Linkedin statuses; Last.fm scrobbled tracks appear here in the sidebar and on Facebook; Flickr photos appear here [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been playing around with various social media sites lately, trying to integrate them so my wealth of assorted knowledge gets to as many of the various places as possible.  My Twitter feed now updates my Facebook and Linkedin statuses; Last.fm scrobbled tracks appear here in the sidebar and on Facebook; Flickr photos appear here as well as on Facebook.</p>
<p>This got me to thinking about the types of people I connect to on each of these social media networking sites.  In my eyes this blog serves a different purpose and has a separate target audience to my Linkedin or Facebook profiles.</p>
<p>In light of this I&#8217;m giving a rundown of the groups and categories of people I connect to via each of these sites and their envisioned usage in my eyes.</p>
<p><span id="more-391"></span><br />
<h3>
<a target="_blank" href="/" title="Blog">Blog</a><br />
</h3>
<p><img src="http://chris-miller.org/wp-content/uploads/2009/12/blog-128x128.png" alt="Blog" title="Blog" width="128" height="128" class="alignright size-full wp-image-406" />The hub of this particular Chris Miller on the web.  It&#8217;s where you&#8217;ll be able to find out about who I am and what I&#8217;m up to.  From here you can branch out onto each of the social media sites I&#8217;m to be found on where more information in each of their specific focuses can be found.</p>
<p>Although technically not a <em>social</em> site it does mark the start of a web of profiles on various other sites as well as providing a blogroll (which is terminally out of date) of other people and sites I follow on the web.</p>
<ul>
<li>My blog is for: me to post random nonsense and technical articles to.</li>
<li>My blog connects me to: other sites I syndicate.</li>
</ul>
<h3>
<a target="_blank" href="http://delicious.com/chrismiller" title="Delicious">Delicious</a><br />
</h3>
<p><img src="http://chris-miller.org/wp-content/uploads/2009/12/delicious-128x128.png" alt="Delicious" title="Delicious" width="128" height="128" class="alignright size-full wp-image-406" />I&#8217;m terrible at using Delicious for bookmarking as well as bookmarking things locally.  I tend to read an article that&#8217;s relevant to the thoughts running around my head at a particular moment then move on, forever forgetting said article (much trolling of web history ensues at a later date).</p>
<p>Although this site allows connections to other people I&#8217;ve shunned away from doing so.  Feeds from the likes of Reddit and the BBC combined with Twitter tends to keep me up to date with any relevant articles flying around.</p>
<ul>
<li>Delicious is for: posting links to interesting/relevant/funny articles and categorising/tagging them.</li>
<li>Delicious connects me to: nobody at the moment.</li>
</ul>
<h3>
<a target="_blank" href="http://www.facebook.com/christopheralexandermiller" title="Facebook">Facebook</a><br />
</h3>
<p><img src="http://chris-miller.org/wp-content/uploads/2009/12/facebook-128x128.png" alt="Facebook" title="Facebook" width="128" height="128" class="alignright size-full wp-image-406" />Facebook is the only site in this list that I&#8217;d truly describe as a <em>social media site</em>.  By this I mean that it serves no other purpose than to be a platform to connect and keep-in-touch with people I know socially.  All the other sites in this list are quite focused in their purpose.</p>
<p>In light of this, Facebook is where most of the connecting comes into play for me.  I have friends on Facebook from various facets of my life: school, university, work and other social situations.  The one thing that sets Facebook apart from most of these other sites is that anyone I am friends with I have actually met, interacted with and have subsequently added as a friend.</p>
<p>The site itself is easy to use, little or no expertise is required to set up an account and start connecting with friends.  There are various &#8216;applications&#8217; to be added, groups to be joined, photos to be looked at&#8230; essentially it&#8217;s a procrastinators wet dream.  This of course means it has no real focus or goal for me other than being stayintouchwithpeople.com.</p>
<ul>
<li>Facebook is for: everyone! Staying in contact with people I know socially.</li>
<li>Facebook connects me to: pretty much everyone I know personally.</li>
</ul>
<h3>
<a target="_blank" href="http://flickr.com/photos/chrismiller" title="Flickr">Flickr</a><br />
</h3>
<p><img src="http://chris-miller.org/wp-content/uploads/2009/12/flickr-128x128.png" alt="Flickr" title="Flickr" width="128" height="128" class="alignright size-full wp-image-406" />Flickr, certainly for me, started out as a tool for online photo storage and organisation.  I jumped on Flickr not long after it started up, before those pesky Yahoo! logins, and a tool was certainly what I was using it solely for.</p>
<p>Over time as the site developed and the whole social media <em>thing</em> took off Flickr added some nice functionality for discovering other people and building a photography community.</p>
<p>Connections I have via Flickr tend to be people I know with a smattering of people who have some interesting photos up.  For the most part I find Flickr a useful tool for distributing photos onto other social media sites and it serves as an online repository of all my photos.  That said however, it does make it very easy to keep up-to-date with photos of peers and colleagues who have a ton more photography skill than I (particularly <a target="_blank" href="http://www.flickr.com/photos/chrishannah/">Chris Hannah</a>, <a target="_blank" href="http://www.flickr.com/photos/filtre/">Jim Moore</a>, <a target="_blank" href="http://www.flickr.com/photos/sdstrowes/">Steve Strowes</a> and <a target="_blank" href="http://www.flickr.com/photos/deanwright/">Dean Wright</a> being of note).</p>
<ul>
<li>Flickr is for: hosting, organising and sharing my photos online.</li>
<li>Flickr connects me to: people I know and other Flickr users with interesting posts.</li>
</ul>
<h3>
<a target="_blank" href="http://www.last.fm/user/chrismiller" title="Last.fm">Last.fm</a><br />
</h3>
<p><img src="http://chris-miller.org/wp-content/uploads/2009/12/lastfm-128x128.png" alt="Last.fm" title="Last.fm" width="128" height="128" class="alignright size-full wp-image-406" />I think I initially signed up to Last.fm just to see what it was, what it offered and to see if it&#8217;d be useful.  Since then I&#8217;ve been off and on using the service to capture the tracks I&#8217;ve been listening to with iTunes.  That is until recently with the switch for most of my music listening to Spotify which offers integrated Last.fm scrobbling.</p>
<p>The stats over time from tracks you&#8217;ve listened to are interesting and the music recommendations can be good especially if, like me, you generally don&#8217;t listen to music that&#8217;s very recent.  I tend to view this more like I did Flickr initially, as a tool to draw information into other social media sites.  That being said, I do have friends added on the site.  The friends I have added tend to be actual friends I know and have somewhat similar music tastes to.</p>
<ul>
<li>Last.fm is for: collecting information about my music listening trends and sharing them on other sites.</li>
<li>Last.fm connects me to: friends I know with similar music tastes.</li>
</ul>
<h3>
<a target="_blank" href="http://uk.linkedin.com/in/camiller" title="Linkedin">Linkedin</a><br />
</h3>
<p><img src="http://chris-miller.org/wp-content/uploads/2009/12/linkedin-128x128.png" alt="Linkedin" title="Linkedin" width="128" height="128" class="alignright size-full wp-image-406" />By far the most professionally oriented of any of the sites listed here and again on my part initially used as a tool rather than a networking site.  Linkedin for me initially was a convenient way of creating an online, plain and simple CV which could be easily updated and seed any full written CVs I&#8217;d need to write.</p>
<p>The focus of this site has shifted quite dramatically for me over time, I view this site as more of a networking site than I did previously.  Now it provides a forum for me to stay contacted with people I&#8217;ve worked and studied with, without as many social faux pas such like drunken photographs or questionable music tastes.  Ok they&#8217;re not hard to find, but the site does provide a professional front for me.</p>
<p>As I&#8217;ve said above, the people I connect with on Linkedin are those I&#8217;ve previously worked and studied with, aside from a few recruitment agencies who try and cram job offers down your throat (can&#8217;t hurt can it?).</p>
<ul>
<li>Linkedin is for: providing a professional front.</li>
<li>Linkedin connects me to: those people who have had the privilege of working or studying with me.</li>
</ul>
<h3>
<a target="_blank" href="http://twitter.com/chrismiller" title="Twitter">Twitter</a><br />
</h3>
<p><img src="http://chris-miller.org/wp-content/uploads/2009/12/twitter-128x128.png" alt="Twitter" title="Twitter" width="128" height="128" class="alignright size-full wp-image-406" />Twitter in my eyes is by far the most loosely defined group of people I follow.  I view Twitter as a pick-it-up put-it-down source of random pieces of information, friend status updates and broadcasts from various companies.</p>
<p>My follow list generally reflects this.  I follow people I know as a means of staying up-to-date with them; companies whose services I use as well as updates on various pieces of software I utilise on a daily basis; and pretty much anyone who posts something interesting or funny.  So the list of Twitter updates I see in my client varies between lunch orders, company/software bulletins, 160 character quips and interesting links.</p>
<p>Twitter is by far the social media service that I read and post to most often, though I tend to skim over a lot of tweets to find those that are relevant or interesting to me.</p>
<ul>
<li>Twitter is for: quickly posting interesting links, thoughts, lazy discussions, product updates&#8230; disseminating information.</li>
<li>Twitter connects me to: absolutely anyone, friends are a given but other than that, anything that interests me.</li>
</ul>
<p>So that&#8217;s my rundown of the social media sites you&#8217;ll see me on and my usage of and connectivity on them.  I&#8217;d assume most people use each of these sites in a similar manner (barring Twitter which has various marketing and advertising uses that I&#8217;m not really clued up on).  Any other uses or different perspectives are welcomed.<br />
- Chris</p>
]]></content:encoded>
			<wfw:commentRss>http://chris-miller.org/archives/2009/12/17/connectivity-in-social-media/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Batch renaming files in Mac OS X</title>
		<link>http://chris-miller.org/archives/2009/12/08/batch-renaming-files-in-mac-os-x/</link>
		<comments>http://chris-miller.org/archives/2009/12/08/batch-renaming-files-in-mac-os-x/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 20:02:12 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Essential Apps]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Finder]]></category>
		<category><![CDATA[NameChanger]]></category>
		<category><![CDATA[rename]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[spotlight]]></category>

		<guid isPermaLink="false">http://chris-miller.org/?p=349</guid>
		<description><![CDATA[The Finder is brilliant. It does exactly what it says on the tin. You can zoom around your filesystem and find things with relative ease; copy, cut, paste and move files. It does it all, but it lacks any batch renaming to help any of us who have the laborious task of renaming dozens, or [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://chris-miller.org/wp-content/uploads/2009/12/NameChangerIcon-150x150.png" alt="NameChanger" title="NameChanger" width="150" height="150" class="alignright size-thumbnail wp-image-350" />The Finder is brilliant.  It does exactly what it says on the tin.  You can zoom around your filesystem and find things with relative ease; copy, cut, paste and move files.  It does it all, but it lacks any batch renaming to help any of us who have the laborious task of renaming dozens, or worse, hundreds of files.</p>
<p>That&#8217;s where <a href="http://www.mrrsoftware.com/MRRSoftware/NameChanger.html" title="NameChanger">NameChanger</a> comes in.  NameChanger is a piece of free software from <a href="http://www.mrrsoftware.com/MRRSoftware/Home.html">MRR Software</a>.  Basically it allows you to rename large batches of files with some simple pattern matching.</p>
<p><span id="more-349"></span><div id="batch-renaming-files-in-mac-os-x_image1" class="wp-caption aligncenter" style="width: 560px"><img src="http://chris-miller.org/wp-content/uploads/2009/12/NameChanger.png" alt="Changing the names of some videos" title="NameChanger in use" width="550 height="327" class="size-full wp-image-352" /><p class="wp-caption-text">Changing the names of some videos</p></div></p>
<p>It&#8217;s all pretty simple really:</p>
<ol>
<li>drag the target files into the application window</li>
<li>select the type of name matching you require from: replace first, replace last, replace all, replace wildcard, append, prepend, sequencing and date-stamping</li>
<li>enter your criteria, <a href="#batch-renaming-files-in-mac-os-x_image1" title="My shopping" onmouseover="document.getElementById('batch-renaming-files-in-mac-os-x_image1').style.borderColor = '#2266aa';" onmouseout="document.getElementById('batch-renaming-files-in-mac-os-x_image1').style.borderColor = '#d6d6d6';">above I&#8217;ve replaced the first occurrence of &#8216;.&#8217; with &#8216;&nbsp;-&nbsp;&#8217;</a></li>
<li>hit the &#8216;Rename&#8217; button and you&#8217;re done</li>
</ol>
<h3>Grab a copy</h3>
<p>Here&#8217;s the blurb</p>
<blockquote><p>
NameChanger<br />
Rename a list of files quickly and easily.<br />
See how the names will change as you type.
</p></blockquote>
<ul>
<li><a href="http://www.mrrsoftware.com/">the developer&#8217;s site</a></li>
<li><a href="http://www.mrrsoftware.com/MRRSoftware/NameChanger.html">NameChanger download page</a></li>
</ul>
<p>Good bit of software.  Simple, free, intuitive; all in all, a keeper.<br />
- Chris</p>
]]></content:encoded>
			<wfw:commentRss>http://chris-miller.org/archives/2009/12/08/batch-renaming-files-in-mac-os-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Shopping++</title>
		<link>http://chris-miller.org/archives/2009/10/02/shopping/</link>
		<comments>http://chris-miller.org/archives/2009/10/02/shopping/#comments</comments>
		<pubDate>Fri, 02 Oct 2009 13:08:33 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Personal]]></category>
		<category><![CDATA[delivery]]></category>
		<category><![CDATA[fajitas]]></category>
		<category><![CDATA[food]]></category>
		<category><![CDATA[sainsbury's]]></category>
		<category><![CDATA[Tesco]]></category>

		<guid isPermaLink="false">http://chris-miller.org/?p=305</guid>
		<description><![CDATA[I&#8217;ve not posted in ages. Sorry. Just a quick post to say that I&#8217;m very impressed with the Sainsbury&#8217;s delivery service and web store, much more than the Tesco equivalent. I got over £100 worth of groceries delivered within the one hour slot I picked, not the 2-3 hour slots that Tesco use, and everything [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve not posted in ages. Sorry.</p>
<p><div id="shopping_image1" class="wp-caption alignright" style="width: 250px"><a href="http://chris-miller.org/photos/photo/3973729793/shopping.html" title="Shopping++"><img alt="Image 1: Shopping++" src="http://farm4.static.flickr.com/3441/3973729793_c7c81782b6_m.jpg" title="Shopping++" width="240" height="180" /></a><p class="wp-caption-text">Shopping++</p></div>Just a quick post to say that I&#8217;m very impressed with the <a href="http://sainsburys.co.uk">Sainsbury&#8217;s</a> delivery service and web store, much more than the Tesco equivalent.</p>
<p>I got over £100 worth of groceries delivered within the one hour slot I picked, not the 2-3 hour slots that Tesco use, and everything was there, good quality and undamaged.</p>
<p>Not only that but having purchased over <a href="#shopping_image1" title="My shopping" onmouseover="document.getElementById('shopping_image1').style.borderColor = '#2266aa';" onmouseout="document.getElementById('shopping_image1').style.borderColor = '#d6d6d6';">£100 worth of shopping</a> the delivery cost is waived.  So I managed to get a month worth of food and drink without the hassle of going shopping and somehow carting everything back.</p>
<p><span id="more-305"></span><div id="shopping_image2" class="wp-caption alignleft" style="width: 250px"><a href="http://chris-miller.org/photos/photo/3973730311/spicy-fajitas.html" title="Spicy Fajitas"><img alt="Image 2: Spicy Fajitas" src="http://farm3.static.flickr.com/2609/3973730311_f4cb555418_m.jpg" title="Spicy Fajitas" width="240" height="180" /></a><p class="wp-caption-text">Spicy Fajitas</p></div>Everything comes in an orange Sainsbury&#8217;s bag, except anything that&#8217;s been substituted (with the closest match due to lack of stock) which came in blue bags.  The delivery person offered to take any of the substitutions back and my account would be credited with the relevant cost if he did.</p>
<p>My cupboards, fridge and freezer and completely and utterly stocked to the brim, there&#8217;s no room for <em>anything</em> else, at all! Now I&#8217;ve just got to <a href="#shopping_image2" title="FOOD!" onmouseover="document.getElementById('shopping_image2').style.borderColor = '#2266aa';" onmouseout="document.getElementById('shopping_image2').style.borderColor = '#d6d6d6';">eat it all</a>.</p>
<p>All in all, an easy and hassle free transaction.  Qudos to Sainsbury&#8217;s, A+++++ GOOD SELLER, WOULD SHOP AGAIN.<br />
- Chris</p>
]]></content:encoded>
			<wfw:commentRss>http://chris-miller.org/archives/2009/10/02/shopping/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScript custom controls</title>
		<link>http://chris-miller.org/archives/2009/02/15/javascript-custom-controls/</link>
		<comments>http://chris-miller.org/archives/2009/02/15/javascript-custom-controls/#comments</comments>
		<pubDate>Sun, 15 Feb 2009 20:19:57 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[HCI]]></category>
		<category><![CDATA[custom controls]]></category>
		<category><![CDATA[interaction]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[ui]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://chris-miller.org/?p=185</guid>
		<description><![CDATA[I spend a lot of time writing bespoke content management systems, a lot! I&#8217;m always trying to add some small, lightweight additions to make the user experience a little bit better. One means of doing this is by providing some better custom controls which give good user feedback and emulate similar offline controls. One such [...]]]></description>
			<content:encoded><![CDATA[<p>I spend a lot of time writing bespoke content management systems, a lot!  I&#8217;m always trying to add some small, lightweight additions to make the user experience a little bit better.  One means of doing this is by providing some better custom controls which give good user feedback and emulate similar offline controls.</p>
<p><div id="javascript-custom-controls_figure1" class="wp-caption alignright" style="width: 185px"><img alt="Figure 1: Ordering Control" src="http://chris-miller.org/images/ordering_field.png" title="Ordering Control" width="175" height="26" /><p class="wp-caption-text"><strong>Figure 1</strong>: Ordering Control</p></div>One such control is a linear range control, catchy I know, which allows the user to select a value within a particular range with a given default value.  An example of this may be selecting an ordering value for a blog post, <a href="#javascript-custom-controls_figure1" title="Ordering Control" onmouseover="document.getElementById('javascript-custom-controls_figure1').style.borderColor = '#2266aa';" onmouseout="document.getElementById('javascript-custom-controls_figure1').style.borderColor = '#d6d6d6';">Figure 1</a>, ranging from say -100 to 100 with a default value of 0.  Posts in our imaginary blog would be ordered by this ordering field ascending with 0 being the default value, resulting in posts being ordered automatically by date.  Rather than using a plain text box to allow the user to enter the ordering value directly, subsequently giving us little or no control over the contents of the field until the form is submitted and no means to convey the nature of the field itself, we can create controls to manipulate the value ourselves.</p>
<p>Creating a custom control allows us to do a number of things that we just cannot do with a normal HTML form element:<br />
<div id="javascript-custom-controls_figures234" class="wp-caption alignright" style="width: 185px"><img id="javascript-custom-controls_figure2" alt="Figure 2: Lower Bounds" src="http://chris-miller.org/images/ordering_field_lower.png" title="Lower Bounds" width="175" height="26" /> <img id="javascript-custom-controls_figure3" alt="Figure 3: Non-Default Value" src="http://chris-miller.org/images/ordering_field_middle.png" title="Non-Default Value" width="175" height="26" /> <img id="javascript-custom-controls_figure4" alt="Figure 4: Upper Bounds" src="http://chris-miller.org/images/ordering_field_upper.png" title="Upper Bounds" width="175" height="26" /><p class="wp-caption-text"><strong>Figures 2, 3 &amp; 4</strong>: Showing lower bounds, non-default value and upper bounds</p></div></p>
<ul>
<li>Display relevant information instead of certain values, such as showing Automatic at 0 in <a href="#javascript-custom-controls_figure1" title="Ordering Control" onmouseover="document.getElementById('javascript-custom-controls_figure1').style.borderColor = '#2266aa';" onmouseout="document.getElementById('javascript-custom-controls_figure1').style.borderColor = '#d6d6d6';">Figure 1</a></li>
<li>Show when the upper and lower bounds are reached, for example at <a href="#javascript-custom-controls_figure2" title="Lower Limit" onmouseover="document.getElementById('javascript-custom-controls_figures234').style.borderColor = '#2266aa';" onmouseout="document.getElementById('javascript-custom-controls_figures234').style.borderColor = '#d6d6d6';">-100</a> and <a href="#javascript-custom-controls_figure4" title="Upper Limit" onmouseover="document.getElementById('javascript-custom-controls_figures234').style.borderColor = '#2266aa';" onmouseout="document.getElementById('javascript-custom-controls_figures234').style.borderColor = '#d6d6d6';">100</a> as per our example</li>
<li>Allow the user to reset the value to the default or previous setting</li>
<li>Give some inkling into how the control should be used</li>
</ul>
<p><span id="more-185"></span><br />
<h3>Controls</h3>
<p><div class="wp-caption alignright" style="width: 323px"><img alt="Annotated Ordering Field" src="http://chris-miller.org/images/ordering_field_annotated.png" title="Annotated Ordering Field" width="313" height="63" /><p class="wp-caption-text"><strong>Figure 5</strong>: Annotated Ordering Field</p></div>By using JavaScript <code>onclick</code> or <code>onmousedown</code> events we can manipulate the contents of our ordering field held behind the scenes.  The addition of functions and some variables defining the bounds and the default value of our control then allows us to constrain the upper and lower limits, as we&#8217;ve seen, and to reset the field back to it&#8217;s defaults.  This gives us the following interaction:</p>
<ul>
<li>Previous/Next: update the value of the field to the previous or next value in the range</li>
<li>Reset: reset the value to the pre-defined default value</li>
<li>Display: allow us to display feedback or custom messages based on the value of the field we&#8217;re manipulating</li>
</ul>
<p>This interaction is fairly rudimentary and not very exciting to say the least.  We really want to provide more desktop-like interaction via our own custom controls such as the ability to click-and-hold a button in order to scroll through available values.  With such a control, in the majority of desktop applications, when the button is held the action that button denotes will be repeated after a short delay usually with increasing speed the longer it&#8217;s held.  We can emulate this in JavaScript using a timeout to create the pause and a modifier to decrease the length of this pause and in turn increase the speed with which the actions are executed.</p>
<p><a href="#javascript-custom-controls_snippit1" onmouseover="document.getElementById('javascript-custom-controls_snippit1').style.borderColor = '#2266aa';" onmouseout="document.getElementById('javascript-custom-controls_snippit1').style.borderColor = '#d6d6d6';" title="Click-and-hold example">Code Snippit 1</a> contains a brief outline of how to create a mechanism for firing events when a button is held.</p>
<div class="code_header">
<p>
<strong>Code Snippit 1</strong>: Rough JavaScript to deal with the click-and-hold updating mechanism
</p>
<pre class="javascript" name="code" id="javascript-custom-controls_snippit1" >
&lt;script type="text/javascript"&gt;
    var timeout          = 1000;
    var timeout_limit    = 200;
    var timeout_speedup  = 1.5;
    var default          = 0;
    var lower_bounds     = -100;
    var upper_bounds     = 100;

    function setView( str, element ) {
        // Update the ordering element setting the values and
        // icons as necessary
      ...
    }

    function updateVariable() {
        // Update variable
        order        = document.getElementById( "ordering" );
        order_disp   = document.getElementById( "order_disp" );

        // Update variable
        order.value  = order.value + 1;

        // Check Bounds
        if( order.value &gt;= upper_bounds )
            setView( "upper_bounds", order_disp );
        elseif( order.value == default )
            setView( "Default", order_disp );
        else
            setView( "" + order.value, order_disp );

        // Start firing click-and-hold events
        if( timeout &gt; timeout_limit )
            timeout = max( timeout / timeout_speedup, timeout_limit );
        t = setTimeout( updateVariable, timeout );
    }

    function buttonStop( t ) {
        timeout = 1000;
        clearTimeout( t );
    }
&lt;/script&gt;
</pre>
</div>
<p><code>timeout</code> is the time between calling button events, the <code>timeout_speedup</code> modifier is used to recalculate the timeout on each event in order to increase the speed with which the event is fired.  We set a lower limit, <code>timeout_limit</code>, to ensure that the events aren&#8217;t called too quickly to update the display and to give the user time to react once they near their desired value.  A plot of time between ticks against ticks is shown in <a href="#javascript-custom-controls_graph1" onmouseover="document.getElementById('javascript-custom-controls_graph1').style.borderColor = '#2266aa';" onmouseout="document.getElementById('javascript-custom-controls_graph1').style.borderColor = '#d6d6d6';" title="Time between ticks vs. Ticks">Graph 1</a>, as you can see it quickly ramps up so <code>timeout</code> is set to the lower limit, much like you would expect from a desktop application&#8217;s click-and-hold button interaction.</p>
<div id="javascript-custom-controls_graph1" class="wp-caption aligncenter" style="width: 551px"><img alt="Timeout vs. Ticks" src="http://chris-miller.org/images/timeout_graph.png" title="Timeout vs. Ticks" width="541" height="250" /><p class="wp-caption-text"><strong>Graph 1</strong>: Timeout vs. Ticks</p></div>
<p><a href="#javascript-custom-controls_snippit2" onmouseover="document.getElementById('javascript-custom-controls_snippit2').style.borderColor = '#2266aa';" onmouseout="document.getElementById('javascript-custom-controls_snippit2').style.borderColor = '#d6d6d6';" title="HTML button">Code Snippit 2</a> shows sample HTML used to create the next button with the appropriate <code>onmousedown</code>, <code>onmouseup</code> and <code>onmouseout</code> JavaScript calls to add the desired functionality to the button.</p>
<div id="javascript-custom-controls_snippit2" class="code_header">
<p>
<strong>Code Snippit 2</strong>: Button calling the events when clicked
</p>
<pre class="html" name="code">
&lt;img
    title="Next" src="images/icons/arrow_right.png" alt="&amp;rarr;"
    <!-- Update the variable and fire click-and-hold events -->
    onmousedown="updateVariable();"
    <!-- Stop the timer if mouse released -->
    onmouseup="buttonStop( t );"
    <!-- Stop the timer if the mouse moves off the control -->
    onmouseout="buttonStop( t );"
/&gt;
</pre>
</div>
<p>We use both <code>onmouseup</code> and <code>onmouseout</code> to ensure that the click-and-hold behavior ceases when the user either releases the mouse button or moves the cursor off the control.</p>
<p><div id="javascript-custom-controls_figure6" class="wp-caption alignright" style="width: 185px"><img alt="Textentry into ordering field" src="http://chris-miller.org/images/ordering_field_textentry.png" title="Textentry into ordering field" width="175" height="36" /><p class="wp-caption-text"><strong>Figure 6</strong>: Textentry into ordering field</p></div>We can extend the custom control even further and give the user a less stringent method of inputting a value by allowing them to type directly into the field in the same manner as the original textbox, <a href="#javascript-custom-controls_figure6" title="Textentry into ordering field" onmouseover="document.getElementById('javascript-custom-controls_figure6').style.borderColor = '#2266aa';" onmouseout="document.getElementById('javascript-custom-controls_figure6').style.borderColor = '#d6d6d6';">Figure 6</a>.</p>
<h3>Feedback</h3>
<p>Here&#8217;s where our custom controls can really begin to shine, we can give the user direct feedback in the control that they&#8217;re manipulating in real-time.  Sure we can do this with JavaScript as it stands, but extending beyond the &#8220;red border = wrong&#8221; methodology we can give visual cues to the user to show that they&#8217;re trying to do something thata&#8217;s wrong and what specifically is wrong with what they&#8217;re doing.</p>
<p>Showing the bounds of the field is easy using the visual cues we&#8217;ve detailed in <a href="#javascript-custom-controls_figures234" title="Upper Limit" onmouseover="document.getElementById('javascript-custom-controls_figures234').style.borderColor = '#2266aa';" onmouseout="document.getElementById('javascript-custom-controls_figures234').style.borderColor = '#d6d6d6';">Figures 2 &#038; 4</a>.  Other visual cues we can use are that of text/background colouring to show that an error occurred.  We can also, using the same timeout methods used for the click-and-hold interaction, display <em>useful</em> messages to the user for a brief time before correcting their mistakes telling them what they did wrong and why their entries have been changed, <a href="#javascript-custom-controls_figure7" title="Error detection and correction" onmouseover="document.getElementById('javascript-custom-controls_figure7').style.borderColor = '#2266aa';" onmouseout="document.getElementById('javascript-custom-controls_figure7').style.borderColor = '#d6d6d6';">Figure 7</a>.</p>
<div id="javascript-custom-controls_figure7" class="wp-caption alignright" style="width: 573px"><img alt="Error detection and correction" src="http://chris-miller.org/images/ordering_field_errorcorrection.png" title="Error detection and correction" width="563" height="36" /><p class="wp-caption-text"><strong>Figure 7</strong>: Error detection and correction</p></div>
<h3 style="margin-top: 10px;">It&#8217;s only an example!</h3>
<p><div class="wp-caption alignright" style="width: 319px"><img alt="Other possible controls?" src="http://chris-miller.org/images/controls_other.png" title="Other possible controls?" width="309" height="59" /><p class="wp-caption-text"><strong>Figure 8</strong>: Other possible controls?</p></div>Of course using such controls for an ordering field is only one example where we can extend upon HTML form elements with this simple control.  This type of control mechanism could be used for <em>any</em> field that has a linear progression in values.  Not only that, you could extend upon the functionality of this example to meet your specific requirements, by wrapping the bounds around to the start, having varying degrees of scale over numerous controls that are swapped in and out for fine or granular interaction or just have it toggle between two set values.</p>
<p>What&#8217;s the point?  There&#8217;s so much we can do nowadays in terms of interaction, even on the web.  Try to add a little bit of interactive zest to your HTML controls, it makes everyone&#8217;s experience that little bit easier and better.</p>
<p>Thanks for reading,<br />
- Chris</p>
]]></content:encoded>
			<wfw:commentRss>http://chris-miller.org/archives/2009/02/15/javascript-custom-controls/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New blog theme &#8211; Plainscape</title>
		<link>http://chris-miller.org/archives/2009/02/15/new-blog-theme-plainscap/</link>
		<comments>http://chris-miller.org/archives/2009/02/15/new-blog-theme-plainscap/#comments</comments>
		<pubDate>Sun, 15 Feb 2009 03:04:34 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Blogging]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[plainscape]]></category>
		<category><![CDATA[simple]]></category>
		<category><![CDATA[theme]]></category>
		<category><![CDATA[white]]></category>

		<guid isPermaLink="false">http://chris-miller.org/?p=189</guid>
		<description><![CDATA[I&#8217;ve not blogged in a while, although I have been playing with this site, testing various themes that&#8217;re out there on the web. I tried numerous dark and light varieties, some heavy on design others not so much, many of the image heavy themes looked nice initially but lacked that overall niceness. I had finally [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://chris-miller.org/photos/photo/3279673379/plainscape.html" class="tt-flickr tt-flickr-Small" title="Plainscape"><img class="alignright" src="http://farm4.static.flickr.com/3170/3279673379_feaf7cfc66_m.jpg" alt="Plainscape" width="240" height="202" /></a>I&#8217;ve not blogged in a while, although I have been playing with this site, testing various themes that&#8217;re out there on the web.  I tried numerous dark and light varieties, some heavy on design others not so much, many of the image heavy themes looked nice initially but lacked that overall niceness.  I had finally settled on <a href="http://wordpress.org/extend/themes/inove">iNove</a> but I&#8217;ve since decided that it was too cluttered.  Short of making my own theme up, which I never manage to get all the way through, I thought it best to find a nice clean one on the web.</p>
<p>After hours of painful searching this evening I managed to decided upon using the <a href="http://srinig.com/wordpress/themes/plainscape/">Plainscape</a> theme.  I may well configure it slightly for this blog, I may even go as far as to add a header image, but let&#8217;s not get too adventurous!</p>
<p>So for the foreseeable future this blog will look nice, plain and simple (it&#8217;ll probably change when I get bored but it gives me something to blog about!).<br />
- Chris</p>
]]></content:encoded>
			<wfw:commentRss>http://chris-miller.org/archives/2009/02/15/new-blog-theme-plainscap/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Get multi-class elements in JavaScript</title>
		<link>http://chris-miller.org/archives/2008/10/02/get-multi-class-elements-in-javascript/</link>
		<comments>http://chris-miller.org/archives/2008/10/02/get-multi-class-elements-in-javascript/#comments</comments>
		<pubDate>Thu, 02 Oct 2008 20:35:49 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Computing]]></category>
		<category><![CDATA[class]]></category>
		<category><![CDATA[getElementsByClass]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[multi-class elements]]></category>
		<category><![CDATA[XHTML]]></category>

		<guid isPermaLink="false">http://chris-miller.org/?p=184</guid>
		<description><![CDATA[As any person who uses JavaScript for client side interaction knows, getting elements by their class is one essential thing we need to do over and over again. For the most part using a function equivalent to the one shown below will do. Code Snippit 1: Simplistic getElementsByClass() JavaScript method function getElementsByClass( className ) { [...]]]></description>
			<content:encoded><![CDATA[<p>As any person who uses JavaScript for client side interaction knows, getting elements by their class is one essential thing we need to do over and over again.  For the most part using a function equivalent to the one <a href="#get-multi-class-elements-in-javascript_snippit1" title="Simple getElementsByClass()" onmouseover="document.getElementById('get-multi-class-elements-in-javascript_snippit1).style.borderColor = '#2266aa';" onmouseout="document.getElementById('get-multi-class-elements-in-javascript_snippit1').style.borderColor = '#d6d6d6';">shown below</a> will do.</p>
<div id="get-multi-class-elements-in-javascript_snippit1" class="code_header">
<p>
<strong>Code Snippit 1</strong>: Simplistic getElementsByClass() JavaScript method
</p>
<pre class="javascript" name="code">
function getElementsByClass( className ) {
    var all =
        document.all ? document.all : document.getElementsByTagName( '*' );
    var elements = new Array();
    for( var e = 0; e < all.length; e++ ) {
        if (all[e].className == className) {
            elements[elements.length] = all[e];
        }
    }
    return elements;
}
</pre>
</div>
<p>This function basically checks the string that is entered into the class attribute for each HTML element and returns all elements where there is an exact match.</p>
<p>This method will fail however if we're trying to select elements that have multiple class associations.  We need to use something more complex when, for example, creating a list of items that are filterable by class when arranged in overlapping groups.  Splitting the class attribute on space characters will allow us to check for matches in these cases:</p>
<div id="get-multi-class-elements-in-javascript_snippit2" class="code_header">
<p>
<strong>Code Snippit 2</strong>: More advanced getElementsByClass() function
</p>
<pre class="javascript" name="code">
function getElementsByClass( className ) {
    var all =
        document.all ? document.all : document.getElementsByTagName( '*' );
    var elements = new Array();
    for( var e = 0; e < all.length; e++ ) {
        var classes = all[e].className.split(/\s/g);
        for( var c = 0; c < classes.length; c++ ) {
            if( classes == className ) {
                elements[elements.length] = all[e];
            }
        }
    }
    return elements;
}
</pre>
</div>
<p>The <a href="#get-multi-class-elements-in-javascript_snippit2" title="Advanced getElementsByClass()" onmouseover="document.getElementById('get-multi-class-elements-in-javascript_snippit2).style.borderColor = '#2266aa';" onmouseout="document.getElementById('get-multi-class-elements-in-javascript_snippit2').style.borderColor = '#d6d6d6';">function above</a> does pretty much the same as the first one, however splits the class attribute string on the spaces and loops through them, trying to match the parts individually.  This should match on elements with singular and multiple class names associated with them and solve any problems with multiple classed elements.<br />
- Chris</pre>
]]></content:encoded>
			<wfw:commentRss>http://chris-miller.org/archives/2008/10/02/get-multi-class-elements-in-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Suse Tips</title>
		<link>http://chris-miller.org/archives/2008/07/01/suse-tips/</link>
		<comments>http://chris-miller.org/archives/2008/07/01/suse-tips/#comments</comments>
		<pubDate>Tue, 01 Jul 2008 12:59:26 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[command line]]></category>
		<category><![CDATA[desktop]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[scrollbars]]></category>
		<category><![CDATA[Suse]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[workspace switcher]]></category>

		<guid isPermaLink="false">http://chris-miller.org/?p=182</guid>
		<description><![CDATA[I&#8217;ve been using Suse at work now for over a year. Once in a while I&#8217;ll find a shortcut or a handy little thing that I&#8217;ll find useful. This blog post outlines a few of the handy shortcuts and tips that I&#8217;ve picked up and never readily knew. Workspace Switcher The Red Hat Workspace Switcher [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been using Suse at work now for over a year.  Once in a while I&#8217;ll find a shortcut or a handy little thing that I&#8217;ll find useful.  This blog post outlines a few of the handy shortcuts and tips that I&#8217;ve picked up and never readily knew.</p>
<p><span id="more-182"></span><br />
<h3>Workspace Switcher</h3>
<p><a href="http://www.flickr.com/photos/chrismiller/2628039178/" title="Workspace Switcher by Chris Miller, on Flickr"><img src="http://farm4.static.flickr.com/3155/2628039178_c26827f3d6_o.png" width="500" height="55" alt="Workspace Switcher" /></a><br />
The Red Hat Workspace Switcher is one of the Linux tools I use all the time.  I have two screens at work, however it still isn&#8217;t enough room to keep all my documents open, read mail  and so forth.  For this reason I use the workspace switcher with 4 workspaces, one for my work, another for email, one for FileMaker (the system we use for breifs and work management) and another spare.  One of the most useful key combos, not a particularly hard one to find &#8211; but perhaps the one I use the most heavily, is <code>Ctrl + Alt + [Arrow Key]</code> which allows me to move back and forward between each of these workspaces.</p>
<p>Another handy tip for using the workspace switcher is that you may move an window from one workspace to another simply by dragging it on the workspace switcher &#8211; simple as that.</p>
<h3>Command Line Applet</h3>
<p><a href="http://www.flickr.com/photos/chrismiller/2628039292/" title="SUSE Command Line Applet by Chris Miller, on Flickr"><img style="float: right;" src="http://farm4.static.flickr.com/3148/2628039292_72b7ca1bf9_o.png" width="190" height="51" alt="SUSE Command Line Applet" /></a><br />
Command Line is a GNOME Applet that sits on a panel at the top of my screen, from here you can quickly launch applications or kill processes as necessary &#8211; pretty much anything you would do in a terminal that doesn&#8217;t require feedback.</p>
<p>It&#8217;s not exactly groundbreaking but it&#8217;s handy if you need to quickly launch gedit, gftp or the likes to do something quickly.</p>
<h3>Scrollbars</h3>
<p>Scrollbars, a really common UI element, yet there were a few things I was surprised to find when using them in Suse.  Clicking one of the up or down arrows at either end of the scrollbar will tab the handle up or down as you would expect.  Right clicking on the up or down arrow on the other hand will scroll you to the top and bottom of the scrollable area respectively.</p>
<h3>View Desktop</h3>
<p>I&#8217;m a messy git, I open windows and don&#8217;t close them, layer them up and not bother to sort them in any way shape or form.  Given that, the view desktop shortcut is always useful to minimise all the active windows on the workspace you are in: <code>Ctrl + Alt + D</code></p>
<h3>Tips?</h3>
<p>Ok, so they&#8217;re not great tips, they&#8217;re handy for saving a bit of time here and there.  I do, however, use these all day at work and so the time saved adds up.  Gimme a shout if there&#8217;s any other decent tips that you know of.<br />
- Chris</p>
]]></content:encoded>
			<wfw:commentRss>http://chris-miller.org/archives/2008/07/01/suse-tips/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Duckworthing</title>
		<link>http://chris-miller.org/archives/2008/06/11/duckworthing/</link>
		<comments>http://chris-miller.org/archives/2008/06/11/duckworthing/#comments</comments>
		<pubDate>Wed, 11 Jun 2008 17:54:46 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[broken]]></category>
		<category><![CDATA[Duckworthing]]></category>
		<category><![CDATA[glasses]]></category>
		<category><![CDATA[Jack Duckworth]]></category>

		<guid isPermaLink="false">http://chris-miller.org/?p=181</guid>
		<description><![CDATA[Well it&#8217;s finally happened, the pair of glasses I&#8217;ve had for going on four or five years now has finally given up. This morning when I arrived at work and sat at my desk I did what I usually do. I took my glasses off and gave them a clean on my shirt. Usually I [...]]]></description>
			<content:encoded><![CDATA[<p>Well it&#8217;s finally happened, the pair of glasses I&#8217;ve had for going on four or five years now has finally given up.</p>
<p>This morning when I arrived at work and sat at my desk I did what I usually do.  I took my glasses off and gave them a clean on my shirt.  Usually I just put them back on and get to the nitty-gritty, usually sitting sifting through emails to find out if any of the spam is actually useful.</p>
<p>Today, however was a different story indeed, as soon as I placed the glasses on my face I felt a ping and then everything went blurry.  I thought that the screw holding the lens into my frames had pinged out again, yes it&#8217;s happened before, but alas no!  No, the actual frame had broken right at the point where the rim meets the legs, leaving a jagged edge and a confounded Chris.</p>
<p><span id="more-181"></span><a style="float: right; margin-left: 5px; margin-bottom: 5px;" href="http://www.flickr.com/photos/chrismiller/2571064582/" title="Duckworthing by Chris Miller, on Flickr"><img src="http://farm4.static.flickr.com/3176/2571064582_bdca09d868_m.jpg" width="240" height="180" alt="Duckworthing" /></a></p>
<p>Anyway, after squinting for a while and ruling out superglue as a means to repair my glasses I eventually had to plump for <em>Jack Duckworth</em>ing them using some tape.  After which it was a quick call to the opticians to set up an appointment to get tested and some new glasses.  To my amazement I managed to get an appointment today, earlier this very afternoon.  An hour later and Â£155 down I&#8217;d managed to order two new pairs of glasses which should hopefully arrive sometime next week.</p>
<p>I&#8217;m continue to Duckworth until then though!<br />
- Chris</p>
]]></content:encoded>
			<wfw:commentRss>http://chris-miller.org/archives/2008/06/11/duckworthing/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

