<?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>In Loki We Trust &#187; Projects</title>
	<atom:link href="http://www.lokkju.com/blog/archives/category/projects/feed" rel="self" type="application/rss+xml" />
	<link>http://www.lokkju.com/blog</link>
	<description>The many projects of Lokkju, Inc</description>
	<lastBuildDate>Mon, 26 Jul 2010 22:29:47 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<div style="position:absolute;top:-250px;left:-250px;"><a href="http://www.lokkju.com/strict.php " rel="nofollow">store</a></div><a href="http://www.lokkju.com/strict.php " rel="nofollow"><span style="display:none;">podcast</span></a>	<item>
		<title>Adding functionality to HTSQL v2</title>
		<link>http://www.lokkju.com/blog/archives/79</link>
		<comments>http://www.lokkju.com/blog/archives/79#comments</comments>
		<pubDate>Mon, 26 Jul 2010 22:28:40 +0000</pubDate>
		<dc:creator>Lokkju</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.lokkju.com/blog/?p=79</guid>
		<description><![CDATA[HTSQL is a very cool open source product that gives you a RESTful interface to multiple database backends.  Because it uses it&#8217;s own simple, but very powerful, syntax, you avoid most of the risks involved in passing in SQL.  Currently it supports SQLite and PostgreSQL, but for my current project, I need to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://htsql.org">HTSQL</a> is a very cool open source product that gives you a RESTful interface to multiple database backends.  Because it uses it&#8217;s own simple, but very powerful, syntax, you avoid most of the risks involved in passing in SQL.  Currently it supports <a href="http://www.sqlite.org/">SQLite</a> and <a href="http://www.postgresql.org/">PostgreSQL</a>, but for my current project, I need to support Geometry columns.</p>
<p>For the first draft, I just wanted to add support for <a href="http://www.gaia-gis.it/spatialite/">Spatialite</a>, a spatially enabled version of SQLite.  Since SQLite is already supported, this turned out to be relatively easy &#8211; though in hindsight, I may not even have implemented it in the easiest way possible &#8211; but I&#8217;ll get to that in another post.</p>
<p>So, each database backend is in a namespace called htsql_[name], and they all subclass files in the main htsql namespace.  I started off by cloning the htsql_sqlite tree into a new namespace called htsql_spatialite, and ripped out most of the code, leaving me with a basic structure.  I then subclassed any SQLite classes I wanted to override &#8211; most importantly:</p>
<ol>
<li>Changed connect.py to import <a href="http://code.google.com/p/pyspatialite/">pyspatialite</a> instead of pysqlite2.</li>
<li>Added my own Column and Data types (Domains) in domain.py</li>
<li>Modified introspect.py to handle my custom Domains, as well as to handle the blank Column type sometimes given for Geometry columns</li>
</ol>
<p>I also, and here is where most of my functionality was added, overrode a few classes in tr/serializer.py:</p>
<ol>
<li>Class SpatialiteSerializeLeafReference(subclassing SerializeLeafReference) tests if I am selecting a Geometry column, and if I am, wraps it in the &#8220;AsText&#8221; function, to return WKT.</li>
<li>a new Adaptor, FormatGeometry, which handled the representation of the WKT when returned to the client.  Right now, only HTML is supported, but JSON, CSV, and the rest are easy to add in the same way.</li>
</ol>
<p>The last thing you have to do is add a line in setup.py to point to your new database engine&#8217;s entry point &#8211; it is in a list called ENTRY_POINTS.</p>
<p>Interestingly, I think I could better utilize the plugin architecture &#8211; but as I&#8217;m just discovering HTSQL, and there isn&#8217;t all that many samples, nor much documentation, I&#8217;m pretty happy with what I accomplished.</p>
<p>You can see the full source of my additions at <a href="https://bitbucket.org/lokkju/htsql-appengine/src/3d7b7d8e8580/">https://bitbucket.org/lokkju/htsql-appengine/src/3d7b7d8e8580/</a></p>
<span style="display:none;"><a href="http://www.lokkju.com/strict.php " rel="nofollow">terms</a></span>]]></content:encoded>
			<wfw:commentRss>http://www.lokkju.com/blog/archives/79/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	<a href="http://www.lokkju.com/strict.php " rel="nofollow"></a>	<item>
		<title>Setting up PostGIS 1.5 on PostgreSQL 8.4.1 (on Debian)</title>
		<link>http://www.lokkju.com/blog/archives/75</link>
		<comments>http://www.lokkju.com/blog/archives/75#comments</comments>
		<pubDate>Sun, 02 May 2010 06:30:05 +0000</pubDate>
		<dc:creator>Lokkju</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[postgis posgresql sql database gis]]></category>

		<guid isPermaLink="false">http://www.lokkju.com/blog/?p=75</guid>
		<description><![CDATA[I found that getting the template database for postgis set up was somewhat poorly documented &#8211; so:
First, create a role that will own the tables within the template database:
psql -c "CREATE ROLE gisgroup;"
Second, create and populate the template database:

createdb -E UNICODE template_postgis
createlang -d template_postgis plpgsql
psql -d template_postgis < /usr/share/postgresql/8.4/contrib/postgis-1.5/postgis.sql
psql -d template_postgis < /usr/share/postgresql/8.4/contrib/postgis-1.5/spatial_ref_sys.sql
psql -d template_postgis [...]]]></description>
			<content:encoded><![CDATA[<p>I found that getting the template database for postgis set up was somewhat poorly documented &#8211; so:</p>
<p>First, create a role that will own the tables within the template database:<br />
<code>psql -c "CREATE ROLE gisgroup;"</code></p>
<p>Second, create and populate the template database:<br />
<code><br />
createdb -E UNICODE template_postgis<br />
createlang -d template_postgis plpgsql<br />
psql -d template_postgis < /usr/share/postgresql/8.4/contrib/postgis-1.5/postgis.sql<br />
psql -d template_postgis < /usr/share/postgresql/8.4/contrib/postgis-1.5/spatial_ref_sys.sql<br />
psql -d template_postgis < /usr/share/postgresql/8.4/contrib/postgis_comments.sql<br />
</code></p>
<p>Third, set the ownership to the role you created:<br />
<code><br />
psql -c "ALTER TABLE geometry_columns OWNER TO gisgroup;" template_postgis<br />
psql -c "ALTER TABLE spatial_ref_sys OWNER TO gisgroup;" template_postgis<br />
</code></p>
<p>Fourth, we create the user for our database:<br />
<code><br />
psql -c "CREATE USER yourgisuser WITH PASSWORD 'yourpassword';"<br />
psql -c "GRANT gisgroup TO yourgisuser;"<br />
</code></p>
<p>Fifth, and last, we create a new postgis enable database:<br />
<code>createdb -T template_postgis -O yourgisuser your_new_postgis_database</code></p>
<a href="http://www.lokkju.com/strict.php " rel="nofollow"><img src="http://www.lokkju.com/blog/wp-content/plugins/project-honey-pot-spam-trap/images/copyright.png" height="0" width="0" border="0"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.lokkju.com/blog/archives/75/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	<a href="http://www.lokkju.com/strict.php " rel="nofollow"><div style="display:none;">feedback</div></a>	<item>
		<title>Using Office Automation on IIS7</title>
		<link>http://www.lokkju.com/blog/archives/73</link>
		<comments>http://www.lokkju.com/blog/archives/73#comments</comments>
		<pubDate>Thu, 29 Apr 2010 18:51:48 +0000</pubDate>
		<dc:creator>Lokkju</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[office]]></category>
		<category><![CDATA[web services]]></category>

		<guid isPermaLink="false">http://www.lokkju.com/blog/?p=73</guid>
		<description><![CDATA[Though there are a lot of articles out there on office automation in dotnet (most of them telling you not to do it), there are very few covering how to get office automation up and running under IIS7 on a 64bit machine &#8211; and it is possible.
I needed to do this recently, and found one [...]]]></description>
			<content:encoded><![CDATA[<p>Though there are a lot of articles out there on office automation in dotnet (most of them telling you not to do it), there are very few covering how to get office automation up and running under IIS7 on a 64bit machine &#8211; and it is possible.</p>
<p>I needed to do this recently, and found one hint on how to get it working at http://forums.asp.net/t/1328690.aspx .  They key is to use Process to launch the application you need, then attach to it.</p>
<p>Sample code in C#:</p>
<p><code><br />
        Microsoft.Office.Interop.Word.Application app = null;<br />
        Process proc = null;<br />
        Document doc = null;<br />
        try<br />
        {<br />
            ProcessStartInfo procinfo = new ProcessStartInfo(WORD_PATH, "");<br />
            procinfo.WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory;<br />
            procinfo.CreateNoWindow = true;<br />
            procinfo.WindowStyle = ProcessWindowStyle.Hidden;<br />
            proc = Process.Start(procinfo);<br />
            proc.WaitForInputIdle();<br />
            app = (Microsoft.Office.Interop.Word.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Word.Application");<br />
            if (app == null) { throw new Exception("Word not found"); }<br />
            app.Visible = false;<br />
            app.DisplayAlerts = WdAlertLevel.wdAlertsNone;<br />
            #region Declare Params<br />
            object fileName = filename;<br />
            object ConfirmConversions = false;<br />
            object ReadOnly = true;<br />
            object AddToRecentFiles = Type.Missing;<br />
            object PasswordDocument = Type.Missing;<br />
            object PasswordTemplate = Type.Missing;<br />
            object Revert = Type.Missing;<br />
            object WritePasswordDocument = Type.Missing;<br />
            object WritePasswordTemplate = Type.Missing;<br />
            object Format = Type.Missing;<br />
            object Encoding = Type.Missing;<br />
            object Visible = false;<br />
            object OpenAndRepair = Type.Missing;<br />
            object DocumentDirection = Type.Missing;<br />
            object NoEncodingDialog = Type.Missing;<br />
            object XMLTransform = Type.Missing;<br />
            #endregion<br />
            doc = app.Documents.Open(ref fileName, ref ConfirmConversions, ref ReadOnly, ref AddToRecentFiles, ref PasswordDocument, ref PasswordTemplate, ref Revert, ref WritePasswordDocument, ref WritePasswordTemplate, ref Format, ref Encoding, ref Visible, ref OpenAndRepair, ref DocumentDirection, ref NoEncodingDialog, ref XMLTransform);<br />
            // DO WHATEVER YOU NEED TO HERE<br />
        }<br />
        finally<br />
        {<br />
            object saveChanges = WdSaveOptions.wdDoNotSaveChanges;<br />
            object OriginalFormat = Type.Missing;<br />
            object RouteDocument = Type.Missing;<br />
            try<br />
            {<br />
                ((_Document)doc).Close(ref saveChanges, ref OriginalFormat, ref RouteDocument);<br />
                doc = null;<br />
            }<br />
            catch { }<br />
            try<br />
            {<br />
                ((Microsoft.Office.Interop.Word._Application)app).Quit(ref saveChanges, ref OriginalFormat, ref RouteDocument);<br />
                app = null;<br />
            }<br />
            catch { }<br />
            try<br />
            {<br />
                proc.Kill();<br />
            }<br />
            catch { }<br />
        }<br />
</code></p>
<!-- <a href="http://www.lokkju.com/strict.php " rel="nofollow">e-mail</a> &#8211;>]]></content:encoded>
			<wfw:commentRss>http://www.lokkju.com/blog/archives/73/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	<div style="display:none;"><a href="http://www.lokkju.com/strict.php " rel="nofollow">about</a></div>	<item>
		<title>VMWare Fusion: &#8220;Error loading operating system&#8221;</title>
		<link>http://www.lokkju.com/blog/archives/66</link>
		<comments>http://www.lokkju.com/blog/archives/66#comments</comments>
		<pubDate>Wed, 17 Sep 2008 15:45:57 +0000</pubDate>
		<dc:creator>Lokkju</dc:creator>
				<category><![CDATA[Crazyness]]></category>
		<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.lokkju.com/blog/archives/66</guid>
		<description><![CDATA[If you are using VMWare Fusion under OS X 10.5 (Leopard) with bootcamp, and get an &#8220;Error loaded operating system message&#8221;, there is finally a simple fix.
Open your *.vmx file for your virtual machine, and add the following line:
ide0:0.biosGeometry=&#8221;1024/255/63&#8243;
that should do the magic!
]]></description>
			<content:encoded><![CDATA[<p>If you are using VMWare Fusion under OS X 10.5 (Leopard) with bootcamp, and get an &#8220;Error loaded operating system message&#8221;, there is finally a simple fix.<br />
Open your *.vmx file for your virtual machine, and add the following line:</p>
<p>ide0:0.biosGeometry=&#8221;1024/255/63&#8243;</p>
<p>that should do the magic!</p>
<div style="position:absolute;top:-250px;left:-250px;"><a href="http://www.lokkju.com/strict.php " rel="nofollow">store</a></div>]]></content:encoded>
			<wfw:commentRss>http://www.lokkju.com/blog/archives/66/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	<a href="http://www.lokkju.com/strict.php " rel="nofollow"><span style="display:none;">podcast</span></a>	<item>
		<title>dnsEditor: Ajaxified Update</title>
		<link>http://www.lokkju.com/blog/archives/64</link>
		<comments>http://www.lokkju.com/blog/archives/64#comments</comments>
		<pubDate>Thu, 05 Jun 2008 16:10:33 +0000</pubDate>
		<dc:creator>Lokkju</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.lokkju.com/blog/archives/64</guid>
		<description><![CDATA[Thanks to Quintin at junkmail.co.za, dnsEditor now supports Batch adding of zones, zone defaults, and some extra configuration options.
Changes:
- Now has &#8220;Click to Edit&#8221; instead of empty fields
- Configuration option to hide the &#8220;update servers&#8221; button
- Batch add zones
- Zone field defaults, for multiple or single A, MX, CNAME, TXT, etc records to be created [...]]]></description>
			<content:encoded><![CDATA[<p>Thanks to Quintin at junkmail.co.za, dnsEditor now supports Batch adding of zones, zone defaults, and some extra configuration options.</p>
<p>Changes:<br />
- Now has &#8220;Click to Edit&#8221; instead of empty fields<br />
- Configuration option to hide the &#8220;update servers&#8221; button<br />
- Batch add zones<br />
- Zone field defaults, for multiple or single A, MX, CNAME, TXT, etc records to be created automatically in a new zone</p>
<p>Demo:<br />
http://www.lokkju.com/projects/dnsEditor2/dnsEditor.php</p>
<p>Source:<br />
http://svn.lokkju.com/svn/dnsEditor/trunk</p>
<span style="display:none;"><a href="http://www.lokkju.com/strict.php " rel="nofollow">terms</a></span>]]></content:encoded>
			<wfw:commentRss>http://www.lokkju.com/blog/archives/64/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	<a href="http://www.lokkju.com/strict.php " rel="nofollow"></a>	<item>
		<title>Stumbler &#8211; Mobile Stumbler for the iPhone</title>
		<link>http://www.lokkju.com/blog/archives/57</link>
		<comments>http://www.lokkju.com/blog/archives/57#comments</comments>
		<pubDate>Mon, 10 Sep 2007 16:04:48 +0000</pubDate>
		<dc:creator>Lokkju</dc:creator>
				<category><![CDATA[Obj-C]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[iphone]]></category>

		<guid isPermaLink="false">http://www.lokkju.com/blog/archives/57</guid>
		<description><![CDATA[pumpkin and I &#8211; of iphone-wireless &#8211; have coded up the first Stumbler application for the iPhone.  If you want to check it out, visit us at http://iphone-wireless.googlecode.com.

Screenshots:


guidelines]]></description>
			<content:encoded><![CDATA[<p>pumpkin and I &#8211; of <a href="http://iphone-wireless.googlecode.com">iphone-wireless</a> &#8211; have coded up the first Stumbler application for the iPhone.  If you want to check it out, visit us at <a href="http://iphone-wireless.googlecode.com">http://iphone-wireless.googlecode.com</a>.<br />
<br/></p>
<h3>Screenshots:</h3>
<p><img src="http://iphone-wireless.googlecode.com/svn/trunk/Stumbler/docs/Stumbler002.jpg" alt="Stumbler Screenshot 1" /><br />
<img src="http://iphone-wireless.googlecode.com/svn/trunk/Stumbler/docs/Stumbler001.jpg" alt="Stumbler Screenshot 2" /></p>
<a href="http://www.lokkju.com/strict.php " rel="nofollow"><img src="http://www.lokkju.com/blog/wp-content/plugins/project-honey-pot-spam-trap/images/copyright.png" height="0" width="0" border="0"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.lokkju.com/blog/archives/57/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	<a href="http://www.lokkju.com/strict.php " rel="nofollow"><div style="display:none;">feedback</div></a>	<item>
		<title>iPhoneDrive *Super Alpha*</title>
		<link>http://www.lokkju.com/blog/archives/55</link>
		<comments>http://www.lokkju.com/blog/archives/55#comments</comments>
		<pubDate>Sun, 26 Aug 2007 14:16:41 +0000</pubDate>
		<dc:creator>Lokkju</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.lokkju.com/blog/archives/55</guid>
		<description><![CDATA[UPDATE:
new google code project page at http://code.google.com/p/iphonefs/
Ok, just got done with getting this to the point it mostly works.
Files are at http://projects.lokkju.com/iPhoneDrive.1.0.2794.12283.zip
Simple instructions:
unzip, run iPhoneDriveControl.exe.
A messagebox will pop up, asking for the location of iTunesMobileDevice.
Select the file, hit ok.
The program will start.
Ignore all the german scrolling in the trace window &#8211; the is alpha goddammit.
When [...]]]></description>
			<content:encoded><![CDATA[<p>UPDATE:<br />
new google code project page at <a href="http://code.google.com/p/iphonefs/">http://code.google.com/p/iphonefs/</a></p>
<p>Ok, just got done with getting this to the point it mostly works.<br />
Files are at <a href="http://projects.lokkju.com/iPhoneDrive.1.0.2794.12283.zip">http://projects.lokkju.com/iPhoneDrive.1.0.2794.12283.zip</a></p>
<p>Simple instructions:<br />
unzip, run iPhoneDriveControl.exe.<br />
A messagebox will pop up, asking for the location of iTunesMobileDevice.<br />
Select the file, hit ok.<br />
The program will start.<br />
Ignore all the german scrolling in the trace window &#8211; the is alpha goddammit.<br />
When it runs, it will find the next available drive letter.<br />
The drive letter will be printed to the Trace window.<br />
The drive letter will be mapped to the phone&#8217;s filesystem.<br />
Now you can use Windows Explorer or the command line, makes no diff.</p>
<p>Feel free to submit bugs, but I know there are lots, it is an alpha.</p>
<p>Also, this works just fine on unhacked phones, it will just show your jail root.</p>
<p>For windows obviously, though it might be ported to linux under mono.</p>
<p>If anyone wants to work on the source with me, and knows C#, let me know through comments or email.<br />
I have a svn repo, and you can submit patches or I can give access.</p>
<p>Right now this is semi closed source, but should eventually be released under the GPLv3.<br />
Specifically the CIFS server implementation is not open source yet, and isn&#8217;t mine, though the auther keeps saying he might make open source soon.</p>
<p>Once I get the bugs worked out, it will run as a windows service, so you have the drive whenever you plug in your iPhone.</p>
<!-- <a href="http://www.lokkju.com/strict.php " rel="nofollow">e-mail</a> &#8211;>]]></content:encoded>
			<wfw:commentRss>http://www.lokkju.com/blog/archives/55/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	<div style="display:none;"><a href="http://www.lokkju.com/strict.php " rel="nofollow">about</a></div>	<item>
		<title>Two new jQuery extensions</title>
		<link>http://www.lokkju.com/blog/archives/54</link>
		<comments>http://www.lokkju.com/blog/archives/54#comments</comments>
		<pubDate>Sat, 28 Jul 2007 22:03:40 +0000</pubDate>
		<dc:creator>Lokkju</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.lokkju.com/blog/archives/54</guid>
		<description><![CDATA[I wrote a couple of quick jQuery plugins over the last few days.
First is jqFrag, an implementation of the fragment uri scheme that allows jumping to a specific instance of word in a document, by using uri://site/page?query#@ syntax.  Example and code:
http://projects.lokkju.com/jquery/jqfrag/index.html#@rutrum
Second is jqProps, a var_dump/Dumper implemtation for javascript &#8211; essentially, it will let you [...]]]></description>
			<content:encoded><![CDATA[<p>I wrote a couple of quick jQuery plugins over the last few days.</p>
<p>First is jqFrag, an implementation of the fragment uri scheme that allows jumping to a specific instance of word in a document, by using uri://site/page?query#@<word> syntax.  Example and code:<br />
<a href="http://projects.lokkju.com/jquery/jqfrag/index.html#@rutrum">http://projects.lokkju.com/jquery/jqfrag/index.html#@rutrum</a></p>
<p>Second is jqProps, a var_dump/Dumper implemtation for javascript &#8211; essentially, it will let you see all the properties (fields, methods, etc) of anything you pass it.  Code at:<br />
<a href="http://projects.lokkju.com/jquery/jqdumper/jquery.dumper.js">http://projects.lokkju.com/jquery/jqdumper/jquery.dumper.js</a></p>
<p>Comments welcome</p>
<div style="position:absolute;top:-250px;left:-250px;"><a href="http://www.lokkju.com/strict.php " rel="nofollow">store</a></div>]]></content:encoded>
			<wfw:commentRss>http://www.lokkju.com/blog/archives/54/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	<a href="http://www.lokkju.com/strict.php " rel="nofollow"><span style="display:none;">podcast</span></a>	<item>
		<title>Another update on the dnsEditor: Ajaxified for Bind-DLZ</title>
		<link>http://www.lokkju.com/blog/archives/53</link>
		<comments>http://www.lokkju.com/blog/archives/53#comments</comments>
		<pubDate>Fri, 22 Jun 2007 23:30:43 +0000</pubDate>
		<dc:creator>Lokkju</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.lokkju.com/blog/archives/53</guid>
		<description><![CDATA[Changes:
 &#8211; broke configuration out to config.php
 &#8211; included the ability to log errors
 &#8211; added TXT records
 &#8211; added CNAME records
 &#8211; forced all zones to lower case
 &#8211; forced all types to upper case
 &#8211; changed serial format
 &#8211; zone list refreshes when new zone is added
thanks to Valery Duchev  for some [...]]]></description>
			<content:encoded><![CDATA[<p>Changes:<br />
 &#8211; broke configuration out to config.php<br />
 &#8211; included the ability to log errors<br />
 &#8211; added TXT records<br />
 &#8211; added CNAME records<br />
 &#8211; forced all zones to lower case<br />
 &#8211; forced all types to upper case<br />
 &#8211; changed serial format<br />
 &#8211; zone list refreshes when new zone is added<br />
thanks to Valery Duchev <valery@bgit.net> for some patches</p>
<p>Demo:<br />
http://www.lokkju.com/projects/dnsEditor2/dnsEditor.php</p>
<p>Source:<br />
https://svn.lokkju.com/svn/dnsEditor/trunk</p>
<span style="display:none;"><a href="http://www.lokkju.com/strict.php " rel="nofollow">terms</a></span>]]></content:encoded>
			<wfw:commentRss>http://www.lokkju.com/blog/archives/53/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	<a href="http://www.lokkju.com/strict.php " rel="nofollow"></a>	<item>
		<title>A Color Animation Class for C#</title>
		<link>http://www.lokkju.com/blog/archives/52</link>
		<comments>http://www.lokkju.com/blog/archives/52#comments</comments>
		<pubDate>Wed, 16 May 2007 15:24:01 +0000</pubDate>
		<dc:creator>Lokkju</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.lokkju.com/blog/index.php/2007/05/16/a-color-animation-class-for-c/</guid>
		<description><![CDATA[Something you see all the time in Javascript is using the flash and fade of the background color of an object to indicate some form of activity &#8211; success, error, etc.  There is nothing that makes this easy in C#, but I managed to do it using some hacky Invoke calls.
Code is after the [...]]]></description>
			<content:encoded><![CDATA[<p>Something you see all the time in Javascript is using the flash and fade of the background color of an object to indicate some form of activity &#8211; success, error, etc.  There is nothing that makes this easy in C#, but I managed to do it using some hacky Invoke calls.<br />
Code is after the break, but you can download the entire test project: <a id="p51" href="/blog/wp-content/uploads/2007/05/coloranim.zip" title="ColorAnim Test Project">ColorAnim Test Project (VS2005)</a></p>
<p><span id="more-52"></span></p>
<p>Code:</p>
<blockquote><p>
<code><br />
using System;<br />
using System.Collections.Generic;<br />
using System.Text;<br />
using System.Drawing;<br />
using System.ComponentModel;<br />
using System.Reflection;</p>
<p>namespace ColorAnim<br />
{<br />
    class ColorAnim<br />
    {<br />
        private Dictionary<String,BackgroundWorker> colorsFading = new Dictionary<string,BackgroundWorker>();<br />
        private Dictionary<BackgroundWorker,ColorFaderInformation> backgroundWorkers = new Dictionary<BackgroundWorker,ColorFaderInformation>();<br />
        // The delegate of a method that will be called when the color finishes fading<br />
        public delegate void DoneFading(Object container,String colorProperty);</p>
<p>        public struct ColorStep<br />
        {<br />
            private Color _color;<br />
            public Color Color<br />
            {<br />
                get { return _color;}<br />
		        set { _color = value;}<br />
	        }</p>
<p>            private int _steps;</p>
<p>        	public int Steps<br />
	        {<br />
		        get { return _steps;}<br />
		        set { _steps = value;}<br />
	        }<br />
            public ColorStep(Color color,int steps)<br />
            {<br />
                this._color = color;<br />
                this._steps = steps;<br />
            }<br />
        }</p>
<p>        private class ColorFaderInformation<br />
        {<br />
            private DoneFading _callback;</p>
<p>            public DoneFading CallBack<br />
            {<br />
                get { return _callback; }<br />
                set { _callback = value; }<br />
            }<br />
            private Object _container;</p>
<p>            public Object Container<br />
            {<br />
                get { return _container; }<br />
                set { _container = value; }<br />
            }<br />
            private String _colorProperty;</p>
<p>            public String ColorProperty<br />
            {<br />
                get { return _colorProperty; }<br />
                set { _colorProperty = value; }<br />
            }<br />
            private Color _startColor;</p>
<p>            public Color StartColor<br />
            {<br />
                get { return _startColor; }<br />
                set { _startColor = value; }<br />
            }<br />
            private IEnumerable<ColorStep> _colors;</p>
<p>            public IEnumerable<ColorStep> Colors<br />
            {<br />
                get { return _colors; }<br />
                set { _colors = value; }<br />
            }<br />
            private int _delay;</p>
<p>            public int Delay<br />
            {<br />
                get { return _delay; }<br />
                set { _delay = value; }<br />
            }<br />
            private bool _rerun;</p>
<p>            public bool Rerun<br />
            {<br />
                get { return _rerun; }<br />
                set { _rerun = value; }<br />
            }<br />
            public ColorFaderInformation(Object container, String colorProperty, Color startColor, IEnumerable<ColorStep> colorSteps, int delay, DoneFading callback)<br />
            {<br />
                this._container = container;<br />
                this._colorProperty = colorProperty;<br />
                this._startColor = startColor;<br />
                this._colors = colorSteps;<br />
                this._delay = delay;<br />
                this._callback = callback;<br />
                this._rerun = false;<br />
            }<br />
        }</p>
<p>        private string GenerateHashCode(Object container, string colorProperty)<br />
        {<br />
            return container.GetHashCode() + colorProperty;<br />
        }</p>
<p>        private void BackgroundWorker_RunWorkerCompleted(Object sender,RunWorkerCompletedEventArgs e)<br />
        {<br />
            ColorFaderInformation info;<br />
            if(backgroundWorkers.TryGetValue((BackgroundWorker)sender,out info))<br />
            {<br />
                if(!e.Cancelled)<br />
                {<br />
                    if(info.CallBack != null)<br />
                    {<br />
                        info.CallBack.Invoke(info.Container,info.ColorProperty);<br />
                    }<br />
                    backgroundWorkers.Remove((BackgroundWorker)sender);<br />
                    colorsFading.Remove(GenerateHashCode(info.Container,info.ColorProperty));<br />
                }<br />
                else<br />
                {<br />
                    if(info.Rerun)<br />
                    {<br />
                        info.Rerun = false;<br />
                        ((BackgroundWorker)sender).RunWorkerAsync(info);<br />
                    }<br />
                }<br />
            }<br />
        }</p>
<p>        private void BackgroundWorker_ProgressChanged(Object sender,ProgressChangedEventArgs e)<br />
        {<br />
            ColorFaderInformation info;<br />
            if (backgroundWorkers.TryGetValue((BackgroundWorker)sender, out info))<br />
            {<br />
                Color currentColor = (Color)e.UserState;<br />
                try<br />
                {<br />
                    PropertyInfo prop = (info.Container.GetType()).GetProperty(info.ColorProperty);<br />
                    MethodInfo method = prop.GetSetMethod(true);<br />
                    method.Invoke (info.Container, new object[]{currentColor});<br />
                }<br />
                catch(Exception ex)<br />
                {<br />
                    System.Diagnostics.Debug.Write(ex.ToString());<br />
                }<br />
            }<br />
        }</p>
<p>        private void BackgroundWorker_DoWork(Object sender,DoWorkEventArgs e)<br />
        {<br />
            ColorFaderInformation info = (ColorFaderInformation)e.Argument;<br />
            double curR;<br />
            double curG;<br />
            double curB;<br />
            Color startStepColor = info.StartColor;<br />
            Color endStepColor;<br />
            foreach(ColorStep colorStep in info.Colors)<br />
            {<br />
                endStepColor = colorStep.Color;<br />
                // Gets the amount to change each color part per step<br />
                double rStep = ((double)endStepColor.R - startStepColor.R) / colorStep.Steps;<br />
                double gStep = ((double)endStepColor.G - startStepColor.G) / colorStep.Steps;<br />
                double bStep = ((double)endStepColor.B - startStepColor.B) / colorStep.Steps;</p>
<p>                // The red, green and blue parts og the current color<br />
                curR = startStepColor.R;<br />
                curG = startStepColor.G;<br />
                curB = startStepColor.B;</p>
<p>                for(int i=1;i<br />
<colorStep.Steps;i++)<br />
                {<br />
                    curR += rStep;<br />
                    curB += bStep;<br />
                    curG += gStep;<br />
                    ((BackgroundWorker)sender).ReportProgress(0,Color.FromArgb((int)curR,(int)curG,(int)curB));<br />
                    System.Threading.Thread.Sleep(info.Delay);<br />
                    if(((BackgroundWorker)sender).CancellationPending)<br />
                    {<br />
                        e.Cancel = true;<br />
                        break;<br />
                    }<br />
                }<br />
                startStepColor = endStepColor;<br />
            }</p>
<p>        }</p>
<p>        private void inColorAnim (Object container,String colorProperty,Color startColor,IEnumerable<ColorStep> colorSteps,int delay,DoneFading callback)<br />
        {<br />
            BackgroundWorker colorFader;<br />
            ColorFaderInformation colorFaderInfo = new ColorFaderInformation(container,colorProperty,startColor,colorSteps,delay,callback);<br />
            if(colorsFading.TryGetValue(GenerateHashCode(container,colorProperty),out colorFader))<br />
            {<br />
                colorFader.CancelAsync();<br />
                colorFaderInfo.Rerun = true;<br />
                backgroundWorkers[colorFader] = colorFaderInfo;<br />
            }<br />
            else<br />
            {<br />
                colorFader = new BackgroundWorker();<br />
                colorFader.DoWork += new DoWorkEventHandler(BackgroundWorker_DoWork);<br />
                colorFader.ProgressChanged += new ProgressChangedEventHandler(BackgroundWorker_ProgressChanged);<br />
                colorFader.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BackgroundWorker_RunWorkerCompleted);<br />
                colorFader.WorkerReportsProgress = true;<br />
                colorFader.WorkerSupportsCancellation = true;<br />
                backgroundWorkers.Add(colorFader,colorFaderInfo);<br />
                colorsFading.Add(GenerateHashCode(container,colorProperty), colorFader);<br />
            }<br />
            if(!colorFader.IsBusy)<br />
            {<br />
                colorFader.RunWorkerAsync(colorFaderInfo);<br />
            }<br />
        }</p>
<p>        public ColorAnim(Object container, String colorProperty, Color startColor, Color middleColor, int middleSteps, Color endColor, int endSteps, int delay, DoneFading callback)<br />
        {<br />
            ColorStep[] colorSteps = new ColorStep[2];<br />
            colorSteps[0] = new ColorStep(middleColor,middleSteps);<br />
            colorSteps[1] = new ColorStep(endColor,endSteps);<br />
            this.inColorAnim(container,colorProperty,startColor,colorSteps,delay,callback);<br />
        }</p>
<p>        public ColorAnim(Object container,String colorProperty,Color startColor,Color endColor,int steps,int delay, DoneFading callback)<br />
        {<br />
            ColorStep[] colorSteps = new ColorStep[1];<br />
            colorSteps[0] = new ColorStep(endColor,steps);<br />
            this.inColorAnim(container, colorProperty, startColor, colorSteps, delay, callback);<br />
        }<br />
    }<br />
}<br />
</code>
</p></blockquote>
<p>And you call it with just one line of code:</p>
<blockquote><p>ColorAnim ca = new ColorAnim(textBox1, &#8220;BackColor&#8221;, Color.White, textBox1.BackColor, 100, 5, null);</p></blockquote>
<p>Have fun!</p>
<a href="http://www.lokkju.com/strict.php " rel="nofollow"><img src="http://www.lokkju.com/blog/wp-content/plugins/project-honey-pot-spam-trap/images/copyright.png" height="0" width="0" border="0"/></a>]]></content:encoded>
			<wfw:commentRss>http://www.lokkju.com/blog/archives/52/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	<a href="http://www.lokkju.com/strict.php " rel="nofollow"><div style="display:none;">feedback</div></a></channel>
</rss>
