<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Andrew Odri</title>
	
	<link>http://blog.affirmix.com</link>
	<description>Flash Platform and Dreamweaver Stuff</description>
	<lastBuildDate>Thu, 17 Sep 2009 22:39:53 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/andrewodri" /><feedburner:info uri="andrewodri" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Konductor in InsideRIA Semi-Finals</title>
		<link>http://feedproxy.google.com/~r/andrewodri/~3/Ce2ludyaVNk/</link>
		<comments>http://blog.affirmix.com/2009/09/01/konductor-in-insideria-semi-finals/#comments</comments>
		<pubDate>Tue, 01 Sep 2009 18:12:51 +0000</pubDate>
		<dc:creator>Andrew Odri</dc:creator>
				<category><![CDATA[konductor]]></category>
		<category><![CDATA[adobe max]]></category>
		<category><![CDATA[insideria]]></category>
		<category><![CDATA[vote]]></category>

		<guid isPermaLink="false">http://blog.affirmix.com/?p=294</guid>
		<description><![CDATA[Konductor made it into the InsideRIA Semi-Finals for Best RIA of the Year. If we come in the top 3, then we go to Adobe MAX 2009 for the final vote.
So make sure you vote for Konductor, it would mean a lot  
]]></description>
			<content:encoded><![CDATA[<p>Konductor made it into the <a href="http://www.insideria.com/" target="_blank">InsideRIA</a> Semi-Finals for Best RIA of the Year. If we come in the top 3, then we go to Adobe MAX 2009 for the final vote.</p>
<p>So make sure you <a href="http://oreillynet.com/insideria/polls/237.csp" target="_blank">vote for Konductor</a>, it would mean a lot <img src='http://blog.affirmix.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<img src="http://feeds.feedburner.com/~r/andrewodri/~4/Ce2ludyaVNk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.affirmix.com/2009/09/01/konductor-in-insideria-semi-finals/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.affirmix.com/2009/09/01/konductor-in-insideria-semi-finals/</feedburner:origLink></item>
		<item>
		<title>Vote for Konductor!</title>
		<link>http://feedproxy.google.com/~r/andrewodri/~3/_0-IXUNx6pQ/</link>
		<comments>http://blog.affirmix.com/2009/08/18/vote-for-konductor/#comments</comments>
		<pubDate>Tue, 18 Aug 2009 17:09:20 +0000</pubDate>
		<dc:creator>Andrew Odri</dc:creator>
				<category><![CDATA[konductor]]></category>
		<category><![CDATA[insideria]]></category>
		<category><![CDATA[oreilly]]></category>
		<category><![CDATA[poll]]></category>
		<category><![CDATA[release]]></category>
		<category><![CDATA[riaoftheyear]]></category>
		<category><![CDATA[vote]]></category>

		<guid isPermaLink="false">http://blog.affirmix.com/?p=291</guid>
		<description><![CDATA[After months of stagnation, I have a brief request to make: vote for Konductor!
]]></description>
			<content:encoded><![CDATA[<p>After months of stagnation, I have a brief request to make: <a href="http://oreillynet.com/insideria/polls/234.csp">vote for Konductor!</a></p>
<img src="http://feeds.feedburner.com/~r/andrewodri/~4/_0-IXUNx6pQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.affirmix.com/2009/08/18/vote-for-konductor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.affirmix.com/2009/08/18/vote-for-konductor/</feedburner:origLink></item>
		<item>
		<title>Code Hinting In The Dreamweaver Extensibility API</title>
		<link>http://feedproxy.google.com/~r/andrewodri/~3/RfttdOnNZOk/</link>
		<comments>http://blog.affirmix.com/2009/05/06/code-hinting-in-the-dreamweaver-extensibility-api/#comments</comments>
		<pubDate>Wed, 06 May 2009 23:49:12 +0000</pubDate>
		<dc:creator>Andrew Odri</dc:creator>
				<category><![CDATA[dreamweaver]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[auto]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[coloring]]></category>
		<category><![CDATA[completion]]></category>
		<category><![CDATA[example]]></category>
		<category><![CDATA[extensibility]]></category>
		<category><![CDATA[hinting]]></category>

		<guid isPermaLink="false">http://blog.affirmix.com/?p=246</guid>
		<description><![CDATA[
After many battles with the quirks in the Dreamweaver API, code completion is now working quiet nicely. After trawling through the code hinting documentation, and getting some help from the Adobe team, it turns out that it&#8217;s actually not all that difficult to get working if you adhere closely to a prescribed structure. 
One few [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://api.photoshop.com/home_ef38c0dde81745679f534f6507a6abff/adobe-px-assets/876b311c32bc49539e659eda5312d631" alt="Dreamweaver Code Hints" /></p>
<p>After many battles with the quirks in the Dreamweaver API, code completion is now working quiet nicely. After trawling through the <a href="http://help.adobe.com/en_US/Dreamweaver/10.0_Extending/WS5b3ccc516d4fbf351e63e3d117f53d62b7-7fd7.html" target="_blank">code hinting documentation</a>, and getting some help from the Adobe team, it turns out that it&#8217;s actually not all that difficult to get working if you adhere closely to a prescribed structure. <span id="more-246"></span></p>
<p>One few thing to keep in mind: start off simple. Don&#8217;t add any language or file restrictions in until everything is proven to work. I learn best from examples, so here is an example that defines packages and classes, which use static properties and methods, as well as and instance properties and methods:</p>
<pre><code>&lt;codehints xmlns:MMString=&quot;http://www.adobe.com/schemes/data/string/&quot;&gt;
	&lt;menugroup MMString:name=&quot;CodeHints_Example&quot; id=&quot;CodeHints_Example&quot; name=&quot;Example Code Hints&quot; enabled=&quot;true&quot;&gt;
		&lt;description&gt;
			&lt;![CDATA[Example Code Hints]]&gt;
		&lt;/description&gt;
		&lt;!--
			This is how a package is defined.
				- Each tier must be defined by an independant menu element
				- The pattern attribute must be used
				- The pattern value must be followed by a dot
		--&gt;
		&lt;menu pattern=&quot;package.&quot; casesensitive=&quot;true&quot;&gt;
			&lt;menuitem label=&quot;firsttier&quot; icon=&quot;shared/mm/images/hintPackage.gif&quot; /&gt;
		&lt;/menu&gt;
		&lt;menu pattern=&quot;package.firsttier.&quot; casesensitive=&quot;true&quot;&gt;
			&lt;menuitem label=&quot;secondtier&quot; icon=&quot;shared/mm/images/hintPackage.gif&quot; /&gt;
		&lt;/menu&gt;
		&lt;menu pattern=&quot;package.firsttier.secondtier.&quot; casesensitive=&quot;true&quot;&gt;
			&lt;menuitem label=&quot;ExampleClass&quot; icon=&quot;shared/mm/images/hintClass.gif&quot; /&gt;
		&lt;/menu&gt;
		&lt;!--
			This is how a class constructor is defined.
				- The pattern attribute must be used
				- The pattern value must be the absolute path to the class
				- The pattern value must also contain any parameters that need to be passed to the constructor
		--&gt;
		&lt;function pattern=&quot;package.firsttier.secondtier.ExampleClass(Object parameter)&quot; casesensitive=&quot;true&quot; icon=&quot;shared/mm/images/hintClass.gif&quot; /&gt;
		&lt;!--
			This is how static class members are defined.
				- The pattern value must be the absolute path to the class
				- The pattern value must be followed by a dot
				- Static properties and events must be menuitem elements that are children of the menu element
				- Static methods must be menuitem elements that are children of the menu element, with a label element the ends with an opening parenthesis
				- Static methods must also be function elements that are siblings of the menu element
				- Static methods must also contain any parameters that need to be passed to the function
		--&gt;
		&lt;menu pattern=&quot;package.firsttier.secondtier.ExampleClass.&quot; casesensitive=&quot;true&quot;&gt;
			&lt;menuitem label=&quot;staticProperty&quot; icon=&quot;shared/mm/images/hintProperty.gif&quot; /&gt;

			&lt;menuitem label=&quot;staticMethod&quot; value=&quot;staticMethod(&quot; icon=&quot;shared/mm/images/hintFunction.gif&quot; /&gt;
		&lt;/menu&gt;
		&lt;function pattern=&quot;package.firsttier.secondtier.ExampleClass.staticMethod(Integer id, String value)&quot; icon=&quot;shared/mm/images/hintFunction.gif&quot; /&gt;
		&lt;!--
			This is how instance class members are defined.
				- The classpattern attribute must be used, and not the pattern attribute
				- The classpattern value must be the absolute path to the class
				- Instance properties must be property elements that are children of the menu element
				- Instance methods must be function elements that are children of the menu element
				- Instance methods must also contain any parameters that need to be passed to the function
		--&gt;
		&lt;menu classpattern=&quot;package.firsttier.secondtier.ExampleClass&quot;&gt;
			&lt;property label=&quot;instanceProperty&quot; icon=&quot;shared/mm/images/hintProperty.gif&quot; /&gt;

			&lt;method pattern=&quot;append(ExampleClass childExampleClass)&quot; icon=&quot;shared/mm/images/hintFunction.gif&quot; /&gt;
			&lt;method pattern=&quot;remove(ExampleClass childExampleClass)&quot; icon=&quot;shared/mm/images/hintFunction.gif&quot; /&gt;
		&lt;/menu&gt;
	&lt;/menugroup&gt;
&lt;/codehints&gt;</code></pre>
<p>There are a few ways to get this up and running, and much of what you need to get going will be contained in the <a href="http://help.adobe.com/en_US/Dreamweaver/10.0_Extending/WS5b3ccc516d4fbf351e63e3d117f53d62b7-7fd7.html" target="_blank">code hints tag reference</a>.</p>
<img src="http://feeds.feedburner.com/~r/andrewodri/~4/RfttdOnNZOk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.affirmix.com/2009/05/06/code-hinting-in-the-dreamweaver-extensibility-api/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://blog.affirmix.com/2009/05/06/code-hinting-in-the-dreamweaver-extensibility-api/</feedburner:origLink></item>
		<item>
		<title>Live *.ste Dreamweaver Password Encoder and Decoder</title>
		<link>http://feedproxy.google.com/~r/andrewodri/~3/qcr2KkVqmUE/</link>
		<comments>http://blog.affirmix.com/2009/05/05/live-ste-dreamweaver-password-encoder-and-decoder/#comments</comments>
		<pubDate>Tue, 05 May 2009 23:02:15 +0000</pubDate>
		<dc:creator>Andrew Odri</dc:creator>
				<category><![CDATA[dreamweaver]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[decode]]></category>
		<category><![CDATA[decrypt]]></category>
		<category><![CDATA[encode]]></category>
		<category><![CDATA[encrypt]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[live]]></category>
		<category><![CDATA[online]]></category>
		<category><![CDATA[password]]></category>
		<category><![CDATA[recovery]]></category>
		<category><![CDATA[solution]]></category>
		<category><![CDATA[ste]]></category>

		<guid isPermaLink="false">http://blog.affirmix.com/?p=251</guid>
		<description><![CDATA[I noticed that a lot of the traffic currently going to this post is coming from people wanting to encode and decode passwords from a *.ste file online. You can now do this using the form below:


function encodePassword(input)
{
    var top = 0;
    var output = '';

    [...]]]></description>
			<content:encoded><![CDATA[<p>I noticed that a lot of the traffic currently going to <a href="http://blog.affirmix.com/2008/08/28/encoded-passwords-in-ste-site-definition-files/">this post</a> is coming from people wanting to encode and decode passwords from a *.ste file online. You can now do this using the form below:</p>

<script type="text/javascript">
function encodePassword(input)
{
    var top = 0;
    var output = '';

    for(var i = 0; i < input.length; i++){
        var currentChar = input.charCodeAt(i);
        if(currentChar < 0 || currentChar > 0xFFFF){return(false);}
        if(top != 0){
            if(0xDC00 <= currentChar && currentChar <= 0xDFFF){
                output += dec2hex(0x10000 + ((top - 0xD800) << 10) + (currentChar - 0xDC00) + i) + '';
                top = 0;
                continue;
                // Insert alert for below failure
            }else{return(false);}
        }
        if(0xD800 <= currentChar && currentChar <= 0xDBFF){top = currentChar;}
        else{output += dec2hex(currentChar + i) + '';}
    }

    return(output);
}

function dec2hex(input){return(input+0).toString(16).toUpperCase();}

function decodePassword(input)
{
    var output = "";

    if(input.length == 0){return("");}

    for(var i = 0; i < input.length / 2; i++){
        var currentHex = parseInt(input.substr(i * 2, 2), 16);
            if(currentHex <= 0xFFFF){
                output += String.fromCharCode(currentHex - i);
            }else if(currentHex <= 0x10FFFF){
                currentHex -= 0x10000
                output += String.fromCharCode(0xD800 | (currentHex >> 10)) + String.fromCharCode(0xDC00 | (currentHex & 0x3FF) - i);
            }else{
                //Insert alert for below failure
                return(false);
        }
    }

    return(output);
}
</script>

<form style="margin-bottom: 10px;">
<label for="encoded">To to decode: <input type="text" value="" id="encoded" name="encoded" /></label><input type="button" value="Decode" id="decode" name="encode" onclick="document.getElementById('decoded').value = decodePassword(document.getElementById('encoded').value);" /><br />
<label for="decoded">To to encode: <input type="text" value="" id="decoded" name="decoded" /></label><input type="button" value="Encode" id="encode" name="decode" onclick="document.getElementById('encoded').value = encodePassword(document.getElementById('decoded').value);" /><br />
</form><img src="http://feeds.feedburner.com/~r/andrewodri/~4/qcr2KkVqmUE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.affirmix.com/2009/05/05/live-ste-dreamweaver-password-encoder-and-decoder/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://blog.affirmix.com/2009/05/05/live-ste-dreamweaver-password-encoder-and-decoder/</feedburner:origLink></item>
		<item>
		<title>MMNotes.localURLToFilePath &amp; MMNotes.filePathToLocalURL Workaround In The Dreamweaver Extensibility API</title>
		<link>http://feedproxy.google.com/~r/andrewodri/~3/cqlVMyZtwc8/</link>
		<comments>http://blog.affirmix.com/2009/04/22/mmnoteslocalurltofilepath-mmnotesfilepathtolocalurl-workaround-in-the-dreamweaver-extensibility-api/#comments</comments>
		<pubDate>Thu, 23 Apr 2009 00:14:57 +0000</pubDate>
		<dc:creator>Andrew Odri</dc:creator>
				<category><![CDATA[dreamweaver]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[dwscripts]]></category>
		<category><![CDATA[extensibility]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[filepath]]></category>
		<category><![CDATA[filepathtolocalurl]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[localurl]]></category>
		<category><![CDATA[localurltofilepath]]></category>
		<category><![CDATA[mmnotes]]></category>
		<category><![CDATA[solution]]></category>
		<category><![CDATA[workaround]]></category>

		<guid isPermaLink="false">http://blog.affirmix.com/?p=240</guid>
		<description><![CDATA[
If you have worked with the Dreamweaver Extensibility API, you may have noticed that the MMNotes.localURLToFilePath and MMNotes.filePathToLocalURL functions do not work correctly on Mac OS X.
Below is the code that I used to get around this issue:
function localURLToFilePath(localURL)
{
	return (dreamweaver.isOSX()) ? localURL.replace(/^file:\/\/\/([\d\w\s\\_-]+)(.+$)/, "/Volumes/$1$2") : MMNotes.localURLToFilePath(localURL);
}

function filePathToLocalURL(filePath)
{
	return (dreamweaver.isOSX()) ? "file://" + filePath : MMNotes.filePathToLocalURL(filePath);
}
Hope that saves [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://api.photoshop.com/home_ef38c0dde81745679f534f6507a6abff/adobe-px-assets/491151bf10914022946ce4dfee4c7896" alt="Dreamweaver Paths" /></p>
<p>If you have worked with the Dreamweaver Extensibility API, you may have noticed that the <a href="http://help.adobe.com/en_US/Dreamweaver/10.0_API_Ref/WS5b3ccc516d4fbf351e63e3d117f9e05b25-7fd7.html" target="_blank">MMNotes.localURLToFilePath</a> and <a href="http://help.adobe.com/en_US/Dreamweaver/10.0_API_Ref/WS5b3ccc516d4fbf351e63e3d117f9e05b25-7ff7.html" target="_blank">MMNotes.filePathToLocalURL</a> functions do not work correctly on Mac OS X.</p>
<p>Below is the code that I used to get around this issue:</p>
<pre><code>function localURLToFilePath(localURL)
{
	return (dreamweaver.isOSX()) ? localURL.replace(/^file:\/\/\/([\d\w\s\\_-]+)(.+$)/, "/Volumes/$1$2") : MMNotes.localURLToFilePath(localURL);
}

function filePathToLocalURL(filePath)
{
	return (dreamweaver.isOSX()) ? "file://" + filePath : MMNotes.filePathToLocalURL(filePath);
}</code></pre>
<p>Hope that saves you some time!</p>
<img src="http://feeds.feedburner.com/~r/andrewodri/~4/cqlVMyZtwc8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.affirmix.com/2009/04/22/mmnoteslocalurltofilepath-mmnotesfilepathtolocalurl-workaround-in-the-dreamweaver-extensibility-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.affirmix.com/2009/04/22/mmnoteslocalurltofilepath-mmnotesfilepathtolocalurl-workaround-in-the-dreamweaver-extensibility-api/</feedburner:origLink></item>
		<item>
		<title>How To Lock Your Workstation In Mac OS X</title>
		<link>http://feedproxy.google.com/~r/andrewodri/~3/Ahd0c17xChg/</link>
		<comments>http://blog.affirmix.com/2009/04/08/how-to-lock-your-workstation-in-mac-os-x/#comments</comments>
		<pubDate>Wed, 08 Apr 2009 20:40:57 +0000</pubDate>
		<dc:creator>Andrew Odri</dc:creator>
				<category><![CDATA[miscellaneous]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[keychain]]></category>
		<category><![CDATA[lock]]></category>
		<category><![CDATA[mac os x]]></category>
		<category><![CDATA[screen]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[windows]]></category>
		<category><![CDATA[workstation]]></category>

		<guid isPermaLink="false">http://blog.affirmix.com/?p=228</guid>
		<description><![CDATA[
This is just a little tip for anyone who has recently switched from Windows to Mac OS X and was wondering where the &#8220;Lock Workstation&#8221; shortcut went. This shows you how to set up a timeout using the screen saver as well.

Go to the &#xF8FF; (Apple) menu, and select the System Preferences&#8230; menu item.
Click on [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://api.photoshop.com/home_ef38c0dde81745679f534f6507a6abff/adobe-px-assets/9f4ce92d54a64fe5be9241ca9560f63a" alt="Padlock Workstation" /></p>
<p>This is just a little tip for anyone who has recently switched from Windows to Mac OS X and was wondering where the &#8220;<a href="http://www.microsoft.com/windowsxp/using/security/learnmore/tips/schnoll1.mspx" target="_blank">Lock Workstation</a>&#8221; shortcut went. This shows you how to set up a timeout using the screen saver as well.</p>
<ol>
<li>Go to the &#xF8FF; (Apple) menu, and select the System Preferences&#8230; menu item.</li>
<li>Click on the Desktop &#038; Screen Saver item, and select a screen saver. <em>This is required if you would like to lock the screen after a timeout.</em></li>
<li>Open Finder, and navigate to Applications » Utilities, and open Keychain Access.</li>
<li>Go to the Keychain Access menu, and select the Preferences&#8230; menu item.</li>
<li>Ensure that Show Status in Menu Bar is checked.</li>
</ol>
<p>You should now see a little padlock in menu bar close to the clock. When you click this, and menu will drop down, and the first menu item Lock Screen will allow you to do just that.</p>
<p>Now if you would like to lock the screen on a time out, follow these instructions:</p>
<ol>
<li>Go to the &#xF380; (Padlock) menu, and select the Open Security Preferences&#8230; menu item.</li>
<li>Ensure that Require password to wake this computer from sleep or screen saver is checked.</li>
</ol>
<p>Unfortunately there is no keyboard shortcut for locking a workstation, and there is no way &#8211; at this time at least &#8211; to set up a shortcut to perform this particular function.</p>
<img src="http://feeds.feedburner.com/~r/andrewodri/~4/Ahd0c17xChg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.affirmix.com/2009/04/08/how-to-lock-your-workstation-in-mac-os-x/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://blog.affirmix.com/2009/04/08/how-to-lock-your-workstation-in-mac-os-x/</feedburner:origLink></item>
		<item>
		<title>IE6, IE7 And IE8 On Mac OS X Step By Step</title>
		<link>http://feedproxy.google.com/~r/andrewodri/~3/pZnMzmMKMzQ/</link>
		<comments>http://blog.affirmix.com/2009/04/01/ie6-ie7-and-ie8-on-mac-os-x-step-by-step/#comments</comments>
		<pubDate>Wed, 01 Apr 2009 21:25:36 +0000</pubDate>
		<dc:creator>Andrew Odri</dc:creator>
				<category><![CDATA[miscellaneous]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[compatibility]]></category>
		<category><![CDATA[compliance]]></category>
		<category><![CDATA[ie6]]></category>
		<category><![CDATA[ie7]]></category>
		<category><![CDATA[ie8]]></category>
		<category><![CDATA[internet explorer]]></category>
		<category><![CDATA[mac os x]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[sun]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[vdi]]></category>
		<category><![CDATA[vhd]]></category>
		<category><![CDATA[virtualbox]]></category>
		<category><![CDATA[w3c]]></category>
		<category><![CDATA[web standards]]></category>

		<guid isPermaLink="false">http://blog.affirmix.com/?p=191</guid>
		<description><![CDATA[
UPDATE: Adobe recently released BrowserLab &#8230; If you want a fast method of previewing your sites on different versions of IE running on different OSes, you might want to check it out  
After recently weening myself off Windows and on to Mac OS X &#8211; and deleting my Windows partition &#8211; it became pretty [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://api.photoshop.com/home_ef38c0dde81745679f534f6507a6abff/adobe-px-assets/41c31b1e484b43a79344c1145b81a188" alt="Sun xVM VirtualBox" /></p>
<p>UPDATE: Adobe <a href="http://labs.adobe.com/technologies/browserlab/">recently released BrowserLab </a>&#8230; If you want a fast method of previewing your sites on different versions of IE running on different OSes, you might want to <a href="https://browserlab.adobe.com/">check it out</a> <img src='http://blog.affirmix.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>After recently weening myself off Windows and on to Mac OS X &#8211; and deleting my Windows partition &#8211; it became pretty clear that if I would need some method of running Internet Explorer on my Mac if I wanted to continue doing web development with any kind of success. After a bit of Googling, a bit of testing, and healthy dose of &#8220;issues&#8221;, I have come up with a fast, stable &#8211; and best of all free &#8211; method of running IE6, IE7 and IE8 simultaneously on my Intel Mac legally. <span id="more-191"></span></p>
<p>First of all, you will need to download a bunch of software. I have listed all of this below:</p>
<ul>
<li><a href="http://download.virtualbox.org/virtualbox/2.0.6/VirtualBox-2.0.6-39760-OSX_x86.dmg">Download Sun xVM VirtualBox 2.0.6</a> <em>The <strong>exact version 2.0.6</strong> of VirtualBox must be used for this process, at least until the network drivers are installed. At the time of writing, the latest version 2.1.4 will not allow the network drivers to be installed correctly.</em></li>
<li><a href="http://www.kju-app.org/">Download Q</a></li>
<li><a href="http://wakaba.c3.cx/s/apps/unarchiver.html">Download The Unarchiver</a></li>
<li><a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=21EABB90-958F-4B64-B5F1-73D0A413C8EF&#038;displaylang=en">Download the Microsoft IE6, IE7 &#038; IE8 Disk Images</a></li>
</ul>
<p>Next, I put together a list of steps that need to be followed in order to get this all working. Read though it first, as I have attached the reasons why I have done things a certain way to help you get a feel for what is going on.</p>
<ol>
<li>Install VirtualBox. <em>This is the virtual machine that will be used to run the various OS and browser images.</em></li>
<li>Install The Unarchiver. <em>This will be used to extract the virtual machines from the *.EXE files.</em></li>
<li>Install Q. <em>This will be used in the process of converting the Microsoft *.VHD virtual machines into native VirtualBox *.VDI virtual machines.</em></li>
<li>Run The Unarchiver, and associate it with *.EXE files.</li>
<li>Open the IE6, IE7 &#038; IE8 images using The Unarchiver. A new folder will be created, with a *.VHD in each of these.</li>
<li>Open Terminal, and type the listed commands for each of the *.VHD files. <em>This will allow all of the images to be mounted and executed together without any conflicts. Currently all the Microsoft images <a href="http://forums.virtualbox.org/viewtopic.php?f=7&#038;t=14976" target="_blank">share that same hard disk identifier</a>, and this method allows it to be changed.</em>
<pre>/Applications/Q.app/Contents/MacOS/qemu-img convert -O raw -f vpc OldVHDImage.vhd NewRAWImage.raw
VBoxManage convertdd NewRAWImage.raw NewVDIImage.vdi</pre>
</li>
</ol>
<p><img src="http://api.photoshop.com/home_ef38c0dde81745679f534f6507a6abff/adobe-px-assets/ea116ed5c6af4b99b0bf545925ee8c10" alt="" /></p>
<ol start="7">
<li>Run VirtualBox, and follow the listed steps for each of the *.VDI images.
<ol>
<li>Go to the File menu, and select Virtual Disk Manager&#8230;</li>
<li>Click on the Add toolbar button on the Virtual Disk Manager window, and select the appropriate *.VDI from the file selection dialog.</li>
</ol>
</li>
</ol>
<p><img src="http://api.photoshop.com/home_ef38c0dde81745679f534f6507a6abff/adobe-px-assets/a7566edbcdbc41c8bf18f99007e9fc0f" alt="" /></p>
<ol>
<ol start="2">
<li>You should now see the *.VDI image in the list. Click on the OK button.</li>
<li>Click on the New toolbar button on the Sun xVM VirtualBox window, and follow the prompts on the Create New Virtual Machine window. Ensure that the right OS type is selected, and that adequate RAM is allotted for the virtual machine.</li>
</ol>
</ol>
<p><img src="http://api.photoshop.com/home_ef38c0dde81745679f534f6507a6abff/adobe-px-assets/35a6409876784c269c17eb9d4173bd81" alt="" /></p>
<ol>
<ol start="4">
<li>Select the new virtual machine, and click on the Start toolbar button on the Sun xVM VirtualBox window. Immediately after this, tap F8 to enter the Windows Advanced Options menu.</li>
<li>Select Safe Mode from the menu, and press the Return key.</li>
<li>Once Windows has booted up in safe mode, cancel all of the hardware prompts.</li>
<li>Go to Start, then select Run&#8230; . Type cmd into the input field.</li>
<li>At the command prompt, type each of the listed commands. <em>This will prevent the virtual machines from bluescreening, and will allow the appropriate network drivers to be installed.</em>
<pre>cd \WINDOWS\system32\drivers
ren processr.sys processr.old
exit</pre>
</li>
<li>Restart the virtual machine. Windows will likely prompt you to do this after is has detected the change.</li>
<li>Once Windows has booted up, cancel all of the hardware prompts.</li>
<li>Go to the Devices menu in VirtualBox, and select Install Guest Additions&#8230;</li>
<li>Follow the prompts within Windows to install the guest additions, or drivers. You will be prompted to reboot your virtual machine at the end of this process.</li>
<li>Once Windows has booted up, you will be presented with the Hardware Update Wizard. Select Install the software automatically, and click on the Next button.</li>
<li>Follow the prompts and wait until the network adapter is installed.</li>
</ol>
</li>
</ol>
<p>If all goes well, you should have three virtual machines that can all run together synchronously for some serious browser testing. If you would like a little more information, I would suggest checking out <a href="http://www.10voltmedia.com/blog/2008/12/screencast-install-internet-explorer-on-osx-using-virtualbox/" target="_blank">Jeff Couturier&#8217;s article</a> (he has a nice tutorial video on the site too), and <a href="http://blog.mozmonkey.com/2008/vpc-ie6-ie7-ie8-on-mac-os-x/" target="_blank">Jeremy Gillick&#8217;s article</a>.</p>
<p>UPDATE: It appears this article has been <a href="http://www.poso.dk/2009/04/20/ie6-ie7-ie8-pa-osx-med-virtualbox/" target="_blank">translated into Danish</a> by <a href="http://www.poso.dk/" target="_blank">Rasmus Luckow-Nielsen</a>. Thanks Rasmus!</p>
<img src="http://feeds.feedburner.com/~r/andrewodri/~4/pZnMzmMKMzQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.affirmix.com/2009/04/01/ie6-ie7-and-ie8-on-mac-os-x-step-by-step/feed/</wfw:commentRss>
		<slash:comments>50</slash:comments>
		<feedburner:origLink>http://blog.affirmix.com/2009/04/01/ie6-ie7-and-ie8-on-mac-os-x-step-by-step/</feedburner:origLink></item>
		<item>
		<title>New Konductor Website Live</title>
		<link>http://feedproxy.google.com/~r/andrewodri/~3/3Ux4boeWlug/</link>
		<comments>http://blog.affirmix.com/2009/03/18/new-konductor-website-live/#comments</comments>
		<pubDate>Wed, 18 Mar 2009 23:32:18 +0000</pubDate>
		<dc:creator>Andrew Odri</dc:creator>
				<category><![CDATA[konductor]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[casey sheehan]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[forums]]></category>
		<category><![CDATA[new]]></category>
		<category><![CDATA[validation]]></category>
		<category><![CDATA[w3c]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[website]]></category>
		<category><![CDATA[xhtml]]></category>

		<guid isPermaLink="false">http://blog.affirmix.com/?p=181</guid>
		<description><![CDATA[
If you haven&#8217;t seen it already, check out the fancy new Konductor website. We&#8217;ve implemented the beautiful design that Casey did for us, and we have also added a bunch of new content as well. If you were wanting a little more information on who Konductor is targeted at, and what it brings to the [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://api.photoshop.com/home_ef38c0dde81745679f534f6507a6abff/adobe-px-assets/83551a6c00664858b075d7dbcb25297e" alt="Konductor Website" /></p>
<p>If you haven&#8217;t seen it already, check out the <a href="http://www.konductor.net/" target="_blank">fancy new Konductor website</a>. We&#8217;ve implemented the beautiful design that <a href="http://www.caseysheehan.com/" target="_blank">Casey</a> did for us, and we have also added a bunch of new content as well. If you were wanting a little more information on who Konductor is targeted at, and what it brings to the table, make sure you take a peek. The new site is also running on Konductor, so check it out if you want to get a feel for the <a href="http://validator.w3.org/check?verbose=1&#038;uri=http%3A%2F%2Fwww.konductor.net%2F" target="_blank">type of code it generates</a>.</p>
<p>We also moved the Konductor blog and forums, and we are in the process of making these look pretty too.</p>
<p>The forums are now at <a href="http://forums.konductor.net/" target="_blank">http://forums.konductor.net/</a>, rather than http://www.konductor.net/forums/. The new skin is up and looking good <img src='http://blog.affirmix.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>The blog is now at <a href="http://blog.konductor.net/" target="_blank">http://blog.konductor.net/</a>, rather than http://www.konductor.net/blog/. The new skin will be up in the next couple of weeks.</p>
<p>As far as the application goes, we have made a <em>lot</em> of progress, and we keep getting more and more excited with what we have. This is going to turn a lot of heads when we go live&#8230;</p>
<img src="http://feeds.feedburner.com/~r/andrewodri/~4/3Ux4boeWlug" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.affirmix.com/2009/03/18/new-konductor-website-live/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.affirmix.com/2009/03/18/new-konductor-website-live/</feedburner:origLink></item>
		<item>
		<title>XULRunner – Adobe AIR’s Grandad</title>
		<link>http://feedproxy.google.com/~r/andrewodri/~3/LxIYU6hMEgk/</link>
		<comments>http://blog.affirmix.com/2009/02/11/xulrunner-adobe-airs-grandad/#comments</comments>
		<pubDate>Wed, 11 Feb 2009 19:50:16 +0000</pubDate>
		<dc:creator>Andrew Odri</dc:creator>
				<category><![CDATA[miscellaneous]]></category>
		<category><![CDATA[air]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[fennec]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[xul]]></category>
		<category><![CDATA[xulrunner]]></category>

		<guid isPermaLink="false">http://blog.affirmix.com/?p=144</guid>
		<description><![CDATA[
XULRunner is a project that has been around since the inception of Firefox, and predates Adobe AIR by quiet a margin. For those who have not really looked into it too much, XULRunner has a lot of similarities to Adobe AIR &#8211; it is a cross platform runtime that allows you to run code written [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://api.photoshop.com/home_ef38c0dde81745679f534f6507a6abff/adobe-px-assets/219a0510d50b4a4b8b9ab8f0765c3dde" alt="Mozilla" /></p>
<p>XULRunner is a project that has been around since the inception of Firefox, and predates Adobe AIR by quiet a margin. For those who have not really looked into it too much, XULRunner has a lot of similarities to Adobe AIR &#8211; it is a cross platform runtime that allows you to run code written in XUL &#8211; an XML derivative very similar to HTML.</p>
<p>A little more information: XUL elements add certain features that are required to add things like menus, menu items, toolbars, toolbar buttons and the like into your application, and can be mixed and matched with HTML. XULRunner also exposes extra functions to JavaScript, allowing you to access files on the host computer, read and write from SQLite databases, and do a lot of things that AIR does in this regard.</p>
<p>I haven&#8217;t played with XUL a whole lot since AIR came out, as documentation has always fallen behind AIR&#8217;s. And performing some advanced functions, like populating a tree component with SQLite results, or manipulating an image, are a little more involved than with AIR.</p>
<p>However, XULRunner has been really branching out to a lot of platform &#8211; Windows, Mac OS and Linux support was all there before AIR even came on the scene. There is also SkyOS support, and today the first &#8220;pre-alpha&#8221; of XULRunner is available for Windows Mobile (codenamed &#8220;Fennec&#8221;). There are also lightweight ports available for mobile Linux distros, and for Symbian S60.</p>
<p>This really opens a lot of doors for developers &#8211; your desktop applications and mobile applications can all share the same codebase. XUL itself is actually quiet nice to write in, and I was always impressed by how it always took advantage of native OS components libraries.</p>
<p>Anyway, I think the XULRunner team deserves very high praise for what they have accomplished &#8211; they have always been ahead of the game when with their platform independent runtime, and they are continuing to push support to an impressive array of platforms.</p>
<ul>
<li><a href="https://developer.mozilla.org/en/XULRunner" target="_blank">XULRunner Documentation</a></li>
<li><a href="https://developer.mozilla.org/En/XUL" target="_blank">XUL Documentation</a></li>
<li><a href="http://dougt.wordpress.com/2009/02/10/milestone-1-fennec-for-windows-mobile/" target="_blank">Doug&#8217;s announcement of Fennec for Windows Mobile</a></li>
<li><a href="http://starkravingfinkle.org/blog/2009/02/xulrunner-1906/" target="_blank">Mark&#8217;s announcement of XULRunner 1.9.0.6</a></li>
</ul>
<img src="http://feeds.feedburner.com/~r/andrewodri/~4/LxIYU6hMEgk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.affirmix.com/2009/02/11/xulrunner-adobe-airs-grandad/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.affirmix.com/2009/02/11/xulrunner-adobe-airs-grandad/</feedburner:origLink></item>
		<item>
		<title>Getting Started With Adobe AIR And SQLite (And Getting Around The Bugs)</title>
		<link>http://feedproxy.google.com/~r/andrewodri/~3/bb6UpzdT9Lc/</link>
		<comments>http://blog.affirmix.com/2009/01/28/getting-started-with-adobe-air-and-sqlite-and-avoiding-the-problems/#comments</comments>
		<pubDate>Thu, 29 Jan 2009 02:29:11 +0000</pubDate>
		<dc:creator>Andrew Odri</dc:creator>
				<category><![CDATA[miscellaneous]]></category>
		<category><![CDATA[air]]></category>
		<category><![CDATA[bitmap]]></category>
		<category><![CDATA[blob]]></category>
		<category><![CDATA[boolean]]></category>
		<category><![CDATA[date]]></category>
		<category><![CDATA[displayobject]]></category>
		<category><![CDATA[responder]]></category>
		<category><![CDATA[sqlite]]></category>
		<category><![CDATA[sqlstatement]]></category>

		<guid isPermaLink="false">http://blog.affirmix.com/?p=101</guid>
		<description><![CDATA[I have been writing some applications in AIR that for the first time make extensive use of SQLite. I hit a few roadblocks along the way, so here are a few things that may come in handy if you are using SQLite in AIR for the first time...]]></description>
			<content:encoded><![CDATA[<p><img src="http://api.photoshop.com/home_ef38c0dde81745679f534f6507a6abff/adobe-px-assets/e8e28e55d2f149f8b09d8d487d020e8b" alt="Adobe AIR" /></p>
<p>I have been writing some applications in AIR that for the first time make extensive use of SQLite. I hit a few roadblocks along the way, so here are a few things that may come in handy if you are using SQLite in AIR for the first time. <span id="more-101"></span></p>
<h3>Reuse SQLStatement Instances</h3>
<p>Rather than creating a new SQLStatement object for each query you want to run, it is recommended that you reuse an existing instance, and just alter the parameters associated with the object. You will reap three benefits from doing this:</p>
<ul>
<li>The query will be cached, so the SQLite connection will not have to compile a new statement every time you want to run the query</li>
<li>You will get automatic type conversion when assigning values like strings, integers, dates and so on</li>
<li>You will improve data integrity within the database because as the automatic type conversion also acts as a kind of filter</li>
</ul>
<p>For queries that get used across an entire application, I have found that putting the SQLConnection object and wrapper functions for the SQLStatement objects inside a singleton class seems to work very well.</p>
<p>NOTE: Every time you change the text property, the query will get recompiled. The trick is in using the parameters.</p>
<p>The following example demonstrates this:</p>
<pre><code>package
{
	import flash.data.SQLConnection;
	import flash.data.SQLStatement;

	public class SQLConnectionWrapper
	{
		private static const SINGLETON_INSTANCE:SQLConnectionWrapper = new SQLConnectionWrapper(SingletonLock);

		public var connection:SQLConnection;

		private var selectRecord:SQLStatement;

		public static function get instance():SQLConnectionWrapper
		{
			return SINGLETON_INSTANCE;
		}

		public function SQLConnectionWrapper(lock:Class)
		{
			// This ensures that only once instance of this class may be created and accessed
			if(lock != SingletonLock){
				throw new Error("Class Cannot Be Instantiated: Use SQLConnectionWrapper.instance");
			}

			createDatabase();
		}

		private function createDatabase():void
		{
			// This creates an SQLConnection object , which can be accessed publicly so that event listeners can be defined for it
			connection = new SQLConnection();

			var databaseFile:File = File.applicationStorageDirectory.resolvePath("database.db");
			connection.openAsync(databaseFile);
		}

		public function getRecord(recordId:int):SQLStatement
		{
			// If selectRecord has not been instantiated, then create the instance with all the data that it needs
			// If it has been instantiated, then we can skip over this part and take advantage of the fact that it has now been cached
			if(!(selectRecord is SQLStatement)){
				selectRecord= new SQLStatement();
				selectRecord.sqlConnection = connection;
				selectRecord.text =
				"SELECT record_id, description, is_active " +
				"FROM record_tbl " +
				"WHERE record_id = :recordId";
			}
			// This simply changes the one parameter that needs to be changed
			// Because recordId has already been declared as an int, this will be converted into an SQLite recognized integer
			selectRecord.parameters[":recordId"] = recordId;

			return selectRecord;
		}
	}
}

// This little class exists to stop extra instances on the singleton being created
class SingletonLock{}</code></pre>
<h3>Use Responders</h3>
<p>One major problem that caught me off guard when trying to reuse instances was event handling. If I were to use SQLConnectionWrapper.instance.getRecord() in multiple places across my application, and attach event listeners to them, I will encounter a problem where all three event listeners get triggered. Even when each event listener is removed, errors still occur due to the fact that the SQLStatement object still thinks that it is executing. Not pretty.</p>
<p>Using Responder objects allows to avoid the pain that come s from constantly adding and removing event listeners, and prevent the race condition that occurs with the SQLStatement objects. The Responder object allows you to define event handlers for both SQLEvent.RESULT and SQLErrorEvent.ERROR events. And rather than attaching itself to the SQLStatement object, it will only handle events generated for each particular call to SQLStatement.execute().</p>
<p>NOTE: After a successful query, the handler will be passed an SQLResult object as the first argument, and not an SQLEvent object.</p>
<p>NOTE: After a failed query, the handler will be passed an SQLError object as the first argument, and not an SQLErrorEvent object.</p>
<p>Here is an example:</p>
<pre><code>package
{
	import SQLConnectionWrapper;</code>

	import flash.net.Responder;
	import flash.data.SQLResult;

	public class SampleApplication
	{
		// Create the responder object once, so that it can be reused again and again
		private var responder:Responder = new Responder(handleSuccess, handleFailure);

		public function SampleApplication():void
		{
			// This opens the database - obviously
			SQLConnectionWrapper.instance.connection.addEventListener(SQLEvent.OPEN, executeQuery);
			SQLConnectionWrapper.instance.connection.open();
		}

		private function executeQuery():void
		{
			// This statement essentially creates a reference to the SQLStatement object that is created once for all time within the SQLConnectionWrapper singleton
			var statement:SQLStatement = SQLConnectionWrapper.instance.getRecord(1);
			statement.execute(-1, responder);
		}

		private function handleSuccess(result:SQLResult):void
		{
			trace("Record ID: " + result.data[0].record_id + ", Description: " + result.data[0].description + ", Is Active: " + result.data[0].is_active);
		}

		private function handleFailure(error:SQLError):void
		{
			trace("Epic Fail: " + error.message);
		}
	}
}</code></pre>
<p><del></p>
<h3>Boolean Objects</h3>
<p>When returning results from a SELECT query, any SQLite Boolean objects will be correctly converted into ActionScript Boolean objects. However, when executing an INSERT or UPDATE query, an integer is actually required. This quick and nasty workaround demonstrates what has to take place:</p>
<p><em>This would need to be part of SQLConnectionWrapper</em></p>
<pre><code>		private function setRecord(description:String, isActive:Boolean):void
		{
			if(!(insertRecord is SQLStatement)){
				insertRecord = new SQLStatement();
				insertRecord.sqlConnection = connection;
				insertRecord.text = "INSERT INTO record_tbl (description, is_active) VALUES (:description, :isActive)";
			}
			insertRecord.parameters[":description"] = description;
			// This is pretty straightforward, but it simply converts the ActionScript Boolean into an int, so that SQLite can accurately create it's own boolean in the database
			insertRecord.parameters[":isActive"] = isActive ? 1 : 0;

			return insertRecord;
		}</code></pre>
<p></del></p>
<h3>Date Objects</h3>
<p>When executing an INSERT or UPDATE query, dates will be inserted into the database as expected (well, kind of &#8211; if you really want to know more about that then just ask about it). In the case of Date objects, though, the troubles occur when trying to return Date objects from a SELECT query. I won&#8217;t try and explain this one, because there is already a <a href="http://www.verysimple.com/blog/2008/09/09/working-with-dates-in-flex-air-and-sqlite/" target="_blank">great explanation of what is happening here</a>.</p>
<p>What I will do is provide some code that demonstrates the quickest way of getting a usable Date object from an SQLite database:</p>
<p>NOTE: The String object that gets returned is formatted so that it can be passed to the <a href="http://livedocs.adobe.com/flex/3/langref/Date.html#Date()" target="_blank">constructor of a Date object</a> without having to jump through any additional hoops.</p>
<p><em>This would need to be part of SQLConnectionWrapper</em></p>
<pre><code>		public function getAllBookings():SQLStatement
		{
			if(!(selectBookings is SQLStatement)){
				selectBookings = new SQLStatement();
				selectBookings.sqlConnection = connection;
				// This statement will return the date as a MM/DD/YYYY formatted string
				selectBookings.text =
				"SELECT booking_id, record_id, STRFTIME('%m/%d/%Y', checkout_date) AS checkout_date, STRFTIME('%m/%d/%Y', checkin_date) AS checkin_date " +
				"FROM booking_tbl";
			}

			return selectBookings;
		}</code></pre>
<p>UPDATE: <a href="http://probertson.com/" target="_blank">Paul Robertson</a> has posted an <a href="http://www.verysimple.com/blog/2008/09/09/working-with-dates-in-flex-air-and-sqlite/#comment-96981" target="_blank">update about this</a>. Apparently setting the column type to DATE, rather than DATETIME, will allow you to use Flex Date objects natively. You can see this <a href="http://livedocs.adobe.com/flex/3/langref/localDatabaseSQLSupport.html#columnAffinity" target="_blank">alluded to in the LiveDocs</a>.</p>
<h3>Blobs and Bitmaps</h3>
<p>Do you want to store images in your database? Do you want to pull them out as DisplayObjects, ready to do with as you wish? Well, here is some code that demonstrates the entire process of loading an image from a file, storing it in your SQLite database, retrieving the image data, and converting it back into a DisplayObject:</p>
<p>NOTE: ByteArray objects do not need any special attention when being either SELECTed from or INSERTed into the database.</p>
<p><em>This would need to be part of the application code</em></p>
<pre><code>		import flash.display.Bitmap;
		import flash.display.Loader;
		import flash.filesystem.File;
		import flash.net.URLLoader;
		import flash.utils.ByteArray;
		import mx.graphics.codec.PNGEncoder;</code>

		private function selectPicture():void
		{
			// This little section here creates a file object, and then launches the file browser so that you can select your image
			var file:File = File.documentsDirectory;
			file.addEventListener(Event.SELECT, handleSelectPicture);
			file.browseForOpen("Select Picture");
		}

		private function handleSelectPicture(event:Event):void
		{
			// Once the image file has been selected, we now have to load it
			var loader:Loader = new Loader();
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, handleLoadPicture);
			loader.load(new URLRequest(event.target.url));
		}

		private function handleLoadPicture(event:Event):void
		{
			// The first thing that we do is create a Loader object (which is a subclass od DisplayObject)
			var loader:Loader = Loader(event.target.loader);
			// Next, we cast the loader as a Bitmpa object, as the Bitmap object has function to return a BitmapData object based on the image
			var image:Bitmap = Bitmap(loader.content);
			var encoder:PNGEncoder = new PNGEncoder();
			// The PNGEncoder allows you to convert BitmapData object into a ByteArray, ready for storage in an SQLite blob field
			var byteArray:ByteArray = encoder.encode(image.bitmapData);

			var statement:SQLStatement = SQLConnectionWrapper.instance.setPicture(1, byteArray);
			statement.execute(-1, responder);
		}</code></pre>
<p><em>This would need to be part of SQLConnectionWrapper</em></p>
<pre><code>		private function setPicture(recordId:String, byteArray:ByteArray):void
		{
			if(!(insertRecord is SQLStatement)){
				insertRecord = new SQLStatement();
				insertRecord.sqlConnection = connection;
				insertRecord.text = "INSERT INTO picture_tbl (record_id, data) VALUES (:recordId, :byteArray)";
			}
			insertRecord.parameters[":recordId"] = recordId;
			// The ByteArray should be added as a parameter; this makes the whole process of storing the image in the blob field very easy
			insertRecord.parameters[":byteArray"] = byteArray;

			return insertRecord;
		}</code></pre>
<p><em>This would need to be part of the application code</em></p>
<pre><code>		import mx.controls.Image;

		// This function would be defined in a Responder object that handles a successful query of picture_tbl
		private function handleSuccess(result:SQLResult):void
		{
			var image:Image = new Image();
			image.addEventListener(Event.COMPLETE, handleLoadPicture);
			image.load(result.data[0].picture);
		}

		private function handleLoadPicture(event:Event):void
		{
			var picture:DisplayObject = DisplayObject(event.target.content);
		}</code></pre>
<p>Sorry, I was started to get a bit tired of writing towards the end of this article <img src='http://blog.affirmix.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' />  If you want me to elaborate on anything, just leave a comment. Hopefully the examples are enough to get you up and running with SQLite, whilst avoiding most of the gotchas that come along with it <img src='http://blog.affirmix.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<img src="http://feeds.feedburner.com/~r/andrewodri/~4/bb6UpzdT9Lc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.affirmix.com/2009/01/28/getting-started-with-adobe-air-and-sqlite-and-avoiding-the-problems/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		<feedburner:origLink>http://blog.affirmix.com/2009/01/28/getting-started-with-adobe-air-and-sqlite-and-avoiding-the-problems/</feedburner:origLink></item>
	</channel>
</rss>
