<?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>BDC Software</title>
	<atom:link href="http://www.bdcsoftware.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.bdcsoftware.com</link>
	<description>Experience Matters</description>
	<lastBuildDate>Fri, 04 Jun 2010 17:55:46 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Pys60 App Skeleton</title>
		<link>http://www.bdcsoftware.com/pys60-app-skeleton/</link>
		<comments>http://www.bdcsoftware.com/pys60-app-skeleton/#comments</comments>
		<pubDate>Tue, 20 Oct 2009 17:29:28 +0000</pubDate>
		<dc:creator>raf</dc:creator>
				<category><![CDATA[pyS60]]></category>

		<guid isPermaLink="false">http://www.bdcsoftware.com/?p=451</guid>
		<description><![CDATA[Over the development of a few applications with pys60 I have standardized on an app skeleton that simplifies and speeds-up the initial process of getting something going. The basic idea is to have an application shell up and running on various environments without needing a lot of configuration changes as quickly as possible. By default [...]]]></description>
			<content:encoded><![CDATA[<p>Over the development of a few applications with pys60 I have standardized on an app skeleton that simplifies and speeds-up the initial process of getting something going. The basic idea is to have an application shell up and running on various environments without needing a lot of configuration changes as quickly as possible. By default the app will run fine in the following environments without any changes: emulator, phone (script shell), phone (stand-alone).</p>
<p>The core idea behind the skeleton is that of a simple launcher and a directory holding the application. The launcher is responsible for setting the import paths based on the environment and bootstraping the application with generic exception handling. The actual application code is in a separate module. The application and data views are also based on individual classes. This allows for simple navigation between views / screens even in situations where the hierarchy is quite complex.</p>
<p>The <a href='http://www.bdcsoftware.com/wp-content/uploads/2009/10/app_skeleton.zip'>sample skeleton</a> project zip file has the following contents:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">app_myapp.py    
AppFolder
    logger.py
    debug.py
    myapp.py</pre></div></div>

<p>Here is how you can get started with your own app in seconds in a emulator (the steps below are based on N97 emulator installed in default location and the paths will have to change to reflect any other emulator editions) :</p>
<ol>
<li>Unzip the <a href='http://www.bdcsoftware.com/wp-content/uploads/2009/10/app_skeleton.zip'>app_skeleton</a> into a temp folder</li>
<li>Copy app_myapp.py to python examples folder (in my case here it would be c:\s60&#8230;.)</li>
<li>Copy the app folder to any location on the emulator C: drive. I usually place the app directory in the c:\data\ folder</li>
</ol>
<p>At this point you can either launch the app from the Python Script Shell</p>
<p>Hopefully the launcher code is self explanatory and will illustrate whats happening behind the scenes when you launch the app:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
</pre></td><td class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;MyApp Name&quot;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> appuifw
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>
<span style="color: #ff7700;font-weight:bold;">import</span> e32
&nbsp;
<span style="color: #ff7700;font-weight:bold;">try</span>:
    <span style="color: #ff7700;font-weight:bold;">global</span> DATA_PATH
    <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Loading, please wait...&quot;</span>
    e32.<span style="color: black;">ao_sleep</span><span style="color: black;">&#40;</span>.1<span style="color: black;">&#41;</span>
    e32.<span style="color: black;">ao_yield</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> e32.<span style="color: black;">in_emulator</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> e32.<span style="color: black;">pys60_version_info</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> == <span style="color: #ff4500;">1</span> <span style="color: #ff7700;font-weight:bold;">and</span> e32.<span style="color: black;">pys60_version_info</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">&lt;</span> <span style="color: #ff4500;">5</span>:
            DATA_PATH = <span style="color: #483d8b;">'c:<span style="color: #000099; font-weight: bold;">\\</span>python<span style="color: #000099; font-weight: bold;">\\</span>myapp_folder<span style="color: #000099; font-weight: bold;">\\</span>'</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            DATA_PATH = <span style="color: #483d8b;">'c:<span style="color: #000099; font-weight: bold;">\\</span>data<span style="color: #000099; font-weight: bold;">\\</span>python<span style="color: #000099; font-weight: bold;">\\</span>myapp_folder<span style="color: #000099; font-weight: bold;">\\</span>'</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        <span style="color: #808080; font-style: italic;">#create app dir if neccessery</span>
        drive = <span style="color: #483d8b;">'e'</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">exists</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'e:'</span><span style="color: black;">&#41;</span>:
            drive = <span style="color: #483d8b;">'e'</span>
            DATA_PATH = <span style="color: #483d8b;">'e:<span style="color: #000099; font-weight: bold;">\\</span>data<span style="color: #000099; font-weight: bold;">\\</span>myapp_folder'</span>
        <span style="color: #ff7700;font-weight:bold;">elif</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">exists</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'c:'</span><span style="color: black;">&#41;</span>:
            drive = <span style="color: #483d8b;">'c'</span>
            DATA_PATH = <span style="color: #483d8b;">'c:<span style="color: #000099; font-weight: bold;">\\</span>data<span style="color: #000099; font-weight: bold;">\\</span>myapp_folder'</span>
        <span style="color: #ff7700;font-weight:bold;">try</span>:
            <span style="color: #dc143c;">os</span>.<span style="color: black;">makedirs</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'%s:<span style="color: #000099; font-weight: bold;">\\</span>data<span style="color: #000099; font-weight: bold;">\\</span>myapp_folder'</span> <span style="color: #66cc66;">%</span> drive<span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">except</span>: <span style="color: #ff7700;font-weight:bold;">pass</span>
        <span style="color: #808080; font-style: italic;">#also add current script path (if we are running from a sis file)</span>
        <span style="color: #dc143c;">sys</span>.<span style="color: black;">path</span>.<span style="color: black;">insert</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>,<span style="color: #dc143c;">os</span>.<span style="color: black;">getcwd</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;">#not 100% sure this is needed</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">exists</span><span style="color: black;">&#40;</span>DATA_PATH<span style="color: black;">&#41;</span> == <span style="color: #008000;">False</span>:
        appuifw.<span style="color: black;">note</span><span style="color: black;">&#40;</span>u<span style="color: #483d8b;">'Unable to set data directory. Exiting Application.'</span><span style="color: black;">&#41;</span>
        e32.<span style="color: black;">ao_sleep</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">3</span><span style="color: black;">&#41;</span>
        appuifw.<span style="color: black;">app</span>.<span style="color: black;">set_exit</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        <span style="color: #dc143c;">sys</span>.<span style="color: black;">exit</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">path</span> = <span style="color: #dc143c;">sys</span>.<span style="color: black;">path</span> + <span style="color: black;">&#91;</span>DATA_PATH<span style="color: black;">&#93;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">import</span> myapp
&nbsp;
    old_title = appuifw.<span style="color: black;">app</span>.<span style="color: black;">title</span>
    exit_handler = appuifw.<span style="color: black;">app</span>.<span style="color: black;">exit_key_handler</span>
&nbsp;
    appuifw.<span style="color: black;">app</span>.<span style="color: black;">screen</span> = <span style="color: #483d8b;">'normal'</span>
&nbsp;
    menu = appuifw.<span style="color: black;">app</span>.<span style="color: black;">menu</span>
&nbsp;
    myApp = myapp.<span style="color: black;">App</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    myApp.<span style="color: black;">run</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    myApp.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> e32.<span style="color: black;">in_emulator</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        appuifw.<span style="color: black;">app</span>.<span style="color: black;">title</span> = old_title
        appuifw.<span style="color: black;">app</span>.<span style="color: black;">exit_key_handler</span> = exit_handler
        appuifw.<span style="color: black;">app</span>.<span style="color: black;">menu</span> = menu
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        appuifw.<span style="color: black;">app</span>.<span style="color: black;">title</span> = old_title
        appuifw.<span style="color: black;">menu</span> = <span style="color: #008000;">None</span>
<span style="color: #ff7700;font-weight:bold;">except</span>:
    <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
    <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">traceback</span>
    <span style="color: #ff7700;font-weight:bold;">import</span> e32
    <span style="color: #ff7700;font-weight:bold;">import</span> appuifw
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> e32.<span style="color: black;">in_emulator</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> e32.<span style="color: black;">pys60_version_info</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> == <span style="color: #ff4500;">1</span> <span style="color: #ff7700;font-weight:bold;">and</span> e32.<span style="color: black;">pys60_version_info</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">&lt;</span> <span style="color: #ff4500;">5</span>:
            DATA_PATH = <span style="color: #483d8b;">'c:<span style="color: #000099; font-weight: bold;">\\</span>python<span style="color: #000099; font-weight: bold;">\\</span>myapp_folder'</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            DATA_PATH = <span style="color: #483d8b;">'c:<span style="color: #000099; font-weight: bold;">\\</span>data<span style="color: #000099; font-weight: bold;">\\</span>python<span style="color: #000099; font-weight: bold;">\\</span>myapp_folder'</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        DATA_PATH = <span style="color: #483d8b;">'e:<span style="color: #000099; font-weight: bold;">\\</span>data<span style="color: #000099; font-weight: bold;">\\</span>myapp_folder'</span>
    <span style="color: #dc143c;">sys</span>.<span style="color: black;">path</span> = <span style="color: #dc143c;">sys</span>.<span style="color: black;">path</span> + <span style="color: black;">&#91;</span>DATA_PATH<span style="color: black;">&#93;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">from</span> logger <span style="color: #ff7700;font-weight:bold;">import</span> Logger
&nbsp;
    errlog  = Logger<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;%s<span style="color: #000099; font-weight: bold;">\\</span>myapp_error_log.txt&quot;</span> <span style="color: #66cc66;">%</span> DATA_PATH<span style="color: black;">&#41;</span>
    errlog.<span style="color: black;">start_trace</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    appuifw.<span style="color: black;">app</span>.<span style="color: black;">screen</span> = <span style="color: #483d8b;">&quot;normal&quot;</span>               <span style="color: #808080; font-style: italic;"># Restore screen to normal size.</span>
    appuifw.<span style="color: black;">app</span>.<span style="color: black;">focus</span> = <span style="color: #008000;">None</span>                    <span style="color: #808080; font-style: italic;"># Disable focus callback.</span>
    body = appuifw.<span style="color: black;">Text</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    appuifw.<span style="color: black;">app</span>.<span style="color: black;">body</span> = body                     <span style="color: #808080; font-style: italic;"># Create and use a text control.</span>
    exitlock = e32.<span style="color: black;">Ao_lock</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> exithandler<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>: exitlock.<span style="color: #dc143c;">signal</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    appuifw.<span style="color: black;">app</span>.<span style="color: black;">exit_key_handler</span> = exithandler  <span style="color: #808080; font-style: italic;"># Override softkey handler.</span>
    appuifw.<span style="color: black;">app</span>.<span style="color: black;">menu</span> = <span style="color: black;">&#91;</span><span style="color: black;">&#40;</span>u<span style="color: #483d8b;">&quot;Exit&quot;</span>, exithandler<span style="color: black;">&#41;</span><span style="color: black;">&#93;</span> <span style="color: #808080; font-style: italic;"># Override application menu.</span>
    errlog.<span style="color: black;">writeline</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">traceback</span>.<span style="color: black;">format_exception</span><span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">exc_info</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    body.<span style="color: #008000;">set</span><span style="color: black;">&#40;</span><span style="color: #008000;">unicode</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">traceback</span>.<span style="color: black;">format_exception</span><span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span><span style="color: #dc143c;">sys</span>.<span style="color: black;">exc_info</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    exitlock.<span style="color: black;">wait</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>                             <span style="color: #808080; font-style: italic;"># Wait for exit key press.</span>
    appuifw.<span style="color: black;">app</span>.<span style="color: black;">set_exit</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></td></tr></table></div>

<p>The launcher will create a &#8216;myapp&#8217; application object and call the run method. From then on, the run method is responsible for creating the first view and for creating a signal lock until the view is closed or an app exit is requested by the user.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdcsoftware.com/pys60-app-skeleton/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Voice for S60</title>
		<link>http://www.bdcsoftware.com/googlevoice-for-s60/</link>
		<comments>http://www.bdcsoftware.com/googlevoice-for-s60/#comments</comments>
		<pubDate>Sat, 26 Sep 2009 22:39:45 +0000</pubDate>
		<dc:creator>raf</dc:creator>
				<category><![CDATA[Symbian]]></category>

		<guid isPermaLink="false">http://www.bdcsoftware.com/?p=405</guid>
		<description><![CDATA[Necessity is the mother of all invention. Google Voice is great service but without a native app for Nokia phones placing a call through the Google Voice number was a major hassle. In addition, I needed a proof of concept app for developing and deploying an app with the 1.9.x PyS60 runtime. The end result [...]]]></description>
			<content:encoded><![CDATA[<p>Necessity is the mother of all invention. Google Voice is great service but without a native app for Nokia phones placing a call through the Google Voice number was a major hassle. In addition, I needed a proof of concept app for developing and deploying an app with the 1.9.x PyS60 runtime. The end result is GoogleVoiceForS60.</p>
<p>In a nutshell, GoogleVoiceForS60 pulls a list of all your contacts, dialed, received and missed calls from the phone and allows you to initiate a phone call or send a SMS message to one of these numbers by using the Google Voice API.&nbsp;</p>
<p>This application is a work in progress and as such it is in a continuing beta stage. It has been tested and is used in every day on the following phones: N97 NAM, N95-5 8GB and N95-3. In addition many users reported it works fine on E75, 5800XM, E71 and E71x phones. In theory it should work on all phones that support the pys60 1.9.7 runtime.</p>
<h2>Screenshots</h2>
<p>For privacy reasons the screenshots were done by running the emulator version. There might be slight differences in look and fee in the real application.</p>
<p><div id="attachment_423" class="wp-caption alignleft" style="width: 234px"><a href="http://www.bdcsoftware.com/wp-content/uploads/2009/09/GoogleVoiceForS60_main.png" rel="lightbox[405]"><img src="http://www.bdcsoftware.com/wp-content/uploads/2009/09/GoogleVoiceForS60_main-253x450.png" alt="List of phone contacts"  width="224" height="400" class="size-medium wp-image-423" /></a><p class="wp-caption-text">List of phone contacts</p></div> <div id="attachment_425" class="wp-caption alignleft" style="width: 234px"><a href="http://www.bdcsoftware.com/wp-content/uploads/2009/09/GoogleVoiceForS60_SMS.png" rel="lightbox[405]"><img src="http://www.bdcsoftware.com/wp-content/uploads/2009/09/GoogleVoiceForS60_SMS-253x450.png" alt="Sending SMS through Google Voice"  width="224" height="400" class="size-medium wp-image-425" /></a><p class="wp-caption-text">Sending SMS through Google Voice</p></div></p>
<div style="clear:both;"></div>
<p>The video below demonstrates the application running on N95-4: </p>
<p><object width="445" height="364"><param name="movie" value="http://www.youtube.com/v/7uDG9nPncPg&#038;hl=en&#038;fs=1&#038;rel=0&#038;border=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/7uDG9nPncPg&#038;hl=en&#038;fs=1&#038;rel=0&#038;border=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="445" height="364"></embed></object></p>
<div style="clear:both;"></div>
<h2>Installation</h2>
<ol>
<li>Download and install the <a href="http://www.bdcsoftware.com/downloads/Python_2.0.0.sis">PyS60 2.0.0 runtime</a></li>
<li>
For 3rd Edition phones (N95, E71, E75 etc.) download and install:<br />
<a href="http://www.bdcsoftware.com/downloads/ssl.sis">ssl.sis</a><br />
<a href="http://www.bdcsoftware.com/downloads/stdioserver.sis">stdioserver.sis</a><br />
<a href="http://www.bdcsoftware.com/downloads/pips.sis">pips.sis</a></p>
</li>
<li>Download and install <a href="http://www.bdcsoftware.com/downloads/GoogleVoiceForS60_0.7.27_merged.sis">GoogleVoiceForS60_0.7.27_merged.sis</a></li>
<li>Reboot the phone.</li>
</ol>
<p>Please make sure to install all the packages to the same drive (it does not matter if it&#8217;s the c: or e: drive). </p>
<h2>Feedback</h2>
<p>Please post all bugs and feature requests in our new support <a href="http://www.bdcsoftware.com/forum" >forum</a></p>
<h2>Change Log</h2>
<p>
<a href="http://www.bdcsoftware.com/downloads/GoogleVoiceForS60_0.7.27_merged.sis">Version 0.7.27</a></p>
<ul>
<li><strong>You have to install Python 2.0.0 or better runtime for this version to work!</strong></li>
<li>Migrated application to Python 2.0.0</li>
<li>Fixed authentication issues after recent Google Voice changes.</li>
<li>Fixed app crashes after unsuccessful call attempts.</li>
</ul>
</p</p>
<p>
<a href="http://www.bdcsoftware.com/downloads/GoogleVoiceForS60_0.7.24_merged.sis">Version 0.7.24</a></p>
<ul>
<li>Bug fixes to new GoogleVoice API code base.</li>
<li>Removed on startup auto-login feature.</li>
</ul>
</p</p>
<p>
<a href="http://www.bdcsoftware.com/downloads/GoogleVoiceForS60_0.7.21_merged.sis">Version 0.7.21</a></p>
<ul>
<li>Rewritten Google Voice API Interop to accommodate recent changes in the API.</li>
<li>Added credential caching to optimize speed. In theory placing call should be much faster now.</li>
<li>Added user feedback when certain error condition occur (Google refusing to place a call etc.)</li>
</ul>
<p>
<a href="http://www.bdcsoftware.com/downloads/GoogleVoiceForS60_0.7.20_merged.sis">Version 0.7.20</a></p>
<ul>
<li>Fixed issues related to latest Google Voice API changes</li>
<li>Added ability to view numbers for selected contact</li>
</ul>
<p>
<a href="http://www.bdcsoftware.com/downloads/GoogleVoiceForS60_0.7.17_merged.sis">Version 0.7.17</a></p>
<ul>
<li>Added default Access Point setting. Once set the application will automatically use that AP for future communications.</li>
<li>Added contact  search functionality.</li>
<li>Added workaround for crashes on phones with 1000+ contacts. On startup the app will detect if there are more than 500 contacts and will force the user to specify search parameter to limit the list of contacts it displays. This workaround will be in places until the bug is fixed in the python runtime.</li>
<li>Fixed issue, where a popup dialog would ask user to select a phone number on a contact even if the contact had only 1 number defined.</li>
</ul>
<p>
<a href="http://www.bdcsoftware.com/downloads/GoogleVoiceForS60_0.7.14_merged.sis">Version 0.7.14</a></p>
<ul>
<li>Fixed &#8220;Unable to set data directory&#8221; issue</li>
<li>Added debug tracing. Just create a file called &#8216;debugversion.txt&#8217; in the GoogleVoiceForS60 directory and the application will log debug statements to debug.log</li>
</ul>
<p>
<a href="http://www.bdcsoftware.com/downloads/GoogleVoiceForS60_0.7.12_merged.sis">Version 0.7.12</a></p>
<ul>
<li>Added wait dialogs and user feedback for call and sms functions.</li>
<li>Added password encryption</li>
<li>Added support for C: drive location. Default is E: but if not available app will fall back to C:</li>
<li>Added password masking</li>
<li>Fixed phantom contacts crashes</li>
<li>This version will DELETE your existing settings database and you will be forced to re-enter your Google Voice credentials and phone number. Sorry.</li>
<li>Received and Missed calls tabs. It&#8217;s not intuitive but there are Missed and Received calls tabs in addition to the Dialed tab. You can use the directional pad to scroll right in the tabs or on 5th edition phones slide/drag the Dialed tab to the left.</li>
</ul>
<p>
<a href="http://www.bdcsoftware.com/downloads/GoogleVoiceForS60_v0_7_9.sis">Version 0.7.9</a></p>
<ul>
<li>Added password masking in options dialog</li>
<li>Fixed login url encoding issues</li>
<li>Added code to gracefully handle contact database issues</li>
</ul>
<p>
Version 0.7.3</p>
<ul>
<li>Improved exception handling</li>
<li>Added settings validation</li>
<li>Added invalid login detection</li>
<li>Added logic to send long SMS text as multiple SMS messages (although the input is limited to 80 chars at the moment due to the UI component limits)</li>
</ul>
<p>
Version 0.7.2</p>
<ul>
<li>Added Received, Dialed and Missed call logs to the selection</li>
<li>Added SMS sending (free SMS through google voice)</li>
</ul>
<p>
Version 0.6.2<br />
Initial alpha release</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdcsoftware.com/googlevoice-for-s60/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Business Development Center 2.5</title>
		<link>http://www.bdcsoftware.com/business-development-center-2-5/</link>
		<comments>http://www.bdcsoftware.com/business-development-center-2-5/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 03:42:56 +0000</pubDate>
		<dc:creator>raf</dc:creator>
				<category><![CDATA[Featured Articles]]></category>

		<guid isPermaLink="false">http://www.bdcsoftware.com/?p=243</guid>
		<description><![CDATA[<p>Business Development Center 2.5 is an easy to use CRM software package automotive dealerships.  Based on proven processes for sales and service, it provides all the necessary tools needed to effectively run a CRM/BDC department at your dealership.</p>]]></description>
			<content:encoded><![CDATA[<p>Business Development Center 2.5 is an easy to use CRM software package automotive dealerships.  Based on proven processes for sales and service, it provides all the necessary tools needed to effectively run a CRM/BDC department at your dealership.</p>
<p>The software was designed with one goal in mind: make it easy to use, so that anybody with basic Microsoft Office experience will find themselves right at home. But, we have also made it powerful and scalable so it can grow with your business. In-fact it, it is scalable enough to run day to day CRM operations for multi-rooftop dealer groups.</p>
<p>The benefits include:</p>
<h2>In-house Solution</h2>
<p>All your data stays in-house and is always accessible. No need to depend on internet connection or storing your data on some questionable servers located who knows where.</p>
<h2>All the Tools for BDC Managers</h2>
<p>Everything is there! From customer and employee management to marketing and reporting</p>
<h2>Secure</h2>
<p>You can control which employees see what and what they can do with the data.</p>
<h2>Sales Agents Tools</h2>
<p>Tools specifically designed for sales agents or BDC reps. Simplified and secure.</p>
<h2>Call Center and Multi-Rooftop Support</p>
<p>You can setup one BDC department that will provide services for all the dealerships in your group.</p>
<h2>Service Module</h2>
<p>Balancing and CRM tie in will allow you to effective integration of service customers into the sales process.</p>
<h2>Internet Lead and Inventory Management</h2>
]]></content:encoded>
			<wfw:commentRss>http://www.bdcsoftware.com/business-development-center-2-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>N97 Music Library</title>
		<link>http://www.bdcsoftware.com/n97-music-library/</link>
		<comments>http://www.bdcsoftware.com/n97-music-library/#comments</comments>
		<pubDate>Sun, 09 Aug 2009 00:14:49 +0000</pubDate>
		<dc:creator>raf</dc:creator>
				<category><![CDATA[Symbian]]></category>

		<guid isPermaLink="false">http://www.bdcsoftware.com/?p=188</guid>
		<description><![CDATA[
As I said in the previous part, the N97 sound playback is very good. There is no distortion, no hissing or cracking during playback. Even when you use the equalizer there is no audible distortion as long as you stay within sane limits.


Most of the time I transfer songs to the device in mass-storage  [...]]]></description>
			<content:encoded><![CDATA[<p>
As I said in the previous part, the N97 sound playback is very good. There is no distortion, no hissing or cracking during playback. Even when you use the equalizer there is no audible distortion as long as you stay within sane limits.
</p>
<p>
Most of the time I transfer songs to the device in mass-storage  mode and have not experienced any slowdowns or transfer issues (as experienced  by <a href="http://www.symbian-guru.com/welcome/2009/07/nokias-music-experience-is-a-joke.html" target="_blank">symbian-guru.com</a>). The reason I transfer in mass-storage mode is twofold:
</p>
<ol>
<li>All my music is stored on a file server, neatly  organized in folders</li>
<li>I have many computers and not one is designated  as a &ldquo;primary&rdquo; computer and hence I don&rsquo;t use anything like a multimedia  library</li>
</ol>
<p><div id="attachment_174" class="wp-caption alignright" style="width: 210px"><a href="http://www.bdcsoftware.com/wp-content/uploads/2009/08/music_player_last_played.jpg" rel="lightbox[188]"><img src="http://www.bdcsoftware.com/wp-content/uploads/2009/08/music_player_last_played.jpg" alt="&quot;Last played&quot; is gone..."  width="200" height="356" class="size-full wp-image-174" /></a><p class="wp-caption-text">Last Played entry is gone...</p></div></p>
<p>
The multimedia player is organized as pretty much any other  player out there: It scans the mp3 files and organizes them by the usual tags.  In addition you also have the ability to play songs based on playlists. The  drawback is that like any other player (except for rockbox) it does not allow  you to play songs based on folder structure (which is my setup).
</p>
<p>
Unfortunately not all my music folders have playlist files  and the multimedia service on the phone will not create automatic playlists  based on folder structure. One workaround that I created and use is a small  python script that will scan the library and automatically add .m3u files to folders  containing mp3 files. &nbsp;Right now the  script has to be run manually but I am in the process of converting it to a  background service.
</p>
<p>
Even though the sound quality is phenomenal, there are some  usability issues with the player that should be addressed by the dev team. The  first annoyance is that the player forgets the &ldquo;Last Played&rdquo; item. This does  not sound as a big deal, but is quite important if you have a large library.
</p>
<p>
Another issue has to do with button placement and general  usability. See, most of the time I use the player in my car. It is hooked up to  the stereo through the headphone jack and usually sits on the passenger seat. I  am used to operating the mp3 player with my right hand without even looking at  it but that is not possible on the N97:
</p>
<h3>Auto-rotate Feature</h3>
<p>
The auto-rotate feature switches between landscape and portrait mode frequently and you don&rsquo;t know which mode it&rsquo;s in  when you pick-up the phone. The button placement in both modes is different and  so you have to look at the phone to see what&rsquo;s going on.
</p>
<h3>Button Location</h3>
<p>
What makes it worse is that the &ldquo;Next Song&rdquo;  button is located close to the &ldquo;Back&rdquo; button in portrait mode but in landscape  it&rsquo;s next to the &ldquo;Options&rdquo; button (See below)
</p>
<p><div id="attachment_178" class="wp-caption alignleft" style="width: 366px"><a href="http://www.bdcsoftware.com/wp-content/uploads/2009/08/music_player_landscape.jpg" rel="lightbox[188]"><img src="http://www.bdcsoftware.com/wp-content/uploads/2009/08/music_player_landscape.jpg" alt="Landscape mode"  width="356" height="200" class="size-full wp-image-178" /></a><p class="wp-caption-text">Landscape mode</p></div><br />
<div id="attachment_177" class="wp-caption alignleft" style="width: 210px"><a href="http://www.bdcsoftware.com/wp-content/uploads/2009/08/music_player_portrait.jpg" rel="lightbox[188]"><img src="http://www.bdcsoftware.com/wp-content/uploads/2009/08/music_player_portrait.jpg" alt="Portrait mode"  width="200" height="356" class="size-full wp-image-177" /></a><p class="wp-caption-text">Portrait mode</p></div></p>
<p style="clear: both">
This causes two issues: if you are not precise you will hit the back button  (very annoying) and of course depending on the portrait/landscape mode you don&rsquo;t  know if you are navigating forward or backward.
</p>
<p>
Also the buttons are too small and are too close the  bottom edge of the phone. I know it was convenient to reuse the button API but  the usability suffers big time here.
</p>
<h3>Gesture Support</h3>
<p>
What would mitigate the issue is gesture  support for skipping songs like this:<br />
<div id="attachment_171" class="wp-caption alignleft" style="width: 210px"><a href="http://www.bdcsoftware.com/wp-content/uploads/2009/08/music_player_gesture_support.jpg" rel="lightbox[188]"><img src="http://www.bdcsoftware.com/wp-content/uploads/2009/08/music_player_gesture_support.jpg" alt="Gesture support would be nice to have..."  width="200" height="356" class="size-full wp-image-171" /></a><p class="wp-caption-text">Gesture support would be nice to have...</p></div></p>
<p>When I pick-up the phone this is where my thumb is resting and a swipe left or  right would be natural for song navigation. If you want to be adventurous, an  up/down swipe could navigate between playlists
</p>
<h3>Other Items</h3>
<p>
There are some additional &ldquo;nice to have&rdquo; items like: song rating, history of songs played including most played list that are missing from the player . In addition it would be nice if the main screen widget could span two slots so that it&rsquo;s easier to navigate the songs without looking at the phone (again that usability thing).
</p>
<h3>Good MP3 Player</h3>
<p>
Even though the software player has some usability issue I still use it as my primary mp3 player. The convenience of having to carry only one device outweighs the issues and with small modifications this could become a great player.
</p>
<p style="clear: both">
&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdcsoftware.com/n97-music-library/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nokia N97  From Developers Perspective</title>
		<link>http://www.bdcsoftware.com/nokia-n97-from-developers-perspective/</link>
		<comments>http://www.bdcsoftware.com/nokia-n97-from-developers-perspective/#comments</comments>
		<pubDate>Sun, 09 Aug 2009 00:07:25 +0000</pubDate>
		<dc:creator>raf</dc:creator>
				<category><![CDATA[Symbian]]></category>

		<guid isPermaLink="false">http://www.bdcsoftware.com/?p=183</guid>
		<description><![CDATA[
Let me state upfront that this is not a typical phone review. Rather it’s the first part of series of articles written from a developers “point of view”. I will try to go over how it is to develop on this phone, the experiences while using it and of course the issues I encounter.


I am [...]]]></description>
			<content:encoded><![CDATA[<p>
Let me state upfront that this is not a typical phone review. Rather it’s the first part of series of articles written from a developers “point of view”. I will try to go over how it is to develop on this phone, the experiences while using it and of course the issues I encounter.
</p>
<p>
I am a developer and I do develop software for Nokia phones. As any <span style="text-decoration: line-through">developer</span> user will know, no tool and no software application or platform is ever perfect. There are always issues. It&rsquo;s just a question if the benefits outweigh the downsides. That&rsquo;s all.
</p>
<p>
I like this phone. Did I have doubts and questions before I bought it? A big YES. This was mostly caused by other people&rsquo;s reviews and ultimately a good thing because it lowered my expectations ;-) For instance: I wasn&rsquo;t expecting much from the keyboard but I really like it. It&rsquo;s perfect for me and I much rather use it than the keyboard on an E71. Another issue was the free memory on the phone. After I stopped some useless apps from running at boot-up, I ended up with 50mb free for the apps and tools I need.
</p>
<p>
Overall this phone is already the best phone I have ever used. It&rsquo;s fast and easy to use. The new theme looks very polished. Keyboard is excellent. And of course the phone has so many features that I&rsquo;m still surprised every day by something new I uncover. I am also amazed how good the phone sounds as an mp3 player. It beats my ipod, sansa and every other mp3 playing gadget I own.
</p>
<p>
However, like I said in the first paragraph, nothing is perfect and there are some issues with this product I would like to see addressed in future revision. There are some embarrassing mistakes and annoyances and there are some serious issues. I will start with the easy and embarrassing ones:
</p>
<h3>Why does the NAM edition ship with a manual that states on the first page; &ldquo;DRAFT DO NOT USE&rdquo; and why are there localization translation errors in the manual?</h3>
<p>
There is not much to add on this topic ;-)
</p>
<p><div id="attachment_176" class="wp-caption alignleft" style="width: 310px"><a href="http://www.bdcsoftware.com/wp-content/uploads/2009/08/06232009012.jpg" rel="lightbox[183]"><img src="http://www.bdcsoftware.com/wp-content/uploads/2009/08/06232009012.jpg" alt="I just can&#039;t resist..."  width="300" height="225" class="size-full wp-image-176" /></a><p class="wp-caption-text">I just can't resist...</p></div><br />
<div id="attachment_175" class="wp-caption alignleft" style="width: 310px"><a href="http://www.bdcsoftware.com/wp-content/uploads/2009/08/06232009013.jpg" rel="lightbox[183]"><img src="http://www.bdcsoftware.com/wp-content/uploads/2009/08/06232009013.jpg" alt="Localization issue"  width="300" height="157" class="size-full wp-image-175" /></a><p class="wp-caption-text">Localization issue</p></div></p>
<div style="clear: both">
&nbsp;
</div>
<h3>Menu</h3>
<p>
I really like the new menu organization feature. Nokia finally found a way to intuitively move the shortcuts around. Excellent. Well, apparently some shortcuts don&rsquo;t like to be moved and &ldquo;move back&rdquo; automatically a short time after they have been moved. I swear I moved all the game shortcuts to the games folder at least four times and every time after a few hours they get moved back to the app menu by some system process.
</p>
<p>
There is also an empty &ldquo;MfE&rdquo; folder in Applications that should not be there. Either ship MfE or get rid of the folder.
</p>
<p>
Another annoyance that&rsquo;s bugging me quite a lot is the inability to uninstall crap like Boingo and JoikuSpot. I will never use these apps. Give me a way to uninstall these and reclaim the space on the phone. Boingo is especially evil because it comes with a protected access point that you can&rsquo;t delete!
</p>
<h3>Web Browser Crashes</h3>
<p>
One of the more serious issues is the 11 browser crashes I experienced in the first week. Two of them happened on flash laden sites, but the rest happened on simple google search pages. This is a bit concerning considering how much functionality of this phone is based on the browser engine but the good news this only happened while browsing websites and not while using any widgets or apps.
</p>
<p>
One feature I would add is a crash recovery. Just give the user an option to continue from where the crash occurs on next browser launch (ala Opera or Firefox)
</p>
<h3>Phone Unlock</h3>
<p>
This has occurred multiple times but I was unable to figure out the steps to reproduce this. Essentially what&rsquo;s happening is I lock the phone, put it in a pouch and next time I take it out either the phone is unlocked or the phone is locked but the front facing camera and app are active in the background. This has happened multiple times but it&rsquo;s not easy to reproduce.
</p>
<p>
There are other issues that I have encountered but will go into the details in future articles. For now that&rsquo;s it and stay tuned for the next part in the series: <a href="http://www.bdcsoftware.com/n97-music-library">The N97 Music Library</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdcsoftware.com/nokia-n97-from-developers-perspective/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>N97 Small Emulator Skin</title>
		<link>http://www.bdcsoftware.com/n97-small-emulator-skin/</link>
		<comments>http://www.bdcsoftware.com/n97-small-emulator-skin/#comments</comments>
		<pubDate>Sat, 08 Aug 2009 23:42:27 +0000</pubDate>
		<dc:creator>raf</dc:creator>
				<category><![CDATA[Symbian]]></category>

		<guid isPermaLink="false">http://www.bdcsoftware.com/?p=162</guid>
		<description><![CDATA[
Recently I have installed and started experimenting with N97SDK 0.5. One of the first things I noticed that the emulator window is huge(due to the 360 x 640 phone resolution) and will be partially off-screen on mylaptop with its low resolution of 1280&#215;800.


Creating the actual skin configuration file and the bitmap for the N97 is [...]]]></description>
			<content:encoded><![CDATA[<p>
Recently I have installed and started experimenting with N97SDK 0.5. One of the first things I noticed that the emulator window is huge(due to the 360 x 640 phone resolution) and will be partially off-screen on mylaptop with its low resolution of 1280&#215;800.
</p>
<p>
Creating the actual skin configuration file and the bitmap for the N97 is fairly simple because in portrait mode the phone has only four buttons visible that have to be mapped. Making the new skin file part of the emulator configuration was a bigger challenge and the only way I got it to work is by overriding the original portrait mode configuration file.
</p>
<p>
Once installed, the emulator will look as follows:
</p>
<p><div id="attachment_165" class="wp-caption aligncenter" style="width: 166px"><img src="http://www.bdcsoftware.com/wp-content/uploads/2009/08/n97_emu_small_skin1-156x300.jpg" alt="Emulator with simple small skin sized for 1280x800 resolutions" title="N97 Small Skin Emulator" width="156" height="300" class="size-medium wp-image-165" /><p class="wp-caption-text">Emulator with simple small skin sized for 1280x800 resolutions</p></div></p>
<h3>Issues</h3>
<p>
The only issue I have encountered so far is the partial redraw issue on the right border of the screen. This is a cosmetic issue only and it will not affect the operation of the emulator. For some reason when the emulator powers on it draws the phone screen at incorrect coordinates and later on restores the location to the correct offset coordinates. Weird.
</p>
<h3>Installation</h3>
<p>
Installation is fairly simple:
</p>
<ol>
<li>Backup the following file: epocdata epoc_360&#215;640_touch_keypadoff.ini </li>
<li>Download the <a href='http://www.bdcsoftware.com/wp-content/uploads/2009/08/n97_small_emu_skin.zip'>n97_small_emu_skin</a> file and unzip it into the epocdata directory in your SDK location. Make sure you overwrite existing files.</li>
</ol>
<h3>Customization</h3>
<p>
I have also uploaded the <a href='http://www.bdcsoftware.com/wp-content/uploads/2009/08/N97_Small_Emu_Image.psd'>N97_Small_Emu_Image</a> that can be used to easily customize the look and feel. Again, this skin is fairly simple to customize because you only have to define four button positions. Once you open the ini file it should b self explanatory on what to do.
</p>
<p>
Hope somebody will get some use out of this.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdcsoftware.com/n97-small-emulator-skin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>XML/SWF Charts in Ruby on Rails</title>
		<link>http://www.bdcsoftware.com/xmlswf-charts-in-ruby-on-rails/</link>
		<comments>http://www.bdcsoftware.com/xmlswf-charts-in-ruby-on-rails/#comments</comments>
		<pubDate>Sat, 08 Aug 2009 23:40:10 +0000</pubDate>
		<dc:creator>raf</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.bdcsoftware.com/?p=160</guid>
		<description><![CDATA[
Since RMagick seems to be broken on Win32 when using with Ruby 1.8.4 and Gruff is using RMagick to draw its pretty graphs, I had to go out and find an alternative chart library for use with Rails.


XML/SWF Charts
Fortunately I have run into this chart library a while back when doing php evelopment. It&#8217;s not [...]]]></description>
			<content:encoded><![CDATA[<p>
Since RMagick seems to be broken on Win32 when using with Ruby 1.8.4 and Gruff is using RMagick to draw its pretty graphs, I had to go out and find an alternative chart library for use with Rails.</p>
<p>
<br />
<strong>XML/SWF Charts</strong><br />
Fortunately I have run into this chart library a while back when doing php evelopment. It&#8217;s not really a php driven because the data input andconfiguration is in form of a XML file. To make it work with rails, all Ihad to do is translate the php function that generates the XML file to Ruby.</p>
<p>Well, after a few hours of playing around and experimenting with differentapproaches to the issue I think I have come up with a fairly easy way to get he charts working with rails.</p>
<p><div id="attachment_202" class="wp-caption aligncenter" style="width: 387px"><a href="http://www.bdcsoftware.com/wp-content/uploads/2009/08/chart_sample.gif" rel="lightbox[160]"><img src="http://www.bdcsoftware.com/wp-content/uploads/2009/08/chart_sample.gif" alt="Chart Sample"  width="377" height="253" class="size-full wp-image-202" /></a><p class="wp-caption-text">Chart Sample</p></div>
</p>
<p>
The above sample displays a sample of a working graph. After a few failed / ugly attempts, I settled for a class/controller hybrid that hopefully is easy to use. So with out further rambling, here is a step by step guide to get it to work:</p>
<p>1.Download the <a href="http://www.maani.us/xml_charts/" title="SWF Chart library">SWF Chart library</a> and place it in the /public directory
</p>
<p>
2.Download the <a href='http://www.bdcsoftware.com/wp-content/uploads/2009/08/swfchart.rb'>swfchart.rb</a> class and place in the /lib directory
</p>
<p>
3.Download <a href='http://www.bdcsoftware.com/wp-content/uploads/2009/08/chart_controller.rb'>chart_controller</a> and place it in the /controllers directory
</p>
<p>
With all the pieces in place, the last two components will be tied to your application directly. The data and options for the chart have to be set in a controller. For instance something like this should work:
</p>
<p>
<span style="background-color: #99ccff">@swf = SWFChart.new</span>
</p>
<p>
<span style="background-color: #99ccff">session[:swfchart] = @swf</span><br />
<span style="background-color: #99ccff">#set data headings</span><br />
<span style="background-color: #99ccff">@swf.data_array = Array.new</span><br />
<span style="background-color: #99ccff">@swf.data_array[0] = [nil]</span><br />
<span style="background-color: #99ccff">@swf.data_array[1] = ['']</span></p>
<p><span style="background-color: #99ccff">#get space count per category</span><br />
<span style="background-color: #99ccff">for c in @current_show.ShowCategories</span><br />
<span style="background-color: #99ccff">    @swf.data_array[0] &lt;&lt; c.name</span><br />
<span style="background-color: #99ccff">    @swf.data_array[1] &lt;&lt; c.BaseSpaces.count</span><br />
<span style="background-color: #99ccff">end</span><br />
<span style="background-color: #99ccff">@swf.chart_type = &quot;3d pie&quot;</span><br />
<span style="background-color: #99ccff">@swf.chart_rect = {:x =&gt; &#8216;150&#8242;,:width =&gt; &#8216;200&#8242;,:height =&gt; &#8216;125&#8242;}</span><br />
<span style="background-color: #99ccff">@swf.legend_rect = {:x =&gt; 10, :y =&gt; 10, :width =&gt; 50, :height =&gt; 200}</span></p>
<p>And finally, the chart will be displayed from the view with code like this:
</p>
<p style="background-color: #99ccff">
&lt;%= @swf.insert_chart(:data_source =&gt; url_for(:controller =&gt; &quot;/chart&quot;), :width =&gt; &quot;400&quot;, :height =&gt; &quot;300&quot;) %&gt;
</p>
<p>
Observant readers will have noticed that the whole chart data-setting and generation is encapsulated in the swfchart.rb class from the /lib directory. Unfortunately I don&rsquo;t have much time to encapsulate this as a plugin, but perhaps somebody could take what I have and run with it&hellip;
</p>
<p>
06.12.06 &#8211; Edit<br />
There have been a few issues reported by a few users while trying to get this up and running. In order to solve some of the more common mistakes, I have decided to create a sample project. Just download <a href='http://www.bdcsoftware.com/wp-content/uploads/2009/08/testapp.zip'>testapp.zip</a>, unzip, run webrick and browse to <a href="http://localhost:3000/sample" title="http://localhost:3000/sample">http://localhost:3000/sample</a>
</p>
<p>
08.02.06 &#8211; Edit<br />
Version 0.1.14 of the SWFChart wrapper is done. Changes include a &quot;plugin&quot; like structure (still have to solve copying of the charts to the public directory before it becomes a true plugin) and minor bugfixes to xml generator method.
</p>
<p>
Installation:<br />
Just download the <a href='http://www.bdcsoftware.com/wp-content/uploads/2009/08/swfchart.0.1.14.zip'>swfchart.0.1.14.zip</a> and unzip it to the root of your rails application. If you have a previous version installed, remove swfchart.rb from the lib directory and any require statements from your controllers.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdcsoftware.com/xmlswf-charts-in-ruby-on-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dreamweaver 8 and Ruby on Rails CodeHints</title>
		<link>http://www.bdcsoftware.com/dreamweaver-8-and-ruby-on-rails-codehints/</link>
		<comments>http://www.bdcsoftware.com/dreamweaver-8-and-ruby-on-rails-codehints/#comments</comments>
		<pubDate>Sat, 08 Aug 2009 23:39:00 +0000</pubDate>
		<dc:creator>raf</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.bdcsoftware.com/?p=158</guid>
		<description><![CDATA[
I am so used to coding help (intellisense) from Visual Studio, that not having an IDE with this type of functionality is a major inconvenience when working with the Ruby on Rails framework. There are editors that offer syntax highlighting and project management options, but all of them lack the intellisense (aka. code completion or [...]]]></description>
			<content:encoded><![CDATA[<p>
I am so used to coding help (intellisense) from Visual Studio, that not having an IDE with this type of functionality is a major inconvenience when working with the Ruby on Rails framework. There are editors that offer syntax highlighting and project management options, but all of them lack the intellisense (aka. code completion or coding hints) functionality.
</p>
<p>
The closest editor is jEdit. It offers code hints for the current class and has ruby RDOC add-in. However, I have not found a way to add the ROR API to it. So it&rsquo;s a shame&hellip;
</p>
<p>
<a href="http://www.bdcsoftware.com/development/rubyonrails/jedit.gif" rel="lightbox[158]"><img src="http://www.bdcsoftware.com/development/rubyonrails/jedit_tn.gif" border="0" alt="Jedit and ROR" width="450" height="310" /></a><br />
 	jEdit and Ruby on Rails
</p>
<h3>Welcome Dreamweaver 8</h3>
<p>
 If you have worked with DW before, you will know that it offers syntax highlighting for many languages. It also has something similar to intellisense built-in for PHP and ASP. It will not complete your custom attributes or methods, but it can list the most used API calls (for instance Session&hellip; or Request&hellip; in ASP). Too bad they don&rsquo;t offer Ruby or ROR codehints&hellip;
</p>
<p>
Well, with a little bit of hacking, you can actually get  syntax highlighting and codhints working in DW 8.
</p>
<p>
First, follow <a href="http://rubygarden.org/ruby/ruby?action=browse&amp;diff=1&amp;id=DreamweaverMX">these instructions</a> to get syntax highlighting. For DW 8, I had to add the rules to the file in my profile directory and not in the global file in Program Files dir.
</p>
<h3>CodeHints</h3>
<p>
The toughest part of getting Ruby on Rails codehints into DW 8 was actually to get them out of the RDOC Html format. Last thing I wanted to manually copy and paste hundreds of lines J. Unfortunately, either I don&rsquo;t understand how to use RDOC correctly or this thing is completely broken. RDOC output to HTML work fine, but the output can&rsquo;t be easily used to get a list of all the APIs. The XML output could be used, but&hellip;it will NOT list the actual methods and parameters. Anyhow here is, after a few hours of trying to get the HTML template to behave the way I want it to, <a href="http://www.bdcsoftware.com/development/rubyonrails/rubyonrails_api_for_dreamweaver.txt">a file with some of  the most used APIs</a> in DW format ready to be added to &ldquo;C:\Program  Files\Macromedia\Dreamweaver 8\Configuration\CodeHints\CodeHints.xml&rdquo;
</p>
<h3>End Result </h3>
<p>
<img src="http://www.bdcsoftware.com/development/rubyonrails/dw_codehint1.gif" border="0" alt="Ruby on Rails in DreamWeaver" width="494" height="306" /><br />
   Dreamweaver CodeHints
</p>
<p>
<img src="http://www.bdcsoftware.com/development/rubyonrails/dw_codehint2.gif" border="0" alt="Alternative Code completion" width="412" height="82" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdcsoftware.com/dreamweaver-8-and-ruby-on-rails-codehints/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Five Years with Firebird</title>
		<link>http://www.bdcsoftware.com/five-years-with-firebird/</link>
		<comments>http://www.bdcsoftware.com/five-years-with-firebird/#comments</comments>
		<pubDate>Sat, 08 Aug 2009 23:35:19 +0000</pubDate>
		<dc:creator>raf</dc:creator>
				<category><![CDATA[Database]]></category>

		<guid isPermaLink="false">http://www.bdcsoftware.com/?p=155</guid>
		<description><![CDATA[
It&#8217;s unbelievable, but the Interbase with VB article has been written over five years ago. Over the years the article has received hundreds of thousands of hits and I hope we have left a mark with the developer community. This little write-up is intended as a follow-up or more like a status update on our [...]]]></description>
			<content:encoded><![CDATA[<p>
It&rsquo;s unbelievable, but the Interbase with VB article has been written over five years ago. Over the years the article has received hundreds of thousands of hits and I hope we have left a mark with the developer community. This little write-up is intended as a follow-up or more like a status update on our experience with Interbase/Firebird.
</p>
<p>
Even though the original article is fairly old by internet/development standards, most of the facts still stand. However, life never stands still, especially not for small agile software companies. By the end of 2001, Borland has seized any future development on the open-sourced version of Interbase. Fortunately a group of amazing developers has picked up the slack and forked the code base and in winter 2002 we have switched to Firebird 1.0 the &ldquo;true&rdquo; open source Interbase and the following year to Firebird 1.5.With close to 1000 deployments on various desktop and server configurations and thousands of gigabytes of data spread across all the databases, I think we can consider ourselves as seasoned Firebird users/developers. </p>
<p>
But, as with any technology, we had our share of challenge and success stories. Following are a few items what to look for and what to look out for. Let&rsquo;s start with the issues as these are most of the time the determining factor when it comes to adoption of new technology:</p>
<h3><span style="font-weight: bold">The Issues</span></h3>
<p>Firebird is not very forgiving when it comes to sloppy SQL syntax. Things that you can get away with in SQL Server, will kill the db performance in Firebird. For instance: </p>
<p><span style="font-style: italic; color: #9999cc">Select * from SomeTable where id in (Select some_id from SomeOtherTable)</span></p>
<p>If  the subselect should return a lot of records, the performance will be abysmal. Fortunately if you think outside of the box, there is always a workaround. In this case we could use a selectable stored proc to do an inner join on like this:</p>
<p><span style="font-style: italic; color: #9999cc">Select * from SomeTable inner join SelectableStoredProcedure(Params) on (someid = stored_proc_param)</span></p>
<p>Another issue that we have run into a few times is the high bandwidth requirement when transferring large blob datasets over the Ethernet. Essentially, when performing a query that returns a lot of data (lets say 100 MB) to the client, Firebird will max out the Ethernet bandwidth on a 100 Mbps switch very quickly without even making the hard drives work. SQL Server performs much better in this instance.</p>
<p>One feature that we sorely miss is the cross database joins that are easily done in SQL server. There are workarounds in Firebird (like defining an external table) but it&rsquo;s not the same. Hopefully, this feature will be added to FB 2.0.</p>
<h3><span style="font-weight: bold">The Awesome</span></h3>
<p>Enough of the issues, lets cover the exciting items, things that have made our lives easy:</p>
<p>The deployment as part of a custom setup is a breeze. With all our deployments  we have had only 3 problem installations. One was caused by a faulty Ethernet card and the other two on Windows ME. I think this metric speaks for itself. In contrast, we are supporting an outside company with MSDE deployments. The failure rate is an astonishing 25% for MSDE deployments in uncontrolled environments. Most of the time these are issues that can be resolved, but the cost of support is very high.</p>
<p>Mentioned before, selectable stored procedures. The power of this feature becomes evident when you can do an inner or outer join between a table and a stored procedure. In addition, stored procedures work &ldquo;internally&rdquo; similar to cursors (there is a loop inside the stored proc) where additional programming logic can be embedded.</p>
<p>Firebird also works well in many environments. Currently we have a .NET project with Firebird deployment on Win2K3, VB6 projects and even Firebird running with Ruby on Rails on a Linux host. </p>
<p>Hopefully this little status update will be useful to somebody. What&rsquo;s important that after five years, we are still sticking with Firebird and there is no change in sight&hellip;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdcsoftware.com/five-years-with-firebird/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Interbase and ADO tutorial</title>
		<link>http://www.bdcsoftware.com/interbase-and-ado-tutorial/</link>
		<comments>http://www.bdcsoftware.com/interbase-and-ado-tutorial/#comments</comments>
		<pubDate>Sat, 08 Aug 2009 23:01:50 +0000</pubDate>
		<dc:creator>raf</dc:creator>
				<category><![CDATA[Database]]></category>

		<guid isPermaLink="false">http://www.bdcsoftware.com/?p=151</guid>
		<description><![CDATA[Has anybody ever wondered if there is an Open Source alternative to SQL Server or Access databases? Well, I have, and I found Interbase. Interbase is a Client/Server database from Borland. It is Open Source. It runs on Windows, Linux and bunch of other *nix platforms. It has a very small memory footprint and it [...]]]></description>
			<content:encoded><![CDATA[<p>Has anybody ever wondered if there is an Open Source alternative to SQL Server or Access databases? Well, I have, and I found Interbase. Interbase is a Client/Server database from Borland. It is Open Source. It runs on Windows, Linux and bunch of other *nix platforms. It has a very small memory footprint and it is relatively fast.</p>
<p>
It will also support large database files (larger then 2 gig. I know a guy that has a 300 Gig database up and running)
</p>
<p>
Anyhow, in this article I will describe the issues and the necessary tools to get you up and running with Interbase.
</p>
<p>
First let me tell you about the benefits of Interbase: </p>
<ol>
<li>Open Source</li>
<li>Fast</li>
<li>Small size</li>
<li>Very easy distribution (scripts for Wise or InstallShield are available)</li>
<li>Works ADO</li>
<li>Works with ODBC</li>
<li>Awesome transaction management (readers never block writers and vice versa)</li>
<li>Multiple platform support (Linux/Unix)</li>
<li>Superb support for BLOB fields (Images and memo fields)</li>
<li>Support for Arrays (you can store Arrays in individual fields)</li>
</ol>
<p>
For starters you need to get the server and client software. You can get the original Open Source version (Source and Binaries) from Borland at:
</p>
<p>
<a href="http://www.borland.com/devsupport/interbase/opensource/">http://www.borland.com/devsupport/interbase/opensource/ <br />
     </a>or get it a modified version (Firebird) from: <br />
     <a href="http://www.ibphoenix.com/ibp_download.html">http://www.ibphoenix.com/ibp_download.html </a>
</p>
<p>
Download and install the server and client binaries. The Interbase server ships with a ODBC driver, but I hate ODBC and use ADO/OleDB on a day to day basis. So I had to find an OleDB driver for Interbase. Luckily there are numerous available. You can find a links to download sites on this site:
</p>
<p>
<a href="http://www.interbase2000.org/tools_conn.htm%20">http://www.interbase2000.org/tools_conn.htm </a>
</p>
<p>
I opted for the IBProvider from <a href="http://www.lcpi.lipetsk.ru/prog/eng/index.html">http://www.lcpi.lipetsk.ru/prog/eng/index.html </a> because they had some VB samples of how to use the provider with ADO. The version that you can download is an Evaluation for 30 days. If you want a completely free OleDB provider then use: <a href="http://www.oledb.net/?Page=FAQ">Http://www.oledb.net/?Page=FAQ </a>. However, all my sample code is tested with IBProvider only.
</p>
<p>
Once you have downloaded and installed all the files, you are ready for development. IB (Interbase) ships with a sample database called employee.gdb. We will use this database as an example. (You can find it in &#8216;C:Program FilesBorlandInterBaseexamplesDatabase&#8217; , provided you installed the server in the default location). Anyhow, lets start with the basics:
</p>
<p>
<strong>Connecting to Interbase </strong><br />
   Lets establish a connection to the database. A sample connection:
</p>
<p>
<em>Dim adoConn As New ADODB.Connection </em>
</p>
<p>
<em> adoConn.ConnectionString = &quot;provider=LCPI.IBProvider;data source=localhost:C:Interbase DBsEmployee.gdb;ctype=win1251;user id=SYSDBA;password=masterkey&quot; </em>
</p>
<p>
<em> adoConn.Open </em>
</p>
<p>
<br />
   Ok, here are a few things to consider: <br />
 Default user name and password (like SA in SQLServer) are SYSDBA and masterkey (case sensitive). The &#8216;data source&#8217; parameter has a following syntax: IP Address:file location on the remote system . If you installed the server on your development machine then use localhost or your IP. If you installed it on a remote machine then use the IP Address of the machine. The file location is a bit weird. It is local to the server and you can&#8217;t use UNC paths.
</p>
<p>
Once the connection is open, we can start working with the database.
</p>
<p>
<strong>Working with an Interbase database </strong><br />
 For the most part, working with Interbase is as easy as working with SQL Server or Access. However there are a few things to consider:
</p>
<p>
For one, Interbase uses dialects, basically it&#8217;s the SQL syntax that you issue your commands to the database. IB 6.0 can use Dialect 1 (legacy) and Dialect 3. The sample databases are in written in Dialect 1. If you decide to use Dialect 3 (as I have), you will notice some weird behavior. If your database has lower case table and field names, you will have to surround them with double quotes. For instance: Select &quot;CompanyName&quot;, &quot;Address&quot; from &quot;tblCustomers&quot;. Needless to say this will create havoc with VB programmers J. One workaround is to use caps for table and field names. (Btw, don&#8217;t ask me why this is the way it is.) For Instance: SELECT COMPAN_YNAME, ADDRESS FROM TBLCUSTOMERS.
</p>
<p>
The other issue that I have found is: you cannot use adCmdStoredProc as your command type. Workaround for this: use adCmdText. But more to this later.
</p>
<p>
Ok, so how would we get some data in and out of our database? Well, you can use your normal recordset object to execute a SQL statement or you can use stored procedures.
</p>
<p>
Here is a sample of a simple select statement:
</p>
<p>
<em>Dim rst As New Recordset </p>
<p>   rst.Source = &quot;SELECT CUSTOMER.CONTACT_FIRST, &quot; &amp; _ <br />
 &quot;CUSTOMER.CONTACT_LAST, CUSTOMER.COUNTRY &quot; &amp; _ <br />
 &quot;FROM CUSTOMER&quot; </p>
<p>   rst.ActiveConnection = adoConn <br />
   adoConn.BeginTrans <br />
   rst.Open <br />
   adoConn.CommitTrans </em>
</p>
<p>
And here is a simple stored procedure execution:
</p>
<p>
<em>Dim rst As New Recordset <br />
   Dim cmd As New ADODB.Command </em>
</p>
<p>
<em> adoConn.Open </p>
<p>   With cmd <br />
   .ActiveConnection = adoConn <br />
   .CommandText = &quot;Select * FROM DEPT_BUDGET (100)&quot; <br />
   End With </em>
</p>
<p>
<em> adoConn.BeginTrans <br />
   Set rst = cmd.Execute <br />
   adoConn.CommitTrans </em>
</p>
<p>
<br />
 Notice that if your stored procedure returns any rows, you have to use the &#8216;SELECT * FROM stored procedure name&#8217; syntax. If your procedure does not return any records, you can use &#8216;EXECUTE stored procedure name&#8217;.
</p>
<p>
Also, the way you pass parameters in and out of the procedure is a bit peculiar. Lets say you have an insert stored procedure that will accept 3 parameters. To pass those parameters you can use inline syntax: For instance, &#8216;execute procedure PROC_INSERT_TBLCUSTOMERS (comma delimited parameter values)&#8217; or you can use this syntax:
</p>
<p>
<em>With cmd <br />
   .ActiveConnection = adoConn <br />
   .CommandText = &quot; execute procedure PROC_INSERT_TBLCUSTOMERS (?,?,?)&quot; <br />
   End With </em>
</p>
<p>
<em>adoConn.BeginTrans <br />
   cmd(0) = parameter value <br />
   cmd(1) = parameter value <br />
   cmd(2) = parameter value <br />
   cmd.Execute <br />
   adoConn.CommitTrans </em>
</p>
<p>
<br />
 Anyhow, these are the basics. If you guys are interested in Interbase, I will write a 2nd part of the tutorial that will cover some advanced features like working with Images, Arrays, UDF functions and tools for Interbase. For now take a look at the sample code for this tutorial, and take a look at the sample databases that are provided by Borland.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bdcsoftware.com/interbase-and-ado-tutorial/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
