<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-14883822</id><updated>2012-01-29T12:25:23.604-06:00</updated><category term='maemo'/><category term='personal'/><category term='spiritual'/><category term='politics'/><category term='programming'/><title type='text'>Ed Page</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>43</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-14883822.post-5230892648499512574</id><published>2011-09-08T20:32:00.002-05:00</published><updated>2011-09-09T08:29:09.333-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>Porting to PySide/QML: Notification Bar</title><content type='html'>I keep hearing about how great QML is to learn so I'm a bit baffled  as to why I am still having such a hard time with getting more than a  toy program written.&amp;nbsp; I'm trying to save my rant about that once I've  gotten an application completed and can help provide more useful  feedback.&amp;nbsp; In the mean time I wanted to cover a set of changes to my  python code that will made the QML port a bit easier.&amp;nbsp; This is regarding  code to make it easy both for users to provide good bug reports and for  me to figure out what went wrong.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;tl;dr&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Some sample programs that demonstrate the ideas in this post&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://github.com/epage/PythonUtils/blob/master/qml_error_display.py#L34"&gt;Reporting python logging events to the user&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://github.com/epage/PythonUtils/blob/master/qt_error_display.py"&gt;Logging helpers&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;I. print "This isn't right!"&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;Early  on in developing for Maemo my applications made use of "print"  statement and the "warning" module.&amp;nbsp; The steps needed to report an issue  were&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Suspect something is wrong&lt;/li&gt;&lt;li&gt;Close Application&lt;/li&gt;&lt;li&gt;Open terminal&lt;/li&gt;&lt;li&gt;&lt;i&gt;APPLICATION&lt;/i&gt; &amp;gt; log&lt;/li&gt;&lt;li&gt;Hope the problem will be able to be reproduced &lt;/li&gt;&lt;li&gt;Close application&lt;/li&gt;&lt;li&gt;Email log file and try to remember to include context like device / maemo version and app version&lt;/li&gt;&lt;/ol&gt;Its bad enough the user has to do anything but with this they had to use the terminal and reproduce the problem.&lt;br /&gt;&lt;br /&gt;Once  I even got a log its value was only as good as what I decided to print  out to it.&amp;nbsp; I only got what I put into it which was pretty simple with  few indications of where I was even printing.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;II. logging.warn("Just a touch bit better")&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Once I made it over the hurdle of adapting to the &lt;a href="http://docs.python.org/library/logging.html"&gt;logging module&lt;/a&gt; things improved drastically.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Suspect something is wrong&lt;/li&gt;&lt;li&gt;Hit Ctrl+i&lt;/li&gt;&lt;li&gt;Paste into a text editor&lt;/li&gt;&lt;li&gt;Email resulting file&lt;/li&gt;&lt;/ol&gt;That  is better but still too much friction for users to report problems.&amp;nbsp;  The quality of the logs is a lot better though.&amp;nbsp; Off the bat logging  offered the following&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Levels&lt;/li&gt;&lt;li&gt;Time stamps&lt;/li&gt;&lt;li&gt;logging.exception records the timestamp&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;Logging Locations:&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Originally  I used the root logger.&amp;nbsp; Eventually I found out about per-module  loggers (you can even do more granular loggers but I've not seen the  need). &lt;br /&gt;&lt;br /&gt;At the top of each module I have:&lt;br /&gt;&lt;blockquote&gt;_moduleLogger = logging.getLogger(__name__)&lt;/blockquote&gt;Then rather than&lt;br /&gt;&lt;blockquote&gt;&lt;span style="color: #274e13;"&gt;try&lt;/span&gt;:&lt;br /&gt;&amp;nbsp;&amp;nbsp; a = []&lt;br /&gt;&amp;nbsp;&amp;nbsp; a[0]&lt;br /&gt;&lt;span style="color: #274e13;"&gt;except&lt;/span&gt;:&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;b&gt;logging&lt;/b&gt;.exception(&lt;span style="color: #660000;"&gt;"This isn't good"&lt;/span&gt;)&lt;/blockquote&gt;&lt;i&gt;ERROR &lt;b&gt;root&lt;/b&gt;: Internal Error: 'NoneType' object has no attribute 'scene'&lt;br /&gt;Traceback (most recent call last):&lt;br /&gt;...&lt;br /&gt;AttributeError: 'NoneType' object has no attribute 'scene'&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;I do&lt;br /&gt;&lt;blockquote&gt;&lt;span style="color: #274e13;"&gt;try&lt;/span&gt;:&lt;br /&gt;&amp;nbsp;&amp;nbsp; a = []&lt;br /&gt;&amp;nbsp;&amp;nbsp; a[0]&lt;br /&gt;&lt;span style="color: #274e13;"&gt;except&lt;/span&gt;:&lt;br /&gt;&amp;nbsp;&amp;nbsp; _&lt;b&gt;moduleLogger&lt;/b&gt;.exception(&lt;span style="color: #660000;"&gt;"This isn't good"&lt;/span&gt;)&lt;/blockquote&gt;&lt;i&gt;ERROR &lt;b&gt;module_name&lt;/b&gt;: Internal Error: 'NoneType' object has no attribute 'scene'&lt;br /&gt;Traceback (most recent call last):&lt;br /&gt;...&lt;br /&gt;AttributeError: 'NoneType' object has no attribute 'scene'&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Log Destination:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I originally had the  problem that I either logged to a file or logged to the console.&amp;nbsp; The  console was nice for my debugging on the desktop while a file was  mandatory for users to avoid the command line when collecting debug  information.&amp;nbsp; I resolved this by having separate scripts each initialize  different logging destinations.&amp;nbsp; Another problem was log bloat.&amp;nbsp; I had  resolved that by deleting the log on upgrade.&amp;nbsp; Unfortunately as my  software matured, upgrades became infrequent and logs grew.&amp;nbsp; So I  settled on the following:&lt;br /&gt;&lt;blockquote&gt;logFormat = &lt;span style="color: #660000;"&gt;'(%(relativeCreated)5d) %(levelname)-5s %(threadName)s.%(name)s.%(funcName)s: %(message)s'&lt;/span&gt;&lt;br /&gt;logging.basicConfig(level=logging.DEBUG, format=logFormat)&lt;br /&gt;&lt;br /&gt;rotating = logging.handlers.RotatingFileHandler(logPath, maxBytes=&lt;span style="color: #0c343d;"&gt;512*1024&lt;/span&gt;, backupCount=&lt;span style="color: #0c343d;"&gt;1&lt;/span&gt;)&lt;br /&gt;rotating.setFormatter(logging.Formatter(logFormat))&lt;br /&gt;&lt;br /&gt;root = logging.getLogger()&lt;br /&gt;root.addHandler(rotating)&lt;br /&gt;_moduleLogger.debug(&lt;span style="color: #660000;"&gt;"%s %s-%s"&lt;/span&gt;, constants.APP_NAME, constants.VERSION, constants.BUILD)&lt;br /&gt;_moduleLogger.debug(&lt;span style="color: #660000;"&gt;"OS: %s"&lt;/span&gt;, os.uname()[&lt;span style="color: #0c343d;"&gt;0&lt;/span&gt;])&lt;br /&gt;_moduleLogger.debug(&lt;span style="color: #660000;"&gt;"Kernel: %s (%s) for %s"&lt;/span&gt;, *os.uname()[&lt;span style="color: #0c343d;"&gt;2&lt;/span&gt;:])&lt;br /&gt;_moduleLogger.debug(&lt;span style="color: #660000;"&gt;"Hostname: %s"&lt;/span&gt;, os.uname()[&lt;span style="color: #0c343d;"&gt;1&lt;/span&gt;])&lt;/blockquote&gt;With adding a second handler (size limited one at that) I am now getting both &lt;i&gt;stdout&lt;/i&gt; and file logging.&amp;nbsp; You'll also see demonstrated: &lt;br /&gt;&lt;ul&gt;&lt;li&gt;Time stamps&lt;/li&gt;&lt;li&gt;Thread information&lt;/li&gt;&lt;li&gt;Module name&lt;/li&gt;&lt;li&gt;Function name&lt;/li&gt;&lt;li&gt;Logging OS information / App information&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;logging.exception:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;To help with logging exceptions I created a &lt;a href="https://github.com/epage/PythonUtils/blob/master/util/misc.py#L46"&gt;decorator to log all exceptions&lt;/a&gt; that escape my application.&amp;nbsp; For a Qt application this would be around the slots.&lt;br /&gt;&lt;blockquote&gt;&lt;span style="color: black;"&gt;@PySide.Slot()&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #274e13;"&gt;&lt;/span&gt;@misc.log_exception(_moduleLogger)&lt;br /&gt;&lt;span style="color: #274e13;"&gt;&lt;/span&gt;&lt;span style="color: #274e13;"&gt;def&lt;/span&gt; &lt;span style="color: #783f04;"&gt;_on_shown&lt;/span&gt;(self):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #0c343d;"&gt;1/0&lt;/span&gt;&lt;/blockquote&gt;&lt;i&gt;ERROR module_name: Internal Error: ZeroDivisionError: integer division or modulo by zero&lt;/i&gt;&lt;br /&gt;&lt;i&gt;Traceback (most recent call last):&lt;br /&gt;...&lt;br /&gt;ZeroDivisionError: integer division or modulo by zero&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;III. self._errorLog.push_error("Inform the user") &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/-l_g3Cr9M8Bg/TmlXoYPvYYI/AAAAAAAAEj0/LMx-95bZbag/s1600/QWidget+Error+Notification.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" id=":current_picnik_image" src="http://2.bp.blogspot.com/-l_g3Cr9M8Bg/TmlXoYPvYYI/AAAAAAAAEj0/LMx-95bZbag/s1600/QWidget+Error+Notification.png" /&gt;&lt;/a&gt;I eventually generalized the &lt;a href="https://github.com/epage/PythonUtils/blob/master/qt_error_display.py"&gt;error reporting system&lt;/a&gt;  of one of my applications to mimic Firefox-style notification bars.&amp;nbsp; I  separated this out into a view / model and added some helpers to provide  similar features to my logging code.&amp;nbsp; This does a great job of taking  the guess work away from the user of  determining what is expected behavior when they see something they think  is strange.&lt;br /&gt;&lt;br /&gt;Examples of some helpers:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="color: #783f04;"&gt;with&lt;/span&gt; qui_utils.notify_error(self._errorLog):&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color: #0c343d;"&gt;1/0&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #783f04;"&gt;with&lt;/span&gt; qui_utils.notify_busy(self._errorLog, &lt;span style="color: #660000;"&gt;"Counting..."&lt;/span&gt;):&lt;/blockquote&gt;&lt;blockquote&gt;&lt;i&gt;&amp;nbsp;&amp;nbsp; ... Long Running Background Thread Task...&lt;/i&gt;&lt;/blockquote&gt;The  log model had to be passed around to each instance that wanted to  report problems which worked fairly well for Qt/QWidget especially since  I did a horrible job separating logic into MVC.&amp;nbsp; For QML I didn't want  to have to do that for every one of my models that QML required me to  have.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;IV. Logging, QML, and Notification Bars&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To resolve the issue of reporting to the user issues without every model having "self._errorLog" I decided to create my own &lt;a href="https://github.com/epage/PythonUtils/blob/master/util/io.py#L235"&gt;log handler&lt;/a&gt;.&amp;nbsp; Now I am able to easily notify the user of internal errors from anywhere in my &lt;a href="https://github.com/epage/PythonUtils/blob/master/qml_error_display.py#L34"&gt;program&lt;/a&gt;  (please excuse my python and QML, I'm still struggling with what I  think is the "right" way to do structure / write a Python/QML app).&lt;br /&gt;&lt;br /&gt;Things that could be improved:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It can only handle a discrete set of log levels&lt;/li&gt;&lt;li&gt;The notification bar looks need drastic improvements&lt;/li&gt;&lt;li&gt;Possibly add a notification count bubble for when there are several active notifications&lt;/li&gt;&lt;li&gt;Somehow expose one or all of the following:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;all active notifications list view&lt;/li&gt;&lt;li&gt;more of the message than the first line&lt;/li&gt;&lt;li&gt;emailing the application developer the full log&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;If I get all of those improvements done, the user experience will be:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Get a notification of an internal error&lt;/li&gt;&lt;li&gt;Select "send report" or later hit Ctrl+i&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;V. Ode to Python&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;All  of this would have been a lot more work, a lot uglier, and without as  much useful information if I was doing this all in C++.&amp;nbsp; It has made a  big difference in improving the error reports I've gotten from users so I  can more quickly resolve their problems.&amp;nbsp; I just wish I had such  powerful tools at my day job where I do C++ development.&lt;br /&gt;&lt;br /&gt;Now back to struggling with QML.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-5230892648499512574?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/5230892648499512574/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2011/09/porting-to-pysideqml-notification-bar.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/5230892648499512574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/5230892648499512574'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2011/09/porting-to-pysideqml-notification-bar.html' title='Porting to PySide/QML: Notification Bar'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-l_g3Cr9M8Bg/TmlXoYPvYYI/AAAAAAAAEj0/LMx-95bZbag/s72-c/QWidget+Error+Notification.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-7098727475357985768</id><published>2011-08-13T19:34:00.001-05:00</published><updated>2011-08-13T19:34:08.536-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>A Swipe UX Idea</title><content type='html'>Over my desk at work I have a sign that says "On my deathbed I would design a better deathbed".&lt;br /&gt;&lt;br /&gt;I've been using the N950 now for several weeks and I can't help thinking about how I would do things differently.&amp;nbsp; This is not meant to criticize Nokia's work on Swipe.&amp;nbsp; Swipe works well as a universal gesture.&amp;nbsp; Even if there are issues with it you and I should recognize this is beta software.&amp;nbsp; I've heard Nokia has already made one change to swipe since my software build and who knows what else might change before release.&lt;br /&gt;&lt;br /&gt;I'm just curious about how else things could be done and the effect they might have on the user experience.&amp;nbsp; I don't think Nokia should immediately drop everything and switch to my idea.&amp;nbsp; I first would like to see what they come up with in the finished project.&amp;nbsp; If I still think mine is better?&amp;nbsp; Oh well.&amp;nbsp; People think and act differently, especially programmers, and they are probably targeting others.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Swipe UX&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I'd recommend &lt;a href="http://www.developer.nokia.com/swipe/ux/pages/PB_Unlocking_the_Device.html"&gt;these demos&lt;/a&gt; for a quick introduction into swipe.&amp;nbsp; The main swipes will bring you back to the last home screen you used.&amp;nbsp; When wanting to swipe to a specific screen you swipe back to the home screen you were on, pause to see which it was, and then swipe over.&amp;nbsp; You can go about it faster by remembering what screen you were on.&amp;nbsp; I usually think I know where I was but I tend to be wrong leading me to swipe a few more times.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;My variant on Swipe UX&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;My idea centers on a spatial model that spans home screens, the lock screen, and applications.&amp;nbsp; This could roughly be translated to virtual desktops with rules controlling which desktop different windows get launched on based on the desktop's role.&lt;br /&gt;&lt;br /&gt;Launch an app, no matter from what screen?&amp;nbsp; As it is opening the device also slides home screens over to the task switcher.&amp;nbsp; Now with the app up a swipe down reveals the task switcher below.&amp;nbsp; If instead you swipe up the app closes.&amp;nbsp; Also you can swipe to the right to move to the launcher or left to move to the events feed.&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-yOZVryHD3wM/TkZq_DKGN2I/AAAAAAAAEjc/iE9KrNgNxL8/s1600/Swipe+UX+Idea+Event.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="225" src="http://3.bp.blogspot.com/-yOZVryHD3wM/TkZq_DKGN2I/AAAAAAAAEjc/iE9KrNgNxL8/s320/Swipe+UX+Idea+Event.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Idea: Swipe up or down from the lock screen to unlock and reveal the feed&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;The device goes to sleep?&amp;nbsp; The lock screen is above the events feed.&amp;nbsp; A swipe up or down reveals the feed below.&amp;nbsp; Instead a swipe right moves to the task switcher and left for the launcher.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-iqafCKAIRcU/TkZrBaHEsdI/AAAAAAAAEjg/4TAJnfieEYQ/s1600/Swipe+UX+Idea+Launcher.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="188" src="http://3.bp.blogspot.com/-iqafCKAIRcU/TkZrBaHEsdI/AAAAAAAAEjg/4TAJnfieEYQ/s320/Swipe+UX+Idea+Launcher.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Idea: Swipe left on the lock screen to unlock and move to the launcher&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Open up a folder of icons? The subfolder opens up above the launcher.&amp;nbsp; A swipe up or down to reveals the main launcher below.&amp;nbsp; &amp;nbsp; This would provide a simple UI for subfolders to be built into the launcher..&amp;nbsp; Again instead a swipe right moves to the events feed, and left for the task switcher.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-DHCj3p60tVE/TkZrDuwmUBI/AAAAAAAAEjk/5nTJzrmsOhs/s1600/Swipe+UX+Idea+Switcher.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="172" src="http://3.bp.blogspot.com/-DHCj3p60tVE/TkZrDuwmUBI/AAAAAAAAEjk/5nTJzrmsOhs/s320/Swipe+UX+Idea+Switcher.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Idea: Swipe Right on the lock screen to unlock and move to task switcher&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Applications, home screens, and the lock screen would operate on a more consistent set of simpler rules using a spatial model for the home screens rather than most-recently-used.&amp;nbsp; From where you are you would always know how to get to where you want to be with one swipe without a pause to think of which screen you are on and what direction you need to go to get to where you want or having to keep an accurate mental copy of the device state.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: x-small;"&gt;*Note: The images are mockups only and were hacked together from screenshots I found through Google.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-7098727475357985768?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/7098727475357985768/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2011/08/swipe-ux-idea.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/7098727475357985768'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/7098727475357985768'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2011/08/swipe-ux-idea.html' title='A Swipe UX Idea'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-yOZVryHD3wM/TkZq_DKGN2I/AAAAAAAAEjc/iE9KrNgNxL8/s72-c/Swipe+UX+Idea+Event.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-1395975847148463273</id><published>2011-08-13T19:07:00.000-05:00</published><updated>2011-08-13T19:07:51.390-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>Python Packaging for Harmattan</title><content type='html'>Right now I am taking a break from learning QML.&amp;nbsp; Instead I've been adding support for Harmattan to my existing QWidget projects.&amp;nbsp; It might seem pretty pointless because of how aweful QWidget can be with the default theme.&amp;nbsp; I will at least have the apps available if I need them in a bind.&amp;nbsp; Also taking working apps and repackaging them rather than new untested apps provides the benefit of controlling the number of variables to debug when things go wrong.&lt;br /&gt;&lt;br /&gt;I will be focusing on packaging for OBS seeing as a QWidget-based application isn't worth pushing through OVI.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Packaging&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;I had to switch my applications packaging over from my &lt;a href="http://www.manatlan.com/page/py2deb"&gt;py2deb&lt;/a&gt; fork to the distutils-based &lt;a href="https://gitorious.org/sdist_maemo"&gt;sdist_maemo&lt;/a&gt;.&amp;nbsp; A big reason is sdist_maemo already has Harmattan support.&amp;nbsp; I also figured it was a good idea to switch to distutils as it is more "proper" python packaging and because it is pluggable for various target packaging systems.&amp;nbsp; That last part will allow me to continue to support Maemo 4.1/5 and in the future support regular MeeGo.&lt;br /&gt;&lt;br /&gt;So first I've moved all of my files to a proper distutils based layout&lt;br /&gt;&lt;ul&gt;&lt;li&gt;./setup.py&lt;/li&gt;&lt;li&gt;./&lt;i&gt;LauncherName&lt;/i&gt; &lt;/li&gt;&lt;li&gt;./&lt;i&gt;package-name&lt;/i&gt;/*.py&lt;/li&gt;&lt;li&gt;./data/&lt;i&gt;package-name&lt;/i&gt;.desktop&lt;/li&gt;&lt;li&gt;./data/&lt;i&gt;package-name&lt;/i&gt;.png&lt;/li&gt;&lt;/ul&gt;I try to reuse code and packaging infrastructure between my projects so this means I need an easy way to diff between them, so I added a symlink from "./&lt;i&gt;package-name&lt;/i&gt;/" to "./src".&lt;br /&gt;&lt;br /&gt;I then wrote my setup.py file with an sdist_maemo command configured for each of my target deb-based distributions.&amp;nbsp; A nice thing to know is that for Maemo 5 the python module will be &lt;a href="http://wiki.maemo.org/Free_up_rootfs_space#Optify_Python"&gt;optified&lt;/a&gt; for you.&lt;br /&gt;&lt;br /&gt;An annoying thing is each platform has different packaging requirements.&amp;nbsp; Some examples include:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Different ".desktop" file locations&lt;/li&gt;&lt;li&gt;&lt;a href="http://library.developer.nokia.com/index.jsp?topic=/MeeGo_1.2_Harmattan_API/html/guide/html/main.html"&gt;Different&lt;/a&gt; ways of launching the app from within a desktop file. &lt;/li&gt;&lt;li&gt;Everything seems different with the app launcher icon&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.developer.nokia.com/Community/Wiki/N9_Development_-_Tips_and_Tricks#Application_icon_in_Application_Grid_.2F_Home"&gt;80x80&lt;/a&gt; pixels&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.developer.nokia.com/Community/Wiki/Harmattan:Platform_Guide/Publishing_with_Harmattan_Platform_SDK/Packaging_your_application_with_Harmattan_Platform_SDK#Adding_an_application_icon"&gt;SVG recommended&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.developer.nokia.com/Community/Wiki/Harmattan:Platform_Guide/Publishing_with_Harmattan_Platform_SDK/Packaging_your_application_with_Harmattan_Platform_SDK#Adding_an_application_icon"&gt;Stored in &lt;tt&gt;/usr/share/themes/base/meegotouch/icons/&lt;/tt&gt;&lt;/a&gt; &lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Different icon sizes for the Maemo-Icon-26 field&lt;/li&gt;&lt;li&gt;Different .deb sections&lt;/li&gt;&lt;li&gt;Different dependency names&lt;/li&gt;&lt;li&gt;Aegis file support (not needed for current apps so skipped over) &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;/ul&gt;Already the differences between Maemo 4.1 and Maemo 5 were annoying from a packaging perspective.&amp;nbsp; This makes the problem even bigger.&amp;nbsp; One approach I've always rejected was maintaining separate packaging scripts for each distribution requiring me to keep duplicate information like the version number.&amp;nbsp; The approach I used with py2deb was passing a parameter in to my script to change what was passed to py2deb.&amp;nbsp; That doesn't seem to jive with distutils.&amp;nbsp; So I threw in a touch of code-gen using a nifty tool called &lt;a href="http://nedbatchelder.com/code/cog/index.html"&gt;cog&lt;/a&gt;.&lt;br /&gt;To minimize my need for using code-gen my setup.py file creates multiple instances of sdist_maemo, one for each platform. &lt;br /&gt;&lt;br /&gt;The app icon caused me some problems.&amp;nbsp; I had assumed it would operate like previous versions of Maemo and desktop Linux, that if you just said "ejpi" or "gonvert" it would look for the appropriate icon size in "/usr/share/icons/hicolor".&amp;nbsp; I'm glad I found &lt;a href="http://www.developer.nokia.com/Community/Wiki/Harmattan:Platform_Guide/Publishing_with_Harmattan_Platform_SDK/Packaging_your_application_with_Harmattan_Platform_SDK#Adding_an_application_icon"&gt;that document&lt;/a&gt; explaining otherwise.&amp;nbsp; As an alternative some of the apps in the OVI Store just hard code an absolute path. When you do make a mistake on this, Harmattan seems to have two different default icons.&amp;nbsp; The red square came up for me when "ejpi" didn't map to an icon.&amp;nbsp; The green curved icon came up when I had an absolute path that pointed at nothing.&lt;br /&gt;&lt;br /&gt;My makefile creates the needed icons, code-gens my desktop files, code-gens my setup.py files, and then runs "setup.*.py sdist_*".&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Odds and Ends&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I do not believe PyQt is available for Harmattan, so I had to finish adding support for PySide in my applications.&amp;nbsp; I've made it easy to use both bindings by &lt;a href="https://github.com/epage/ejpi/blob/master/ejpi/util/qt_compat.py"&gt;centralizing&lt;/a&gt; all knowledge of the differences between the two.&lt;br /&gt;&lt;br /&gt;I've tried to make the switch a couple of times already but each time I came across new bugs that the old bugs prevented me from seeing.&amp;nbsp; Luckily the PySide people are quick at resolving these issues and by 1.0.5 my applications ran smoothly.&lt;br /&gt;&lt;br /&gt;I went ahead and made the simple switch to XDG and Harmattan-style icons though I'm not yet seeking OVI compliance.&amp;nbsp; I decided to redo the icons.&amp;nbsp; They weren't all that great, no where near the &lt;a href="http://www.developer.nokia.com/swipe/ux/pages/Icons.html"&gt;icon guidelines&lt;/a&gt;, and I wanted SVGs so I could use the &lt;a href="http://depot.javispedro.com/nit/hicg/"&gt;Harmattan Icon Generator&lt;/a&gt;.&amp;nbsp; Not being an expert at graphics tools, the icon generator definitely saved me a good amount of work.&amp;nbsp; The main drawback is that basing the icons background gradient on the base icon's content seems to produce results without enough contrast.&amp;nbsp; I ended up using the "mean" setting to force gray backgrounds.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Distributing&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Now that we have all that wrapped up, time to upload onto the OBS.&amp;nbsp; The &lt;a href="http://wiki.meego.com/Getting_started_with_OBS"&gt;Getting Started Guide&lt;/a&gt; has been updated and now is pretty good.&amp;nbsp; I setup a harmattan-specific subproject due to my code-gen specializing the source-packages per distribution.&amp;nbsp; Once everything was uploaded to my project, I logged in as &lt;a href="http://wiki.meego.com/Migrating_from_N900_to_N950#root"&gt;root&lt;/a&gt;, &lt;a href="http://wiki.meego.com/Getting_started_with_OBS#Into_Harmattan"&gt;added my sources&lt;/a&gt;, and away I went.&lt;br /&gt;&lt;br /&gt;So for the fruit of my work:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://github.com/epage/ejpi"&gt;ejpi&lt;/a&gt; and &lt;a href="https://github.com/epage/Gonvert"&gt;gonvert&lt;/a&gt; source including support for Maemo 4.1, Maemo 5, and Harmattan&lt;/li&gt;&lt;li&gt;&lt;a href="https://build.pub.meego.com/project/show?project=home%3Aepage%3Aharmattan"&gt;my Harmattan OBS project&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://repo.pub.meego.com//home:/epage:/harmattan/Harmattan"&gt;my Harmattan repository&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Well I guess this means I need to get back to learning QML. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;Resources&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Desktop File:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://standards.freedesktop.org/desktop-entry-spec/1.0/ar01s05.html"&gt;Desktop File Spec&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://wiki.meego.com/Porting_Fremantle_Applications_to_Harmattan#Change_Paths_for_Desktop_Files_etc."&gt;Desktop File location change since Maemo 5&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://library.developer.nokia.com/index.jsp?topic=/MeeGo_1.2_Harmattan_API/html/guide/html/main.html"&gt;Speed Booster&lt;/a&gt; &lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;XDG&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html"&gt;Spec&lt;/a&gt;&lt;br /&gt;  &lt;/li&gt;&lt;/ul&gt;Icon&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.developer.nokia.com/swipe/ux/pages/Icons.html"&gt;Guidelines&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://depot.javispedro.com/nit/hicg/"&gt;Icon Generator with Color suggestions&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Finding icons&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://thenounproject.com/"&gt;The Noun Project&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.iconfinder.com/"&gt;Icon Finder&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://findicons.com/"&gt;Find Icons&lt;/a&gt;&lt;br /&gt;  &lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;Package&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections"&gt;Debian official section list&lt;/a&gt;&amp;nbsp; &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.developer.nokia.com/Community/Wiki/Harmattan:Developer_Library/Reference_documentation/Harmattan_Appendix_to_the_Debian_Policy_Manual"&gt;.deb policy addendum&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;OBS&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://draft.blogger.com/blogger.g?blogID=14883822#editor/target=post;postID=1395975847148463273"&gt; &lt;/a&gt;&lt;a href="http://wiki.meego.com/Getting_started_with_OBS"&gt;Getting Started with OBS&lt;/a&gt; (including both MeeGo and Harmattan)&lt;/li&gt;&lt;li&gt;Plan for &lt;a href="http://wiki.meego.com/MeeGo_Apps"&gt;Apps&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-1395975847148463273?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/1395975847148463273/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2011/08/python-packaging-for-harmattan.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/1395975847148463273'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/1395975847148463273'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2011/08/python-packaging-for-harmattan.html' title='Python Packaging for Harmattan'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-7850598246043707333</id><published>2011-07-19T22:12:00.000-05:00</published><updated>2011-07-19T22:12:15.083-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>N950 Arrival and My Development Plans</title><content type='html'>A couple of weeks ago I was notified by Quim Gil that I was selected for the MeeGo Community Developer Device Program for a Nokia N950 devkit.&amp;nbsp; Prior to this I had been quiet in Maemo-land for a little bit while I worked on an experimental rewrite of one of my applications that uses PyGame.&amp;nbsp; Seeing as PyGame isn't on the N950 I hurried up in getting it to a state I could put aside and moved on to learning QML.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-TT8QDsVsw1c/TiYRVo0ws1I/AAAAAAAAEgI/jZGze36IpNc/s1600/20110718_003.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="180" src="http://4.bp.blogspot.com/-TT8QDsVsw1c/TiYRVo0ws1I/AAAAAAAAEgI/jZGze36IpNc/s320/20110718_003.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The excitement increased as I saw the box personalized with my name regardless of that personalization just being a piece of tape&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;b&gt;MeeGo Development &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;My development plans have changed (and frustration increased) over time as the MeeGo development story has gotten refined.&amp;nbsp; This is due to both changes in the UI toolkit availability and rules for distribution of applications.&lt;br /&gt;&lt;br /&gt;Originally when things shifted to Qt I chose QWidget because it was ready now, includes widgets, and was &lt;a href="http://www.developer.nokia.com/Community/Wiki/index.php?title=Porting_Mobile_Applications_to_Qt&amp;amp;oldid=101807"&gt;recommended&lt;/a&gt; by Nokia (you know, the people who own Qt) for the types of apps I write (which recommendation was removed on June 22, 2011).&amp;nbsp; At MeeGo Conference I found out that some (most? all?) MeeGo instances are not including QWdget themes (which without a theme its basically dead).&amp;nbsp; QWidget in Qt5 will be optional and will probably not be included on those same MeeGo instances that currently don't ship a theme.&amp;nbsp; So there goes that work.&lt;br /&gt;&lt;br /&gt;I am still a bit frustrated with QML in that there is not even a subset of common QML Components between platforms though some &lt;a href="http://achipa.blogspot.com/2011/07/qt-components-story-of-ugly-qwidgetling.html"&gt;disagree on it being a problem&lt;/a&gt;.&amp;nbsp; I've just seen really terrible QML  applications which mostly stem from everyone reinventing the same bugs  when writing widgets from scratch.&amp;nbsp; I also find it a wonderful experience having the widgets available for the desktop such that I can write apps in a desktop environment that are targeted for small screens without the need for any pesky IDEs and emulation.&amp;nbsp; When it comes to testing, I am much more efficient testing and debugging natively on the desktop and just need to spot check how it translates to my devices.&lt;br /&gt;&lt;br /&gt;I do not look forward to packaging for generic MeeGo.&amp;nbsp; I found out at MeeGo conference that dependency management isn't guaranteed to be included and one has to include in their package any dependencies outside of core MeeGo.&amp;nbsp; This is fine for compiled applications, you just pull in static libs.&amp;nbsp; This is not as simple for Python developers where part of the beauty is your program isn't compiled and any compiled extensions are distributed and maintained separately.&amp;nbsp; I have contemplated some tools to simplify this (based on &lt;a href="http://cx-freeze.sourceforge.net/"&gt;cx-freeze &lt;/a&gt;and &lt;a href="https://github.com/rfk/pysidekick/blob/master/PySideKick/Hatchet.py"&gt;Hatchet&lt;/a&gt;) but that is a good amount of work and focused away from what makes all of this fun.&lt;br /&gt;&lt;br /&gt;At MeeGo conference I raised my concern for packaging Python applications during the apps.meego.com lunch time BoF.&amp;nbsp; The impression I got then (no clue if things have changed) is that they will focus on MeeGo compliant apps at first and might later support others.&amp;nbsp; Even with that concession this is a stark contrast to the original vision that helped bring me on board from Maemo about (what was then called) Surrounds which would serve both as an app repo and as a place for third-party dependencies.&amp;nbsp; If I chose to not bundle all of my libraries then I also am not available for any of the other distribution channels (and any contests they might be running).&amp;nbsp; I don't program for the reward of the contests but it isn't fun feeling excluded.&lt;br /&gt;&lt;br /&gt;The beauty of developing for Maemo was it had very low friction in the development story thanks to Python that I was able to spend more time focusing on what was fun: designing software for end-users to enjoy.&amp;nbsp; I feel that this is being lost in MeeGo.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;MeeGo and Nokia&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The picture can be better when focusing on a individual vendors.&amp;nbsp; Vendors may keep things a bit more lax with their distribution channels.&amp;nbsp; The problem is then you are customizing per vendor which requires device availability for testing and a lot more work.&amp;nbsp; That vendor has to be worth it.&lt;br /&gt;&lt;br /&gt;Nokia is worth it (even without the DDP).&amp;nbsp; Nokia actually shipped a great device previously (N900 running Maemo5) and is committed to shipping the N9.&amp;nbsp; That is a lot more than other vendors can say.&amp;nbsp; On top of that Nokia offers a great experience with the software and hardware.&amp;nbsp; So as a user, Nokia is worth it.&amp;nbsp; What about as a developer?&amp;nbsp; Nokia has Qt Quick Components to provide reusable QML widgets.&amp;nbsp; They also will support dependencies and have &lt;a href="http://lists.meego.com/pipermail/meego-python/2011-June/000051.html"&gt;Python/PySide available in their store&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Way Forward&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;For my initial ports I will continue to focus on what keeps this fun, writing apps for end-users despite any downsides of being vendor specific.&amp;nbsp; After that I will bite the bullet of making my applications MeeGo compliant to make them available for a wider audience.&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-hnbk9mmzE0U/TiYRbow-yTI/AAAAAAAAEgU/9bCc_TH4Tfs/s1600/20110718_009.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-hnbk9mmzE0U/TiYRbow-yTI/AAAAAAAAEgU/9bCc_TH4Tfs/s320/20110718_009.jpg" width="180" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;The default date.&amp;nbsp; It's good to see somebody at Nokia has a sense of humor&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;I have work to do on all of my applications but I will be  focus on the ones that still use GTK first, especially since they are fairly  simple. &amp;nbsp; I am using &lt;a href="http://wiki.maemo.org/Quicknote"&gt;QuickNote&lt;/a&gt; as my playground for learning QML.&amp;nbsp; Expect further posts regarding progress updates and lessons learned regarding QML and MeeGo 1.2 Haramattan.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-7850598246043707333?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/7850598246043707333/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2011/07/n950-arrival-and-my-development-plans.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/7850598246043707333'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/7850598246043707333'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2011/07/n950-arrival-and-my-development-plans.html' title='N950 Arrival and My Development Plans'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-TT8QDsVsw1c/TiYRVo0ws1I/AAAAAAAAEgI/jZGze36IpNc/s72-c/20110718_003.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-5476881439705645658</id><published>2011-07-19T18:10:00.000-05:00</published><updated>2011-07-19T18:10:32.250-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Google CR-48</title><content type='html'>Today I was asked my opinion on my CR-48 ChromeOS netbook to help with a purchasing decision for a Chromebook.&amp;nbsp; I thought I'd share my thoughts of having used it for the last 6 months.&lt;br /&gt;&lt;br /&gt;I have a plethora of devices including most of the &lt;a href="http://www.flickr.com/photos/sjgadsby/5954394183/"&gt;Maemo family&lt;/a&gt; (just missing the n800), some netbooks I got free through various (legal) means, and my desktop.&lt;br /&gt;&lt;br /&gt;Whenever I am out and am needing something bigger than a handheld, I rarely choose something other than my CR-48.&amp;nbsp; This is because most of what I use are the various Google web apps and I can limp along on other use cases that don't fit in as well.&amp;nbsp; As an example, my CR-48 leaves the house once a week for my church meetings to assist me in my current responsibilities which is facilitating administrative matters so our congregational leaders get to focus more on assisting people.&amp;nbsp; An example of when I might chose another device is when I travel to various Maemo/MeeGo events where I'd want something that is a bit more prepared for python development.&lt;br /&gt;&lt;br /&gt;The other main use of my CR-48 is what I'll refer to as opportunistic internet usage.&amp;nbsp; What I am referring to is the reduction in friction when having the thoughts "Oh, I'd like to look up ..." or "I should record ... so I don't forget" enough that you will act upon that thought more often.&amp;nbsp; This is when I am sitting about the apartment (or out and about) and my phone isn't quite enough to satisfy my need.&amp;nbsp; This is something harder to quantify when doing comparisons so it is usually not even thought of.&amp;nbsp; A tablet could also serve this purpose well except they are pricier and don't have a physical keyboard.&lt;br /&gt;&lt;br /&gt;With any netbook you have to be honest with yourself about the reduced functionality due to their design, it is just more so the case for the CR-48 as you only have access to a web browser.&amp;nbsp; This can have some benefits though.&amp;nbsp; I remember an observation made to me back in the days of PalmOS.&amp;nbsp; My father preferred PalmOS because it wasn't imitating the desktop.&amp;nbsp; Why is that good?&amp;nbsp; When the imitation is too close you are more likely to get frustrated at the gaps when you come across them, sort of an &lt;a href="http://en.wikipedia.org/wiki/Uncanny_valley"&gt;uncanny valley&lt;/a&gt; of features.&lt;br /&gt;&lt;br /&gt;So what devices should someone have?&amp;nbsp; It depends on your use case.&amp;nbsp; I've generally been a person who has preferred a cheap portable with the work horse being their desktop.&amp;nbsp; This has the benefit of being less paranoid about the portable device and making it easier to replace it when needed combined with the cost savings of a desktops (especially when you go 6 years without replacing them).&amp;nbsp; It is hard to say what I would get myself when left to my own devices (pun intended) since so many of my devices have been free.&lt;br /&gt;&lt;br /&gt;ps If you are reading this and dream of robbing me, look further at the specs, release dates, and niche role of the various devices I listed.&amp;nbsp; It won't be worth it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-5476881439705645658?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/5476881439705645658/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2011/07/google-cr-48.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/5476881439705645658'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/5476881439705645658'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2011/07/google-cr-48.html' title='Google CR-48'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-6739518464901216783</id><published>2011-07-01T20:56:00.000-05:00</published><updated>2011-07-01T20:56:02.273-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><title type='text'>Google+</title><content type='html'>I still don't have too many people on Google+ but I thought I'd record my thoughts&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Circles &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I love them.&amp;nbsp; Some people are a bit confused about them and consider it a privacy risk that people can add you without your permission.&amp;nbsp; FB has the same problem but doesn't do a good job of telling you.&amp;nbsp; In FB if you send a friend request and it is never accepted/rejected then your feed will display any public updates from that person.&amp;nbsp; Google makes this explicit and emphasizes the benefit of it by having a "following" circle by default.&amp;nbsp; I think it is a much better and simpler model than "friending" products and people or "liking" their Page.&lt;br /&gt;&lt;br /&gt;I'm still playing with what I want in circles.&amp;nbsp; Too granular of circles means you have a lot more to manage for each post.&amp;nbsp; Right now I am looking at "family", "friends", "acquaintances", "local", and "professional"&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For cleaning up my circles over time, I'd appreciate a mass-edit mode where everyone is a row in a table and the columns are the circles they are in.&amp;nbsp; Bonus points for Google also showing who has not added me back and who I've not added back.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Posting&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I like that when commenting on posts you can see what the visibility is of that thread.&lt;br /&gt;&lt;br /&gt;Sometimes  privacy on my posts isn't a big deal, like talking about programming  for MeeGo.&amp;nbsp; It'd be nice if you could use your circles not just to  restrict communication but say "these people will actually care but allow it to be discoverable for people I'm not connected to yet".&lt;br /&gt;&lt;br /&gt;Another variant of that global-sharing-with-focused-audience use case is my use case for Twitter.&amp;nbsp; I originally joined twitter so I could track MeeGo Conference hashtag and know what else was going on around me while in attendance.&amp;nbsp; A Similar use case that a friend pointed out is tracking live news for things like the Texas legislative session.&amp;nbsp; I don't think I've seen a G+ equivalent system to hash tags but it will be hard for it to compete with Twitter without it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Notifications&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This is one of the killer features, being able to check on my notifications within GMail.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Feedback&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;It is nice that it is so easy to find how to provide feedback to Google on Google+.&amp;nbsp; It is also a really slick tool.&amp;nbsp; I've already sent them several items for improvement.&amp;nbsp; I hope they roll this out to their other services.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Integration with other Google products&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Currently there is some integration with Buzz and Picasa Web though I am unsure of what Buzz's role is now and am thinking of disabling it.&lt;br /&gt;&lt;br /&gt;I am looking forward to this being improved.&amp;nbsp; Good Google Calendar integration is a must for being a FB replacement.&amp;nbsp; Blogger shouldn't be too hard to also tie in.&amp;nbsp; I'd like them to solve the GMail / Google Reader integration issue but not too sure how they'll pull that off.&lt;br /&gt;&lt;br /&gt;Contacts integration is actually where users will probably see the  greatest troubles.&amp;nbsp; This is due to trying to bolt together different  services that don't always have their data coordinated.&amp;nbsp; Users have  unmerged GMail contacts, contacts creating G+ accounts with different  email addresses than what are in my contact book, and the various tags I  have from people.&amp;nbsp; It'll be a mess even with Google's help to try to  match up all of these representations of people. &lt;br /&gt;&lt;br /&gt;Back to Picasa Web.&amp;nbsp; I figured I should go back and update my tagging of people in my  pictures.&amp;nbsp; Sadly I can't find the really helpful mass-tag tool that lets  you look through all the faces it found and tag them.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Google Takeout&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;One of the reasons I am loyal to Google products (besides reducing the number of accounts I need) is the ability to leave and this is no different.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Final Thoughts&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;As I said, Google will need to improve their service integration and slowly ramp up their algorithms taking care of things for me.&lt;br /&gt;&lt;br /&gt;Reaching critical mass will be a challenge.&amp;nbsp; Some might compare this with the migration from MySpace but this is even harder seeing as there are even more users with more history in the service to leave behind.&amp;nbsp; Maybe that is a good thing, to have a fresh start, but there are some connections that might not transition over that I would miss.&lt;br /&gt;&lt;br /&gt;A question for me: where do I post things?&amp;nbsp; Facebook, Twitter, or G+?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-6739518464901216783?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/6739518464901216783/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2011/07/google.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/6739518464901216783'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/6739518464901216783'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2011/07/google.html' title='Google+'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-7000282108539721684</id><published>2011-06-06T21:05:00.000-05:00</published><updated>2011-06-06T21:05:13.627-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><title type='text'>Extrapolating</title><content type='html'>I give at the office, blood that is.&amp;nbsp; The organization that does it recently gave me access to my vitals through their website.&amp;nbsp; I finally took a look and a coworker made a startling &lt;a href="http://xkcd.com/605/"&gt;realization&lt;/a&gt;.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-RUpDcOi7iVc/TeZFulQ3cKI/AAAAAAAAEEY/Xa8sGbAYtI4/s1600/Pulse.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-RUpDcOi7iVc/TeZFulQ3cKI/AAAAAAAAEEY/Xa8sGbAYtI4/s1600/Pulse.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;I wonder if our cafeteria at work will start serving brains by 2012.&amp;nbsp; I bet Sodexo will charge an arm and a leg for it though.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-7000282108539721684?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/7000282108539721684/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2011/06/extrapolating.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/7000282108539721684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/7000282108539721684'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2011/06/extrapolating.html' title='Extrapolating'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-RUpDcOi7iVc/TeZFulQ3cKI/AAAAAAAAEEY/Xa8sGbAYtI4/s72-c/Pulse.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-6790442369975289216</id><published>2011-05-28T13:47:00.000-05:00</published><updated>2011-05-28T13:47:11.637-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>Meego Conference First Impressions</title><content type='html'>I am grateful for the opportunity to have gone to MeeGo Conference this week.&lt;br /&gt;&lt;br /&gt;As has been discussed, the keynote was a let down. I very much appreciate Jaffa's &lt;a href="http://www.maemopeople.org/index.php/jaffa/2011/05/28/meego_conference_keynote_how_it_should_v"&gt;analysis&lt;/a&gt; of the keynote.&amp;nbsp; The only thing I have to add is that there were rumors that the keynote was reworked at the last minute for various reasons and if this is the case we should be somewhat understanding, it is difficult pulling off a change like that.&lt;br /&gt;&lt;br /&gt;So what were my favorite things about MeeGo Conference?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;First&lt;/b&gt;, spending time with various members of the Maemo and MeeGo communities.&amp;nbsp; It was a lot of fun spending time together whether in sessions, meals, trips around town, or playing werewolf together.&amp;nbsp; It was great to see GeneralAntilles, Jaffa, Qole, sjgadsby, fiferboy, texrat, timsamoff, wazd, and many more.&lt;br /&gt;&lt;br /&gt;My &lt;b&gt;second&lt;/b&gt; favorite aspect of the conference was the collaboration.&amp;nbsp; I caught word of an apps.meego.com QA lunch BoF which was good as I don't remember if there were any other community app developers at the table to provide input from that perspective.&amp;nbsp; It was great to see the collaboration between geekygirldawn, xfade, lbt, bergie, and others.&lt;br /&gt;&lt;br /&gt;The main problems I see with where we are at with maemo.org extras is (1) the monotonically increasing version numbers between repos, causing pain if you have a "1.3" in extras-testing but need to push through a "1.2.1" due to say Google changing an API making the app in extras completely worthless, (2) the friction in the workflow for providing both testing and user feedback, (3) noise in extras-testing due to lack of cleanup, and (4) use of extras-devel rather than a PPA.&amp;nbsp; (3) and (4) are resolved, so hopefully we also get (1) and (2).&lt;br /&gt;&lt;br /&gt;Another aspect to the collaboration that I participated in was thp's Python presentation.&amp;nbsp; During the Q&amp;amp;A we had a bit of a discussion on viability for Python for various instances of Meego.&amp;nbsp; I'll cover this more in another post.&lt;br /&gt;&lt;br /&gt;The final part to collaboration which I got to observe was thp et al taking the loaner Exo PC's and creating a multi-touch pong game.&lt;br /&gt;&lt;br /&gt;The &lt;b&gt;third&lt;/b&gt; and final of my favorite parts of the conference was the sessions.&lt;br /&gt;&lt;br /&gt;Arjan Van De Ven's presentation was the best I saw due to his passion, his call to action, and audience (particularly Jaffa) raising issues with the internal communication within Intel being at friction with keeping MeeGo open.&amp;nbsp; A couple months ago he announced replacing several pieces of key software with other variants.&amp;nbsp; People took issue with no previous open discussion, few if any bug reports regarding Intel's complaints, possible NIH syndrome, and how much of this was spite towards Nokia for the switch.&amp;nbsp; Some interesting tidbits from what little I caught of that flame war were that some of the software being reverted to (evolution) has the same problems as what it is replacing (tracker) and the suggestion that software shouldn't be accepted until it is ready being at odds with the call to use innovative technologies.&amp;nbsp; Add on top of that last one the risk of "ready software" being more likely to be announced through unilateral big-reveals, shunning the in-the-open from-the-beginning software (here is looking at you MeeGo QML Components which I'll discuss more in a follow up post).&amp;nbsp; The main disappointment were a couple of potshots made at Nokia during the discussion.&lt;br /&gt;&lt;br /&gt;I do understand that there is a conflict between always-innovative/always-beta software and getting quality releases out now using tried and true software.&amp;nbsp; I think the main thing people take issue with is how this was done and how much more this will be done with Nokia taking a backseat role.&lt;br /&gt;&lt;br /&gt;The presentations on the future of Qt were also great even if they did raise my eyebrows on a few points (again, in a follow up post).&amp;nbsp; I got to see the Qt5 plans, Lighthouse, and QtQuick 2 presentations.&amp;nbsp; Unfortunately it wasn't until after-the-fact that I found out I should have also gone to MeeGo UX Components presentation (again, that promised follow up post).&lt;br /&gt;&lt;br /&gt;As I've previously mentioned, thp's Python presentation was great.&amp;nbsp; I also expect wazd's presentation to be good but forgot to go (and he even used some of my programs, shame on me).&amp;nbsp; I also have to say I was impressed with hopbeat's use of &lt;a href="http://prezi.com/"&gt;Prezi&lt;/a&gt; and would wish to never see a traditional power point again.&lt;br /&gt;&lt;br /&gt;Despite the let downs, MeeGo Conference was great.&amp;nbsp; It was also good to get some time dedicated to programming and to see more of &lt;a href="https://picasaweb.google.com/eopage/MeegoConferenceSanFrancisco?feat=directlink"&gt;San Francisco&lt;/a&gt; compared to my &lt;a href="https://picasaweb.google.com/eopage/MaemoDeveloperEvent?feat=directlink"&gt;last visit&lt;/a&gt; (I was a lot less lost thanks to a real GPS).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-6790442369975289216?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/6790442369975289216/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2011/05/meego-conference-first-impressions.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/6790442369975289216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/6790442369975289216'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2011/05/meego-conference-first-impressions.html' title='Meego Conference First Impressions'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-1022499775727436617</id><published>2011-05-19T17:50:00.001-05:00</published><updated>2011-05-19T17:53:51.362-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='spiritual'/><title type='text'>The Marriage Discussion</title><content type='html'>I was reading a friend's &lt;a href="http://sawasnow.blogspot.com/2011/05/men-and-marriage.html"&gt;blogpost&lt;/a&gt; and my response got a bit long (and now&amp;nbsp; there is&lt;a href="http://sawasnow.blogspot.com/2011/05/me-and-marriage.html"&gt;another post&lt;/a&gt; so I guess I also take too long to write also), so here we go. &lt;br /&gt;&lt;br /&gt;As was pointed out in the comments, Elder Oaks did also speak on the subject and did mention the sisters.&amp;nbsp; The proportions spent on each topic though is telling.&lt;br /&gt;&lt;br /&gt;I think we tend to simplify this subject a bit too much.&amp;nbsp; Many guys could probably claim the following paragraph from the post would apply to them:&lt;br /&gt;&lt;blockquote&gt;"I have so many girlfriends who wrack their brains about what they are doing that's keeping them from getting married. They wonder what's wrong with them and what they should be doing differently. They think that perhaps there's something else for them to learn before they get married. It's absolutely ridiculous! And though they mean well, some friends and family members don't help at all. They will often say things like, "You should act like this, or you should wear that." They go on and on about how men are stupid, and women need to practically bend over backward and be the aggressor to get men to see what they need to do. Essentially, they are making excuses for men and telling women to do all the work."&lt;/blockquote&gt;Well, except the last two sentences.&lt;br /&gt;&lt;br /&gt;Some of the factors I can think of include (which some can apply to both genders)&lt;br /&gt;&lt;ul&gt;&lt;li&gt;No desire.&amp;nbsp; Maybe it is a sampling bias but despite this one getting a lot of complaints this &lt;i&gt;doesn't&lt;/i&gt; apply to most guys I've met.&lt;/li&gt;&lt;li&gt;Desire but not priority&amp;nbsp; Sometimes we don't realize that we treat things with a lower priority those things we actually really want.&amp;nbsp; A lowered priority can be for obviously selfish reasons as "still wanting to have fun" or others like education and career.&lt;/li&gt;&lt;li&gt;Asking a person on a date being read into too much.&amp;nbsp; As President Hollingsworth pointed out, 10 years ago he was struggling to get people to go on second and third dates without them reading into things, now the problem is going on first dates without them being read into.&lt;/li&gt;&lt;li&gt;&lt;a href="http://lds.org/general-conference/2006/10/let-us-be-men?lang=eng"&gt;The 20s being the new teenage years&lt;/a&gt;.&amp;nbsp; This is especially the case with guys that are meandering through life rather than working to establish themselves in a career but face women around them that have or are working towards higher degrees.&amp;nbsp; Notice that I said "not working to establish" rather than "not established".&amp;nbsp; A guy actively working to establish his career whether through getting an education or growing in one's field is fine and should hold his head up.&amp;nbsp; This is also a problem spiritually.&amp;nbsp; If someone has been working to purify their desires, to fulfill the commandments, and serve those around them would they want to risk regressing through the negative influence&amp;nbsp; of someone who has not been developing themselves spiritually?&lt;/li&gt;&lt;li&gt;Trying really hard but not realizing they are doing it wrong.&amp;nbsp;&amp;nbsp;&amp;nbsp; One example: we've seen the times when a new cute girl or guy moves into a ward and everyone of the opposite gender surrounds that person and obsesses and fights over them for the next 4 months or so.&amp;nbsp; This is made more ridiculous by the fact that the attraction is skin deep and the person doesn't really seem to match them in their personality.&amp;nbsp; Sometimes it is helpful to take a step back and stop being so aggressive over being married to explore what you want and don't want through dating a variety of people and developing friendships that can blossom into a relationship.&lt;/li&gt;&lt;li&gt;And then there are the guys that girls ignore, turn down, or are even mean to.&amp;nbsp; This can because they aren't familiar with these guys, they are socially awkward, they are different but in a good way, different in a bad way, etc.&amp;nbsp; Hopefully if it is a bad way the guy recognizes this and is trying to improve but the way to improve is to be with people but others are so myopically focused on marriage they don't practice charity towards these people but see them as a waste of time on their path to marriage.&lt;/li&gt;&lt;/ul&gt;Those last two points mentioned the marriage/dating myopia and that is a topic of its own.&amp;nbsp; Sometimes it seems people's obsession over marriage is making them less ready for marriage.&amp;nbsp; I hear people talk about needing to have Christ in one's marriage and the need for selflessness.&amp;nbsp; People tend to be too focused on what they get out of a situation, who they'll get to flirt with, etc that they lose the opportunities to grow.&lt;br /&gt;&lt;br /&gt;One example is to not be early or even being late to church.&amp;nbsp; A person then loses out on the opportunity to meditate on the atonement and the sacrament.&amp;nbsp; If they hold the priesthood they also lose out on helping prepare, bless, or pass the sacrament.&amp;nbsp; One reason people might do this is so that they can chose who they sit by and maximize time during meetings to be with them.&lt;br /&gt;&lt;br /&gt;Another example is to just look at the amount of service offered to who, especially between two people that have needs.&amp;nbsp; Sometimes we neglect those who need it most because we get nothing out of it.&amp;nbsp; Granted there are other factors like how much the person needing service seeks help but we should be a lot more observant about these things.&lt;br /&gt;&lt;br /&gt;Pressure to get married can be good and help push people past their hang ups with selfishness and help them take a risk but I also worry that continued pressure over the years and a social/spiritual environment that focuses mostly on socializing as a means for encouraging marriage to the detriment of service, sacrifice, etc exacerbates the marriage myopia.&lt;br /&gt;&lt;br /&gt;I dislike not really having a purpose or conclusion to be building to so sorry for the jumble of not-fully-thought-out thoughts.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-1022499775727436617?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/1022499775727436617/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2011/05/marriage-discussion.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/1022499775727436617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/1022499775727436617'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2011/05/marriage-discussion.html' title='The Marriage Discussion'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-9201663020087196736</id><published>2011-05-06T07:13:00.000-05:00</published><updated>2011-05-06T07:13:55.447-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='spiritual'/><title type='text'>Forgiving Self and Others</title><content type='html'>Several months ago I was asked to speak during the main services of my Church. &amp;nbsp;In software development Bjarne&amp;nbsp;Stroustrup&amp;nbsp;stated&amp;nbsp;"Starting a major project 'completely from scratch' can be exhilarating. &amp;nbsp;However, often more accurate description is 'intoxicating' and the result is a drunkard's walk through the design alternatives". &amp;nbsp;I tend to agree with that and is a something I would like to improve on. &amp;nbsp;Similar to the challenge of starting new software projects from scratch is to chose one of a myriad of topics related to the Gospel and Jesus Christ and narrowing down a focus in that topic. &amp;nbsp;So I kindly asked for a topic and was given "Forgiving Self and Others".&lt;br /&gt;&lt;br /&gt;Someone had asked for some of material I used in my comments and I decided to go ahead and turn what I said into a post on the subject (and not just a transcript).&lt;br /&gt;&lt;br /&gt;President Spencer W. Kimball described forgiveness as “purging of our feelings and thoughts and bitternesses” (Miracle of Forgiveness Ch 18). &amp;nbsp;I believe these feelings that we need to purge are an impediment to our living the two great commandments. &amp;nbsp;How can we "love the Lord our God" if we deny the efficacy of the atonement in the lives of ourself and others, rejecting that great sacrifice that the Christ made for us? &amp;nbsp;How can we "love thy neighbor as thyself" if we don't love ourself, if we can't forgive ourself? &amp;nbsp;How can we love our neighbor if bear a grudge against our neighbor?&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Forgiving Self&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I contemplated reasons we might not forgive ourself. &amp;nbsp;The ones I was able to come up with include&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Incomplete Repentance&lt;/li&gt;&lt;li&gt;Needing increased faith and trust that we can be forgiven by Christ through the Atonement&lt;/li&gt;&lt;li&gt;Being too concerned with our perception of other's perception of ourself&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;To me it seems like we are in self-denial if we try to forgive ourselves without complete repentance. &amp;nbsp;I worry how much we are desensitizing ourselves to the influence of the Holy Ghost if we are trying to ignore the Holy Ghost's prodding for us to repent.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;On the other hand it can seem overwhelming to look at our vast array of imperfections and to think of trying to repent of them all. &amp;nbsp; &amp;nbsp;An analogy comes to mind for how to handle this.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If we were in a car accident and taken to the ER, what wounds would the doctors worry about first? &amp;nbsp;Scratches? &amp;nbsp;Your persisting foot infection you've never resolved? &amp;nbsp;A broken leg? &amp;nbsp;A pierced lung? &amp;nbsp;They would work on the life threatening injuries and as they are stabilized focus on the more debilitating damage. &amp;nbsp;They probably wouldn't even worry about the scratches until they are trying to clean everything off&amp;nbsp;afterwards. &amp;nbsp;They also wouldn't focus&amp;nbsp;solely&amp;nbsp;on the what was initially the worst injury until it was completely healed, ignoring all others.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What sins keep us furthest from God? &amp;nbsp;Sometimes it can be quite surprising. For me an issue is "cease to sleep longer than is needful; retire to thy bed early, that ye may not be weary; arise early, that your bodies and your minds may be invigorated." (D&amp;amp;C 88:124). &amp;nbsp;If I repeatedly stay up I am too tired to wake up on time in the morning. &amp;nbsp;In my rush to leave for work I then neglect caring for my body through exercise, have less&amp;nbsp;alert and&amp;nbsp;sincere prayers, and I cut my scripture study short.&lt;br /&gt;&lt;br /&gt;I'll leave it to President Lee for his words on forgiving self and the atonement:&lt;br /&gt;&lt;blockquote&gt;Some years ago President Romney and I were sitting in my office. The door opened and a fine young man came in with a troubled look on his face, and he said, "Brethren, I am going to the temple for the first time tomorrow. I have made some mistakes in the past, and I have gone to my bishop and my stake president, and I have made a clean disclosure of it all; and after a period of repentance and assurance that I have not returned again to those mistakes, they have now adjudged me ready to go to the temple. But, brethren, that is not enough. I want to know, and how can I know, that the Lord has forgiven me also."&amp;nbsp;&lt;/blockquote&gt;&lt;blockquote&gt;What would you answer one who would come to you asking that question? As we pondered for a moment, we remembered King Benjamin's address contained in the book of Mosiah. Here was a group of people who now were asking for baptism, and they said they viewed themselves in their carnal state:&amp;nbsp;&lt;/blockquote&gt;&lt;blockquote&gt;"And they all cried aloud with one voice, saying: O have mercy, and apply the atoning blood of Christ that we may receive forgiveness of our sins, and our hearts may be purified. ...&amp;nbsp;&lt;/blockquote&gt;&lt;blockquote&gt;"After they had spoken these words the Spirit of the Lord came upon them, and they were filled with joy, having received a remission of their sins, and having peace of conscience" (Mosiah 4:2-3).&amp;nbsp;&lt;/blockquote&gt;&lt;blockquote&gt;There was the answer.&amp;nbsp;&lt;/blockquote&gt;&lt;blockquote&gt;If the time comes when you have done all that you can to repent of your sins, whoever you are, wherever you are, and have made amends and restitution to the best of your ability; if it be something that will affect your standing in the Church and you have gone to the proper authorities, then you will want that confirming answer as to whether or not the Lord has accepted of you. In your soul-searching, if you seek for and you find that peace of conscience, by that token you may know that the Lord has accepted of your repentance. Satan would have you think otherwise and sometimes persuade you that now having made one mistake, you might go on and on with no turning back. That is one of the great falsehoods. The miracle of forgiveness is available to all of those who turn from their evil doings and return no more, because the Lord has said in a revelation to us in our day: "Go your ways and sin no more; but unto that soul who sinneth [meaning again] shall the former sins return, saith the Lord your God" (D&amp;amp;C 82:7). Have that in mind, all of you who may be troubled with a burden of sin.&amp;nbsp;&lt;/blockquote&gt;&lt;div style="text-align: right;"&gt;Harold B&amp;nbsp;Lee&lt;/div&gt;&lt;div style="text-align: right;"&gt;Ensign, Oct 2008, 44-49, Stand Ye in Holy Places&lt;/div&gt;&lt;br /&gt;If the barrier to forgiving ourself is worry over how people perceive us that sounds like some pride there. &amp;nbsp;Does the forgiveness of sins come from men or from God? &amp;nbsp;If we don't forgive ourselves due to how other's people perceive us, whose forgiveness are we considering more important? &amp;nbsp;Now don't get me wrong, repentance does involve repairing wrongs. &amp;nbsp;We should love and strengthen our fellow men. &amp;nbsp;What I am talking about is when these things are done and we are not letting go of the fact that we sinned because of this.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Forgiving Others&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;23 Therefore, if ye shall come unto me, or shall desire to come unto me, and rememberest that thy brother hath aught against thee—&lt;/blockquote&gt;&lt;blockquote&gt;24 Go thy way unto thy brother, and first be reconciled to thy brother, and then come unto me with full purpose of heart, and I will receive you.&lt;/blockquote&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-align: right;"&gt;3 Nephi 12:23-24&lt;/div&gt;&lt;br /&gt;This last time I read these verses I thought about how it really would apply both to the person needing forgiveness and for person forgiving.&amp;nbsp;&amp;nbsp;As I said in the beginning, how are we loving our neighbor if we haven't forgiven him?&amp;nbsp;&amp;nbsp;Then if you wish to come unto the Lord and remember that you have not forgiven your brother but hold harsh feelings towards him rather than love, can you really come unto the Lord with full purpose of heart and be received by him?&lt;br /&gt;&lt;br /&gt;Sometimes it feels like we talk of one person repenting and another forgiving as if these are strictly ordered and coupled affairs. &amp;nbsp;I'd say that these are not coupled events but are orthogonal to each other to the point where one might forgive another when that person has no sin to repent of.&lt;br /&gt;&lt;br /&gt;First, I'll look at the ordering when both are needed. &amp;nbsp;President Kimball taught that we must be willing to make the first move. “we must forgive, and we must do so without regard to whether or not our antagonist repents, or how sincere is his transformation, or whether or not he asks our forgiveness” (Miracle of Forgiveness). &amp;nbsp;Our forgiving of another is an expression of love that can help elevate that person even to repentance.&lt;br /&gt;&lt;br /&gt;This idea of love elevating another is expressed by Dr Victor Frankl in the following powerful but dry language&lt;br /&gt;&lt;blockquote&gt;By the spiritual act of love he is enabled to see the essential traits and features in the beloved person; and even more, he sees that which is potential in him, that which is not yet actualized but yet ought to be actualized. Furthermore, by his love, the loving person enables the beloved person to actualize these potentialities. By making him aware of what he can be and of what he should become, he makes these potentialities come true.&lt;/blockquote&gt;&lt;div style="text-align: right;"&gt;Viktor Frankl, Man's Search for Meaning&lt;/div&gt;&lt;br /&gt;This same concept was expressed by&amp;nbsp;Goethe when he said "Treat a man is he is and he will remain as he is. &amp;nbsp;Treat a man as he can and should be and he will become as he can and should be". &amp;nbsp;The musical Man of La Mancha (which I sadly can't recommend) also expresses this idea. &amp;nbsp;Don Quixote saw the beautiful virtuous Dulcinea when the reality was a women named Aldonza but this has a transforming affect on her. &amp;nbsp;As Don Quixote is dying, Aldonza comes and pleads for him to see her as he did before. &amp;nbsp;"Won't you please bring back \&amp;nbsp;The dream of Dulcinea... \&amp;nbsp;Won't you bring me back \&amp;nbsp;The bright and shining glory \&amp;nbsp;Of Dulcinea... Dulcinea...".&lt;br /&gt;&lt;br /&gt;Now on to my second point about needing to forgive a person when there might not be need of&amp;nbsp;repentance. &amp;nbsp;Is sometimes the offense we are forgiving really in our self, that we judged them harshly and took offense where none was meant?&lt;br /&gt;&lt;br /&gt;A great example of this is the&amp;nbsp;correspondences&amp;nbsp;between Moroni and Pahoran. &amp;nbsp;Moroni's armies had not been receiving the needed supplies to defend and retake lost territory. &amp;nbsp;His first letter to Pahoran receives no response. &amp;nbsp;After losing even more&amp;nbsp;territory and lives, he writes again and accuses Pahoran of joining in with others in their effort to overthrow their republic with a monarchy. &amp;nbsp;Pahoran responds humbly that such a overthrow did happen but that he was a&amp;nbsp;victim&amp;nbsp;of it and was gathering strength to retake the kingdom if it be right to turn against their own people. &amp;nbsp;When sending the letter Moroni probably expected himself to be needing to forgive Pahoran to only find out there was no offense in Pahoran.&lt;br /&gt;&lt;br /&gt;Regarding this concept, President Spencer W Kimball quotes the following in Miracle of Forgiveness:&lt;br /&gt;&lt;blockquote&gt;"There is but one quality necessary for the perfect understanding of character, one quality that, if man have it, he may judge-that is, omniscience. Most people study character as a proofreader pores over a great poem: his ears are dulled to the majesty and music of the lines, his eyes are darkened to the magic imagination of the genius of the author; that proofreader is busy watching for an inverted comma, a misspacing, or a wrong font letter. He has an eye trained for the imperfections, the weaknesses. …&lt;/blockquote&gt;&lt;blockquote&gt;"We do not need to judge nearly so much as we think we do. This is the age of snap judgments. … [We need] the courage to say, 'I don't know. I am waiting further evidence. I must hear both sides of the question.' It is this suspended judgment that is the supreme form of charity"&lt;/blockquote&gt;&lt;div style="text-align: right;"&gt;William George Jordan&lt;/div&gt;&lt;br /&gt;Orson Scott Card in the Ender series has a societal role called "Speaker for the Dead" who seeks to understand a person's life and correct the misunderstanding of us proof readers. &amp;nbsp;The idea that we see through a glass darkly lit is and can come to understand and love others is a powerful running concept in that series.&lt;br /&gt;&lt;br /&gt;Forgiving someone does not mean that they not face the consequences of their actions. &amp;nbsp;Going through the consequences, paying the price for their actions, is a portion of what need to go through as part of repentance. &lt;br /&gt;President Kimball speaks of a son talking to his father’s murderer “Tom, you made a mistake for which you owe a debt to society for which I feel you must continue to pay, just the same as I must continue to pay the price for having been reared without a father”.&lt;br /&gt;&lt;br /&gt;Just as King Mosiah guarded his kingdom against his sons falling back to sin (See &lt;a href="http://lds.org/scriptures/bofm/mosiah/29?lang=eng"&gt;Moshiah 29:6-7&lt;/a&gt;), we need not put ourselves back in a position to be hurt. &amp;nbsp;It is a tough balance to meet, forgiving someone and recognizing they can repent and be a different person while not putting oneself in the path of their destruction while they are still in error or at risk to return to their errors.&lt;br /&gt;&lt;br /&gt;Whether we properly administer mercy these two above cases comes down to whether we are loving the person as Christ does. &amp;nbsp;In addition to the son forgiving his murderer, another great example of these principles is the Nephites protecting&amp;nbsp;themselves, both passively and actively, against the Lamanites without seeking for revenge. &amp;nbsp;When the Nephites act out of revenge is when their nation is on decline and on the verge of destruction. &lt;br /&gt;&lt;blockquote&gt;Recompense to no man evil for evil … Dearly beloved, avenge not yourselves, but rather give place unto wrath: for it is written, Vengeance is mine; I will repay, saith the Lord.&lt;/blockquote&gt;&lt;div style="text-align: right;"&gt;Romans 12:17, 19&lt;/div&gt;&lt;br /&gt;The most important element I have left for last, the healing power of Christ's Atonement. &amp;nbsp;Christ's Atonement does not just offer us a healing balm for our sins but for our heart. &amp;nbsp;Elder Featherstone has provided one of my favorite descriptions of this and I will leave it to him.&lt;br /&gt;&lt;blockquote&gt;Lately I have decided that I need to talk more about justice. We don't understand justice completely, and there is so much out in the world that seems unjust and unfair that it is probably a good time to discuss this.&lt;/blockquote&gt;&lt;blockquote&gt;Who suffers most, the guilty or the innocent? The adulterer can go see the bishop. If he or she has truly repented, the bishop can say, on behalf of the Church, "You are forgiven." And they leave the office and that burden is lifted. What about the innocent? Who suffers most, the adulterer or the mother and father with a wayward son or daughter?&lt;/blockquote&gt;&lt;blockquote&gt;When will that hurt and suffering go away? It won't--not until the straying son or daughter comes back home. Should the innocent suffer? The parents quite often are innocent; and they hurt and they ache and they pray, and the pain will not go away.&lt;/blockquote&gt;&lt;blockquote&gt;Who suffers most, the incest perpetrator or the incest victim? Little ones are sometimes violated at a very tender age.&lt;/blockquote&gt;&lt;blockquote&gt;Who suffers most--the fornicator? the thief? those involved in drugs, homosexuality, and other perversions--or the innocent? Or do sometimes the innocent suffer more--the paraplegic, the quadriplegic, those with debilitating diseases, the "innocent" man or woman who has been involved in divorce, and dozens of others?&lt;/blockquote&gt;&lt;blockquote&gt;I believe sometimes the innocent suffer far, far more than the guilty--and that would not be justice, would it? It wouldn't be fair.&lt;/blockquote&gt;&lt;blockquote&gt;Now then, if the sinful one can go in and sit down with the bishop and have the burden relieved, then why should not the innocent? There are those who watch a spouse slowly die with cancer--a husband eventually becomes a widower or, if a man dies, a wife will be left alone. There are those who have other kinds of debilitating diseases--for instance, the quadriplegic who goes through a difficult life that way--isn't it only just that somehow the Atonement cover that kind of suffering? The innocent must be able to find the same relief as the guilty; that would only be just.&lt;/blockquote&gt;&lt;blockquote&gt;In Alma 7 we discover that the Lord suffered not only for the transgressions and sins of the world but for our afflictions and our illnesses and the sicknesses of the world. That is the part of the Atonement that I have missed somehow, and I want to suggest to you it is not left undone. Justice according to the supreme goodness of God will be satisfied. When we have a heart like unto God's own heart, we know justice will take place. Now, the innocent ones must do the same thing that the guilty do; that is, they must go to him who has a right to lift that off of their hearts.&lt;/blockquote&gt;&lt;blockquote&gt;President Harold B. Lee said, "I came to a night, some years ago, when on my bed, I realized that before I could be worthy of the high place to which I had been called, I must love and forgive every soul that walked the earth" (CR, October 1946, p. 146). If you have been violated, if you have been abused as a child or as an adult, or if you are later on in this life, would you remember that we must forgive the offending one? Justice "according to the supreme goodness of God" means that we do turn it over to him. It will not be left undone. We can have that absolute assurance. That would only be just. We must take it off of our hearts. Some modern psychiatrists might say, "Well, you don't get healed that way," but you do. You do get healed by turning justice over to God and forgiving the offender. We must be merciful if we would obtain mercy. The Lord can lift all burdens from us. Once we turn it over to him and simply say, "It is between that person and God. I forgive," then the burden will be lifted quietly and easily. If you are sitting here today and have had those problems in the past and can in your heart forgive and simply turn justice over to the Savior, then through his Atonement those sicknesses and illnesses and the abuses will be lifted from you. That would only be just.&lt;/blockquote&gt;&lt;blockquote&gt;The innocent must forgive the perpetrator, then transfer the burden to the Savior; and that is justice. That, again, does not mean that it is left undone; it just means that we have turned it over to the Savior.&lt;/blockquote&gt;&lt;div style="text-align: right;"&gt;Vaughn J Featherstone,&amp;nbsp;&lt;a href="http://speeches.byu.edu/reader/reader.php?id=2993&amp;amp;x=30&amp;amp;y=3"&gt;“A Man After God’s Own Heart”&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-9201663020087196736?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/9201663020087196736/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2011/05/forgiving-self-and-others.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/9201663020087196736'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/9201663020087196736'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2011/05/forgiving-self-and-others.html' title='Forgiving Self and Others'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-5572601082820956039</id><published>2011-02-11T19:51:00.000-06:00</published><updated>2011-02-11T19:51:33.818-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>And what do I do now?</title><content type='html'>&lt;blockquote&gt;I felt a great disturbance in the Force, as if millions of voices  suddenly cried out in terror and were suddenly silenced. I fear  something terrible has happened.&amp;nbsp;&lt;/blockquote&gt;That quote was the first thing that went through my mind when I heard the announcement about the MS/Nokia partnership.&amp;nbsp; As a community member I feel betrayed but I feel even worse for the employees.&amp;nbsp; Nokia has been building up a strategy that attracts a very passionate group.&amp;nbsp; The main supplier of your mobile platform switching strategies away from your needs is a drop in the bucket to your employer switching strategies to the exact opposite of where your passion lies.&amp;nbsp; Whether you quit, get layed off, switch to developing a product you dislike, or even move to a project in the forgotten shed that gets no attention are all options that are not fun.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="font-size: small;"&gt;So drop in the bucket time.&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I first switched to Nokia Linux-based products from Palm because I needed pocketable internet access.&amp;nbsp; I was moving to a lot of internet services so my Palm wasn't doing a good job fulfilling my needs.&amp;nbsp; I was annoyed with the Linux support which was purely a community effort.&amp;nbsp; Momentum is important so that I will have the apps I need and the lifetime to make the switch worth while.&amp;nbsp; I bought the 770 more as an experiment and found it fulfilled my needs.&lt;br /&gt;&lt;br /&gt;I started developing applications for it to fit different needs and have come to appreciate it as a development platform.&amp;nbsp; I can develop and use my applications on the desktop and have them also work on Maemo.&amp;nbsp; That makes development easier and means I can make greater use of my work.&amp;nbsp; I've also come to appreciate a flexible architecture with things like Telepathy allowing VOIP/IM service to be first-class, sharing system, libsocialweb (Meego), and hopefully in the future libfolks for contact aggregation.&lt;br /&gt;&lt;br /&gt;Writing mobile applications has grown beyond fulfilling my needs as a user.&amp;nbsp; I enjoy the opportunity to provide benefit for people as well as the chance to experiment and play with things that I don't get to in my job.&amp;nbsp; Releasing my applications for free changes the feeling of user support, fixes, and new features from have-to to get-to and keeps things very liberating and fun.&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Where do I go from here?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Meego&lt;/i&gt;: Intel is sticking with Meego.&amp;nbsp; I am curious to see what all devices are announced next week.&amp;nbsp; If they look like they have life to them then maybe I'll stick around.&amp;nbsp; Nokia is still keeping Meego development around as a project and is releasing a device this year.&amp;nbsp; I wonder if this is to fulfill some item in a contract with Intel.&amp;nbsp; If so and when the contract ends, this is dead.&amp;nbsp; If not, I wonder how long it will survive.&amp;nbsp; I am sure the financial analysts will be telling them to kill it to shift even greater investment to money pot they will expect WP7 to be.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Android&lt;/i&gt;: Android would probably offer me the apps I need.&amp;nbsp; Linux being under the hood is meaningless when you don't have the full Linux experience.&amp;nbsp; I feel no motivation to develop for it, either in Java, C++ and the Python supported seems grotesque at first brush.&amp;nbsp; I dislike the siloed approach that apps focus on.&amp;nbsp; You don't get the power of frameworks like Telepathy, libsocialweb, or libfolks where the backend is decoupled from the front end, allowing for choosing the front-end and back-ends that best fulfill your needs rather than sacrificing one over the other.&amp;nbsp; I dislike the idea of a manufacturer holding back updates and feel too lazy to always be following the latest custom ROMs (or some of the feats you need to go through to load one on some devices).&amp;nbsp;&amp;nbsp; I've played with friends Android devices and follow high level developments in the Android community but I could be mistaken on some things either good or bad.&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;webOS, something else?&lt;/i&gt; WP7 and iOS are out of the question.&amp;nbsp; webOS seems a bit limited in both apps and development platform but does offer "synergy" which sounds like it provides a similar experience of a plugin architecture that Maemo has.&amp;nbsp; I feel a bit concerned over the momentum of the platform especially in terms of how well it'll stick around.&amp;nbsp; Being from a single vendor adds to that risk and limits device options (which was why I was glad Nokia partnered with Intel to create Meego).&amp;nbsp; I only have cursory knowledge of webOS and have never played with a device whether this biases me in its favor or against it is to be seen.&lt;br /&gt;&lt;br /&gt;I think I'll wait for next week to see what Meego devices come out of MWC before making my decision.&lt;br /&gt;&lt;br /&gt;In the mean time I'd be curious if people have recommendations:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Pocketable (3-5 inches) devices with modern specs &lt;i&gt;(Required)&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Google Voice / VOIP Support regardless of network connection &lt;i&gt;(Required) &lt;/i&gt;&lt;/li&gt;&lt;li&gt;Good support for desktop Linux &lt;i&gt;(Required) &lt;/i&gt;&lt;/li&gt;&lt;li&gt;Support for Google services (GMail, Reader, Calendar, etc) &lt;i&gt;(Option because I'm used to using the mobile website)&lt;/i&gt; &lt;/li&gt;&lt;li&gt;Access to a Linux command line with VIM and SSH &lt;i&gt;(Optional but encouraged)&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Support for Python or some other higher level language (maybe I'd even be willing to venture into Javascript which always felt dirty to me). &lt;i&gt;(Optional but encouraged)&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Apps run on both desktop and handheld without modification or emulation &lt;i&gt;(Optional but encouraged)&lt;/i&gt;&lt;/li&gt;&lt;li&gt;Official way to distribute free apps without charge &lt;i&gt;(Optional but encouraged)&lt;/i&gt; &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;I'd also be curious what users of my applications will do.&amp;nbsp; There have been some stalwarts on Maemo 4.1 (n800, n810).&amp;nbsp; Will you all be sticking around or giving up on it?&amp;nbsp; Will there be a similar stalwart community on Maemo 5 (n900)?&amp;nbsp; If I move from Maemo to Meego and everyone jumps ship from Maemo 4.1 and Maemo 5 then there is no reason for me to put in the extra effort to maintain compatibility with Maemo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-5572601082820956039?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/5572601082820956039/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2011/02/and-what-do-i-do-now.html#comment-form' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/5572601082820956039'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/5572601082820956039'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2011/02/and-what-do-i-do-now.html' title='And what do I do now?'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-8099580366280974195</id><published>2011-01-07T21:39:00.000-06:00</published><updated>2011-01-07T21:39:19.530-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>Porting Dialcentral: The Last "10%"</title><content type='html'>I had thought I was "almost done" with the rewrite of DialCentral from GTK to Qt.&amp;nbsp; I've even &lt;a href="http://wiki.meego.com/Using_the_OBS_with_distutil_packages"&gt;started investigating my Meego ports&lt;/a&gt; and &lt;a href="http://talk.maemo.org/showthread.php?t=67508"&gt;started helping package / develop a new project&lt;/a&gt;.&amp;nbsp; Oh the joy of rewriting software and reimplementing old bugs and the creation of all new ones.&lt;br /&gt;&lt;br /&gt;Maemo 4.1 was leading in being the least polished.&amp;nbsp; Somehow I kept missing the &lt;i&gt;setIconSize&lt;/i&gt; method on &lt;i&gt;QTabWidget&lt;/i&gt; to override the default tab size on that platform which was incredibly small.&lt;br /&gt;&lt;br /&gt;I also had to fix some modality issues.&amp;nbsp; I had not set the parent window of my dialogs because rather than a new window appearing, the dialog's contents would be drawn on the parent window on top of everything else.&amp;nbsp; It took me a bit to discover the variant of &lt;i&gt;setParent&lt;/i&gt; that I also needed to set the &lt;i&gt;Qt::WindowsFlags &lt;/i&gt;which you can conveniently do both with a &lt;i&gt;setParent&lt;/i&gt; overload.&amp;nbsp; The other side of this modality issue was with close buttons on Ubuntu on tap-out-of-window on Maemo 5, I forgot close buttons on some dialogs.&lt;br /&gt;&lt;br /&gt;The last major user complaint is for those who haven't yet installed a Qt application on Maemo 4.1.&amp;nbsp; The Application Manager reports the size of a package as its own size plus all of its dependencies.&amp;nbsp; This makes sense for if a program has a separate data package or uses a rare but large library.&amp;nbsp; The downside is if you see 5 packages listed at 24 MB "each" then that is a bit discouraging for installing any of them.&amp;nbsp; Not much can be done about this one though.&lt;br /&gt;&lt;br /&gt;I think most of the other Maemo 4.1 issues have been resolved or are "good enough".&lt;br /&gt;&lt;br /&gt;Maemo 5 is now presenting the bigger challenge.&amp;nbsp; Take a look at the following screenshot.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_dnuI3IgE4aQ/TSfWBm7RydI/AAAAAAAADoc/x7IdQVDjDf0/s1600/Screenshot-20110107-211102.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="192" src="http://3.bp.blogspot.com/_dnuI3IgE4aQ/TSfWBm7RydI/AAAAAAAADoc/x7IdQVDjDf0/s320/Screenshot-20110107-211102.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;If you can't tell "Tell Me" is my number of choice for testing DialCentral.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Problems:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The box/line in the text box are an artifact of scrolling&lt;/li&gt;&lt;li&gt;The "Cancel Call" button is marked as not-visible but the "Send SMS" and "Call" buttons are marked as visible.&amp;nbsp; Sure doesn't look that way in the UI.&amp;nbsp; Well, until you press on part of "Cancel Call", then the "Call" button is drawn on top.&lt;/li&gt;&lt;/ul&gt;The best I can figure is that it is glitches in Qt dealing with the compositing.&amp;nbsp; While the window is hidden and in the time that it is sliding in I am changing up the UI in response to changes in the model.&amp;nbsp; If you cause something in the UI to change, like going back and adding another contact or entering some text, some or all of the glitches go away.&lt;br /&gt;&lt;br /&gt;I could just chalk this up as a Qt bug, file it, and move on.&amp;nbsp; Even if I can find a simpler reproduction case what is the chance that Maemo 5 users will see the fix?&amp;nbsp; Even if there is a chance that they do see it, how does that help them in the mean time?&amp;nbsp; I've been experimenting with update, activate, enableUpdate with and without delays aimed to arrive after the slide-in animation and have not gotten any results.&amp;nbsp; I might just have to queue up the UI changes for a timed delay after show to hope it is after the animation.&amp;nbsp; This will take a bit of rewriting this dialog for a problem that is only on one platform.&amp;nbsp; I'm not looking forward to this.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-8099580366280974195?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/8099580366280974195/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2011/01/porting-dialcentral-last-10.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/8099580366280974195'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/8099580366280974195'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2011/01/porting-dialcentral-last-10.html' title='Porting Dialcentral: The Last &quot;10%&quot;'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_dnuI3IgE4aQ/TSfWBm7RydI/AAAAAAAADoc/x7IdQVDjDf0/s72-c/Screenshot-20110107-211102.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-8061035655203069199</id><published>2011-01-07T20:27:00.000-06:00</published><updated>2011-01-07T20:27:21.605-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Primitive Debugging</title><content type='html'>At the end of a release at work our product has to be tested mixed in with other products.&amp;nbsp; In development we tend to be focused on our individual product and we try to keep things simple for reproducibility sake.&amp;nbsp; Our customers focus on a problem and need multiple products to be used in complex ways.&amp;nbsp; This helps give us some comfort that things won't break terribly in the customer's environment.&lt;br /&gt;&lt;br /&gt;These are no the most fun issues to be had.&amp;nbsp; It is difficult if at all possible to reproduce these issues outside of the test lab.&amp;nbsp; The test lab also exists on an isolated network.&amp;nbsp; These combine to reproduce some interesting challenges when debugging.&lt;br /&gt;&lt;br /&gt;By dumb luck I ended up being the one to usually go down to look at these problems.&amp;nbsp; This time around a different developer got wrangled in.&amp;nbsp; This is an experienced person who previously only dealt in app software.&amp;nbsp; His favorite tools like remote desktop and Visual Studio debugging (remote or even local) are thrown out the window.&lt;br /&gt;&amp;nbsp; &lt;br /&gt;Normally I end up using WinDBG but some quick looking leads us to believe it is an issue with the startup of a service we have.&amp;nbsp; Debuggers aren't much use in these situations because you can't start the service from inside it and you can't always attach in time.&amp;nbsp; So even though my coworker dreads WinDBG, he can't even use this tool.&amp;nbsp; That leaves us with print messages from a debug build of our service.&amp;nbsp; I am the one to generally maintain the service in question and I've  been sure to put in debug messages in all the most useful spots.&amp;nbsp; I also showed my fellow developer a few tricks with debugging through DebugView.&lt;br /&gt;&lt;br /&gt;This just gave me pause to reflect on how useful it is to use (in my case exclusively) these "primitive" tools.&amp;nbsp; In regular day-to-day debugging I can use the right tool (user space debugger, kernel space debugger, prints).&amp;nbsp; In addition I have the experience to deal with these more extreme debugging situations.&amp;nbsp; This is another great benefit for tools like VIM which you can use in a GUI, local command prompt, and through SSH.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-8061035655203069199?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/8061035655203069199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2011/01/primitive-debugging.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/8061035655203069199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/8061035655203069199'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2011/01/primitive-debugging.html' title='Primitive Debugging'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-5639511616294509529</id><published>2010-12-11T17:47:00.001-06:00</published><updated>2010-12-11T17:47:43.250-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>Porting DialCentral: Meaningless Results</title><content type='html'>I'm not sure why I like to wrap up each port with these meaningless results but here we go.&lt;br /&gt;&lt;br /&gt;Qt Version&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Near feature parity with GTK version (no custom callbacks, not re-implemented Alarm UI, no rotation for now)&lt;/li&gt;&lt;li&gt; Access to call cancel&lt;/li&gt;&lt;li&gt; Divider on various lists (for time ones, tried to balance heavy/light phone users)&lt;/li&gt;&lt;li&gt; Condensed history&lt;/li&gt;&lt;li&gt; Changed SMS Entry letter count style from GV to Nokia&lt;/li&gt;&lt;li&gt; Tabs are cached between launches&lt;/li&gt;&lt;li&gt; Display when history/messages tabs where last refreshed&lt;/li&gt;&lt;li&gt;4,866 LOCs&lt;/li&gt;&lt;li&gt;From August 18th to December 2nd &lt;/li&gt;&lt;/ul&gt;GTK Version&lt;br /&gt;&lt;ul&gt;&lt;li&gt;7,207 LOCs&lt;/li&gt;&lt;li&gt;For forever :)&lt;/li&gt;&lt;/ul&gt;That is quite an impressive difference in size.&amp;nbsp;&amp;nbsp; I think a lot of that is owed to a cleaned up design that only needs to worry about Google Voice and not Grand Central.&lt;br /&gt;&lt;br /&gt;I've still got some things to clean up, a couple bugs to fix, and improving some UI glitches on Maemo 4.1.&amp;nbsp; After that my plan is to get all of my applications into the Community OBS so they are available for Meego.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-5639511616294509529?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/5639511616294509529/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/12/porting-dialcentral-meaningless-results.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/5639511616294509529'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/5639511616294509529'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/12/porting-dialcentral-meaningless-results.html' title='Porting DialCentral: Meaningless Results'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-8187001863811170857</id><published>2010-12-10T17:57:00.000-06:00</published><updated>2010-12-10T17:57:48.590-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>Threading in Dialcentral</title><content type='html'>So this is a bit more boring of a post.&amp;nbsp; Pretty much everything went as expected.&amp;nbsp; The only annoyance&amp;nbsp; as part of my zeal to &lt;a href="http://eopage.blogspot.com/2010/06/porting-gonert-qts-design.html"&gt;avoid concrete inheritance&lt;/a&gt; was that Maemo 4.1 seems to have too old of a version of Qt to avoid inheriting from  &lt;a href="http://labs.qt.nokia.com/2010/06/17/youre-doing-it-wrong/"&gt;QThread&lt;/a&gt;.&amp;nbsp; That page has some better practice listings for QThread.&lt;br /&gt;&lt;br /&gt;DialCentral original used threading to be lazy about startup and to avoid the slowest of operations from blocking the UI thread.&amp;nbsp; I've now pushed all blocking operations to a thread. &amp;nbsp;The main question was what approach I would take to&amp;nbsp; &lt;a href="http://wiki.maemo.org/index.php?title=PyQt_Tips_and_Tricks"&gt;threading in PyQt&lt;/a&gt;.&amp;nbsp; I was tempted to keep using Python threads using&amp;nbsp;GObject callbacks but I keep to one toolkit for simplicity.&lt;br /&gt;&lt;br /&gt;In The One Ring I had some code that used generators to trampoline code to the worker thread. &amp;nbsp;I just had to refactor it so that there were toolkit specific and toolkit agnostic components.&lt;br /&gt;&lt;br /&gt;I was glad that python logging works smoothly with QThreads.&amp;nbsp; The messages get marked with some kind of distinguishing identifier.&lt;br /&gt;&lt;br /&gt;See, nice and boring. &amp;nbsp;No real issue which to me is a plus.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-8187001863811170857?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/8187001863811170857/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/12/threading-in-dialcentral.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/8187001863811170857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/8187001863811170857'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/12/threading-in-dialcentral.html' title='Threading in Dialcentral'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-2333321929048095132</id><published>2010-12-09T20:05:00.000-06:00</published><updated>2010-12-09T20:05:39.300-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>Latest Lessons on Widgets from Dialcentral</title><content type='html'>This is a bit of a catch-all post to go back over some previously covered items with some new things learned.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;TreeViews&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_dnuI3IgE4aQ/TQA-aKYVjqI/AAAAAAAADnc/9gD81leh17A/s1600/DialCentral_Messages.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="120" src="http://2.bp.blogspot.com/_dnuI3IgE4aQ/TQA-aKYVjqI/AAAAAAAADnc/9gD81leh17A/s200/DialCentral_Messages.png" width="200" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;HTML Delegates&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;I previously couldn't find the way to do &lt;a href="http://eopage.blogspot.com/2010/06/porting-gonvert-actual-port.html"&gt;custom cell renderers&lt;/a&gt;.&amp;nbsp; In part the oddity is that they provide default ways to render that are meaningless when you provide Delegates.&amp;nbsp; I did some searching and found an example HTML Delegate.&amp;nbsp; It had some issues with dark themes so I had to fix several bugs in it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: right;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_dnuI3IgE4aQ/TQA-bdULn_I/AAAAAAAADng/bi3yh2YIYPU/s1600/DialCentral_Contacts.png" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="120" src="http://4.bp.blogspot.com/_dnuI3IgE4aQ/TQA-bdULn_I/AAAAAAAADng/bi3yh2YIYPU/s200/DialCentral_Contacts.png" width="200" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Simple heirarchy&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Next I wanted Dialcentral to have letter separators in the contact list.&amp;nbsp; I never messed with hierarchical views in GTK before so I can't really compare.&amp;nbsp; My first time branching out to applying this to Messages and History turned out bad because it seems to have the parent items' columns aligned with the child's columns.&amp;nbsp; The original History view had 3 columns with the left two scrunched together.&amp;nbsp; These didn't provide much space for the parent row's text.&amp;nbsp; When I switched to a condensed history view this became moot.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_dnuI3IgE4aQ/TQA-3uMODqI/AAAAAAAADnk/XKq5IXDUjwM/s1600/DialCentral_History.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="192" src="http://2.bp.blogspot.com/_dnuI3IgE4aQ/TQA-3uMODqI/AAAAAAAADnk/XKq5IXDUjwM/s320/DialCentral_History.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Condensed history view, allowing the parent text to fit.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;When learning about hierarchical views I found out that the root expander decorator is given space by default even if there are no children and it isn't shown.&amp;nbsp; This saved some space in the UI and will clean up the look of my other applications.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Layouts&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The only real comment I have for layouts regards QGridLayout which I've not used before this.&amp;nbsp; Early on I was looking at using &lt;a href="http://eopage.blogspot.com/2010/07/porting-ejpi-custom-widgets-in-qt.html"&gt;my pie menus&lt;/a&gt; for the buttons which had some issues, so I setup the alignment.&amp;nbsp; This didn't help but when I switched to buttons I eventually found out that it caused the buttons to fit to their minimum size rather than expand.&amp;nbsp; I probably fixed the pie menu issue without realizing I had thwarted myself.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Combo Box&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The only real trouble I ran into with QComboBox was when I wanted it editable.&amp;nbsp; I was going to use this to allow choosing an existing GV configured callback or a custom one.&amp;nbsp; On the desktop the only way I've gotten it to insert into the list the item I'm creating is when there is nothing else to capture the enter key press.&amp;nbsp; Otherwise what gets activated is the "Apply" button (or worst "Clear Account" button when I remove the "Apply" button).&amp;nbsp; I've not found my way around this issue yet.&lt;br /&gt;&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_dnuI3IgE4aQ/TQA_S7Xz48I/AAAAAAAADno/TUTzwFo6Mmg/s1600/DialCentral_Account.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="192" src="http://3.bp.blogspot.com/_dnuI3IgE4aQ/TQA_S7Xz48I/AAAAAAAADno/TUTzwFo6Mmg/s320/DialCentral_Account.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Callback Combobox caused problems on desktop Qt&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-2333321929048095132?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/2333321929048095132/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/12/latest-lessons-on-widgets-from.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/2333321929048095132'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/2333321929048095132'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/12/latest-lessons-on-widgets-from.html' title='Latest Lessons on Widgets from Dialcentral'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_dnuI3IgE4aQ/TQA-aKYVjqI/AAAAAAAADnc/9gD81leh17A/s72-c/DialCentral_Messages.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-1754693110525542646</id><published>2010-12-08T20:22:00.000-06:00</published><updated>2010-12-08T20:22:39.518-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>Porting Dialcentral to Qt</title><content type='html'>&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; text-align: left;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_dnuI3IgE4aQ/TQA7E1ECd7I/AAAAAAAADnQ/qL0D873cFYs/s1600/GCDialer.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="120" src="http://1.bp.blogspot.com/_dnuI3IgE4aQ/TQA7E1ECd7I/AAAAAAAADnQ/qL0D873cFYs/s200/GCDialer.jpg" width="200" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;GrandCentral Dialer&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Dialcentral started its life as Grand Central Dialer for the 770.&amp;nbsp; I got involved by adding support for desktop Linux (which also made possible porting to future versions of Maemo).&amp;nbsp; Soon after the name change to Dialcentral (out of trademark paranoia) I took over maintaining it.&amp;nbsp; Google Voice support was added while maintaining Grand Central support as long as possible.&amp;nbsp; Over time other features were added like texting and group texts.&amp;nbsp; Eventually I provided an alternate way of interacting with Google Voice through a telepathy connection manager called &lt;a href="http://theonering.garage.maemo.org/"&gt;The One Ring&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: right;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_dnuI3IgE4aQ/TQA7P-eIVTI/AAAAAAAADnY/mbY8J5VxgPc/s1600/Dialcentral+-+Dialpad+-+1.0.7-12+Fremantle.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="120" src="http://2.bp.blogspot.com/_dnuI3IgE4aQ/TQA7P-eIVTI/AAAAAAAADnY/mbY8J5VxgPc/s200/Dialcentral+-+Dialpad+-+1.0.7-12+Fremantle.png" width="200" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;DialCentral 1.0.7&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;This port to Qt has taken longer for many reasons.&amp;nbsp; The backend has slowly become more compartmentalized over time but the complexity grew faster.&amp;nbsp; I ended up needing to rewrite everything but the direct wrapper around Google Voice.&amp;nbsp; Besides some other misc parts of life during this time I was also contacted by a recruiter from a very good company, an opportunity I felt I shouldn't pass up.&amp;nbsp; My interests have have focused on system programming, programming practices, and software architecture and so I've ended up ignoring algorithms a bit too much.&amp;nbsp; Their process spread over 2 months which I spent refreshing and expanding my knowledge of algorithms rather than working on Dialcentral.&amp;nbsp; After a couple trips out seeing the company and the office's city I came to the conclusion that Austin and the company I work for are the place for me to remain for now.&amp;nbsp; Location was the biggest clincher to me and that was after I researched all of their branch locations and interviewed for one of two I found that I had a chance of liking.&lt;br /&gt;&lt;br /&gt;&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; text-align: right;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_dnuI3IgE4aQ/TQA7JZ74AtI/AAAAAAAADnU/RQy6Et4A87U/s1600/DialCentral_Dialpad.png" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="120" src="http://2.bp.blogspot.com/_dnuI3IgE4aQ/TQA7JZ74AtI/AAAAAAAADnU/RQy6Et4A87U/s200/DialCentral_Dialpad.png" width="200" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;DialCentral 1.2 Beta&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;I'm still putting some finishing touches on this port.&amp;nbsp; I'm cautiously testing the waters with releasing this to extras out of concern that Google might break the brittle unofficial API and i have to do an immediate release.&amp;nbsp; I released a &lt;a href="http://talk.maemo.org/showpost.php?p=882647&amp;amp;postcount=1339"&gt;snapshot&lt;/a&gt; and have moved on to putting it in extras-devel with &lt;a href="http://talk.maemo.org/showpost.php?p=887277&amp;amp;postcount=1342"&gt;dire warnings&lt;/a&gt; especially since if an issue arises I might start having the GTK/Qt versions leapfrogging each other (joy of not having PPAs or a stable API).&lt;br /&gt;&lt;br /&gt;For me the interesting part is this was my first Qt app that involves threading.&amp;nbsp; Related to this is that I want to maintain as much common code with &lt;a href="http://theonering.garage.maemo.org/"&gt;The One Ring&lt;/a&gt; as possible.&amp;nbsp; Also with more UI work comes more insight into the better ways of doing things.&amp;nbsp; I try to keep all of my UIs fairly simple but this is one of the more involved ones.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-1754693110525542646?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/1754693110525542646/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/12/porting-dialcentral-to-qt.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/1754693110525542646'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/1754693110525542646'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/12/porting-dialcentral-to-qt.html' title='Porting Dialcentral to Qt'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TQA7E1ECd7I/AAAAAAAADnQ/qL0D873cFYs/s72-c/GCDialer.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-7338120771763399882</id><published>2010-11-21T07:51:00.000-06:00</published><updated>2010-11-21T07:51:54.705-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>Dublin and Meego Conference</title><content type='html'>Thanks to the generosity of the Linux Foundation I flew out and attended Meego Conference this year as well as payed for a couple extra days to see Dublin. &amp;nbsp;This is my first time out of the United States (I did pop across the border into western Canada for 10 minutes but I don't think that counts). &amp;nbsp;I've been a Maemo user since the 770 but I never before attended any of the Maemo Summits. &amp;nbsp;This was a great experience.&lt;br /&gt;&lt;br /&gt;&lt;div style="margin: 0px;"&gt;I arrived on Saturday the 13th and left on Friday the 19th. &amp;nbsp;I ended up site seeing rather than participating in any of the early bird events.&lt;/div&gt;&lt;br /&gt;On Day 1 I attended Rob Bradford's location/social aware presentation. &amp;nbsp;I had not known about libsocialweb before which I thought was interesting. &amp;nbsp;More interesting is I got some ideas of things to do with geoclue. &amp;nbsp;I also went to a presentation about the Touch Input Method Framework. &amp;nbsp;The thing that saddens me about these frameworks being created is that they are in-process and limit you to developing in C++ unless someone goes through the effort for each one to write a proxy plugin. &amp;nbsp;I try to exclusively deal with Python because it let's me focus more of my time on developing rather than worrying about cross-compiling, debugging, etc. &amp;nbsp;I can understand that there can be performance issues for some frameworks passing a lot of data over dbus, that was the reason I was given for libfolk. &amp;nbsp;At the evenings receptions, timeless and I had some interesting conversation. &amp;nbsp;I just hope I remember all the UI feedback he gave.&lt;br /&gt;&lt;br /&gt;On Day 2 I attended the two telepathy related sessions (the project, not the super power though that would have made an interesting and confusing unconference day session). &amp;nbsp;I am looking forward to telepathy 1.0 despite the extra work it is going to put on me for updating The One Ring (and any future CMs I write). &amp;nbsp;It will be disappointing if I end up having to drop a couple of platforms (currently I support Maemo 4.1, Maemo 5, and desktop Ubuntu with work being done to prep for Meego).&lt;br /&gt;&lt;br /&gt;Some worries of fcrochik and I were eased a bit when Mikhail brought up the QtContact plugin backed by libfolk (a bit before a blogpost hit the various planets). &amp;nbsp;It still seems odd that QtContacts is built with support for plugins yet you would either need some kind of layer on top to aggregate the plugins (needing retrofits for apps using the old API) or else only have one plugin and it aggregates things that plugin to it (plugin for plugins, joy).&lt;br /&gt;&lt;br /&gt;The third day was unconference which is more of a good-chaotic everyone-present-what-they-want kind of day. &amp;nbsp;Sadly due to a conflict I missed Christian's Wayland presentation.&lt;br /&gt;&lt;br /&gt;During one of the slots is when I picked up my Lenovo Ideapad that they were giving away.&amp;nbsp; A bit weird that it comes with a UK power chord and keyboard (I suspect I'm not the only American that set it to US layout to our confusion).&amp;nbsp; Sadly there is still some work that needs being done which is not giving people the best perception of the netbook/tablet and of Meego.&amp;nbsp; Hopefully it'll all be worked out in the &lt;a href="http://forum.meego.com/showthread.php?t=1995"&gt;thread on f.m.c&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I ended the unconference with leading a session about experiences porting from Maemo to Meego but due to conflicts and being the end of the last day I only had fcrochik in attendance. &amp;nbsp;We still had the good time.&lt;br /&gt;&lt;br /&gt;Being from the US and having seen pretty much no professional football games, I enjoyed the Ireland v Norway game. &amp;nbsp;I heard from others later that both teams weren't playing all that well. &amp;nbsp;We had free tickets, the pre-game premium lounge with drinks and pretty good snacks. &amp;nbsp;We had a good number of rounds of the food because they came in such small bowls. &amp;nbsp;Thankfully texrat was nearby to take all of our dishes. &amp;nbsp;I didn't take part much in the half-time or pot-game festivities since the lines were long.&lt;br /&gt;&lt;br /&gt;I have to say the venue was great, having the hacker's lounge was great, and it all felt top notch. &amp;nbsp;Amy, Dawn, Quim, and everyone else involved did a great job and there are many thanks to go around. One lesson learned I think was to have more power (and maybe even power converters at the "Power Plant" for people like me who forgot one).&amp;nbsp; If my laptop I brought actually had power, it would have been fun to have a day like what I heard happened in Barcelona.&lt;br /&gt;&lt;br /&gt;I enjoyed being out in Dublin on the other days. &amp;nbsp;I managed to do everything by foot besides going from and to the airport (so 10+ km of walking on non-conference days).&lt;br /&gt;&lt;br /&gt;On Saturday I spent my time at the city centre. &amp;nbsp;I saw Marions Square, St Stephen's Green, Dublin Castle, Christ Church Cathedral, and walked Grafton Street.&amp;nbsp; I enjoyed exploring the city but none of those sites really moved me. &amp;nbsp;I had some good lamb stew at some place near Dublin Castle. &amp;nbsp;Coming from Austin and freezing out in Dublin, that stew hit the spot. &amp;nbsp;That evening I also went and saw Tosca performed at the&amp;nbsp;Gaiety&amp;nbsp;Theatre. &amp;nbsp;That was a very powerful production.&lt;br /&gt;&lt;br /&gt;On the Thursday after the Conference I ended up going to some of the further out spots.&amp;nbsp; I saw the National Gallery and then walked out to O'Connell Street to see the Spire, the James Joye Statue, the Remembrance Garden (very beautiful both in design and in idea), and the James Joyce Centre. &amp;nbsp;I then went out west and saw the&amp;nbsp;Leprechaun&amp;nbsp;Museum on my way.&amp;nbsp; Eventually I was at Kilmainham Gaol and the Ireland Museum of Modern Art. &amp;nbsp;I then had to rush back real quick to get on the internet to see when I flew back.&lt;br /&gt;&lt;br /&gt;Those last three sites ended up being my favorite.&amp;nbsp; It was fascinating to learn the political history of Ireland from the perspective of a jail, including the execution of the leaders of the Easter Rising.&amp;nbsp; The Garden of Remembrance was a great place to contemplate.&amp;nbsp; The Leprechaun Museum was fascinating for learning Irish Mythology.&lt;br /&gt;&lt;br /&gt;The things I sadly didn't get to see are the Ireland Botanical Gardens, Mallahide Castle, Knowth/Newgrange, the War Memorial Gardens, and a Famine Memorial I saw on my tour map (if it exists, couldn't find it).&amp;nbsp; I wasn't even sure how I would get to Knowth/Newgrange but at the Leprechaun Museum they aid that the Dublin Tourism place on O'Connell does a tour up in those parts, you jut need to arrange it a head of time it sounded like. &amp;nbsp;Something to know for the next trip out to Dublin.&lt;br /&gt;&lt;br /&gt;I find it interesting that a friend had recommended I see a lot of the Churches but instead I saw or at least tried to see war memorials, jails, execution sites, ancient burial tombs, etc.&amp;nbsp; A bit different of priorities I guess. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://picasaweb.google.com/eopage/MeegoConference?feat=directlink"&gt;See Pictures&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-7338120771763399882?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/7338120771763399882/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/11/dublin-and-meego-conference.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/7338120771763399882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/7338120771763399882'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/11/dublin-and-meego-conference.html' title='Dublin and Meego Conference'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-8645144767819005862</id><published>2010-09-01T22:07:00.000-05:00</published><updated>2010-09-01T22:07:45.682-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>DAQpy</title><content type='html'>Once upon a time I needed to write an application that interfaced with the real world.&amp;nbsp; I decided I wanted to use a data acquisition device from NI but I'm picky.&amp;nbsp; I want easy prototyping with fine control in the finished product.&amp;nbsp; That kicks out LabVIEW (luckily I'm forgetful or else I could write post after post about the good and bad of LabVIEW).&lt;br /&gt;&lt;br /&gt;So I decided to use the C with DAQmx.&amp;nbsp; For prototyping I decided to use Python with its ctypes library.&amp;nbsp; I found some &lt;a href="http://www.google.com/url?sa=t&amp;amp;source=web&amp;amp;cd=1&amp;amp;ved=0CBIQFjAA&amp;amp;url=http%3A%2F%2Fwww.scipy.org%2FCookbook%2FData_Acquisition_with_NIDAQmx&amp;amp;rct=j&amp;amp;q=daqmx%20python&amp;amp;ei=lxJ_TJHCM4SclgfR5f31Dw&amp;amp;usg=AFQjCNGbTNSRg0Yr-lpV4RwhiBmFy7W3Cg&amp;amp;sig2=IvxouJMwkstX0BCP8tfYSA&amp;amp;cad=rja"&gt;example bindings&lt;/a&gt; on a scipy page but they were hand generated and didn't seem very pythonic.&amp;nbsp; So I wrote my own generator and then added some custom helpers on top to make common operations more pythonic.&amp;nbsp; Unlike &lt;a href="http://code.google.com/p/pydaqmx/"&gt;pydaqmx&lt;/a&gt; (which I just now found out about) I include my code-gen tool and I don't try to create a fake OOP system on top of the DAQmx API.&lt;br /&gt;&lt;br /&gt;I even took some of the basic examples included with DAQmx and created the &lt;a href="http://github.com/epage/DAQpy/blob/master/examples/daqmxtest.py"&gt;Python equivelants&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;You can find a copy of DAQpy on &lt;a href="http://github.com/epage/DAQpy"&gt;github&lt;/a&gt;.&amp;nbsp; I would caution I re-organized the code on my Linux box which means I don't have access to DAQmx to validate things.&amp;nbsp; Patches welcome :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-8645144767819005862?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/8645144767819005862/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/09/daqpy.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/8645144767819005862'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/8645144767819005862'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/09/daqpy.html' title='DAQpy'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-2977311065965011403</id><published>2010-08-16T07:49:00.000-05:00</published><updated>2010-08-16T07:49:27.612-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>Porting ejpi: Meaningless Results</title><content type='html'>So let's see how the two versions of ejpi compare:&lt;br /&gt;&lt;br /&gt;Qt  Version&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Feature parity with the GTK version &lt;/li&gt;&lt;li&gt;Improved pie menu performance but two pie menu display bugs&lt;/li&gt;&lt;li&gt;Simplified layout with the potential for rotation&lt;br /&gt;&lt;/li&gt;&lt;li&gt; 3382 LOCs&lt;/li&gt;&lt;li&gt;From June 8th to July 16th&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;GTK Version&lt;br /&gt;&lt;ul&gt;&lt;li&gt;4473 LOCs&lt;/li&gt;&lt;li&gt;From January 30th to February 25th&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;LOCs are measured by "wc -l" rather than getting fancy.&amp;nbsp; I wrote  both  apps and they were written in a similar style with similar  amounts of  whitespace and documentation.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The LOC counts look nice, &lt;a href="http://eopage.blogspot.com/2010/06/porting-gonvert-meaningless-results.html"&gt;more drastic than my Gonvert port&lt;/a&gt; for what it is worth.&amp;nbsp; I had a lot more distractions going on during my port of ejpi so a comparison of implementation times between Gtk/Qt or Gonvert/ejpi is as meaningless as the title of this post suggests.&lt;br /&gt;&lt;br /&gt;My main Qt disappointment in this port is what seems like high coupling both in Qt itself and in code written by others (the example pie menus).&lt;br /&gt;&lt;br /&gt;Now for some of the upsides.&amp;nbsp; Though I implemented them differently, the similarity in the drawing code between Qt and Cairo helped.&amp;nbsp; Also finding out about QStandardItemModel made my life easier.&lt;br /&gt;&lt;br /&gt;I'm split on which direction I want to go in my learning of Qt.&amp;nbsp; Originally I had planned on porting Dialcentral for gaining experience with threading.&amp;nbsp; I have too many ideas though and not enough time.&amp;nbsp; Possible directions include: porting other apps of mine, a new app using QGraphicsView, or some QtMobility contacts (and eventually calendar) plugins (though then I'd also have to learn the quirks of Qt in C++ and deploying compiled apps to Maemo).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-2977311065965011403?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/2977311065965011403/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/08/porting-ejpi-meaningless-results.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/2977311065965011403'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/2977311065965011403'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/08/porting-ejpi-meaningless-results.html' title='Porting ejpi: Meaningless Results'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-602250376031318619</id><published>2010-08-16T07:43:00.000-05:00</published><updated>2010-08-16T07:43:07.857-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Learning Ruby: Vampire Numbers</title><content type='html'>Instead of the traditional book group at work I'm in a group where each person chooses to learn a new language.&amp;nbsp; For me to make it feel worth while it either needs easy C bindings, existing bindings, or be used for scripting at work.&amp;nbsp; That left me with Go, Lua, Io, and Ruby.&amp;nbsp; Go was out due to error handling and generics.&amp;nbsp; I decided to stick with Ruby so it would be work practical (Python is heavily used by the company-wide build tools but my group has a lot of Perl and Ruby scripts).&lt;br /&gt;&lt;br /&gt;Our first assignment was simple, identify &lt;a href="http://en.wikipedia.org/wiki/Vampire_number"&gt;vampire numbers&lt;/a&gt;.&amp;nbsp; They seem arbitrary and useless but oh well.&lt;br /&gt;&lt;br /&gt;One of the first things I did was "gem install rubydoctest".&amp;nbsp; I like doctests from Python for their providing examples for the code and that they provide very low friction low coverage tests.&lt;br /&gt;&lt;br /&gt;My work computer is sadly running Windows.&amp;nbsp; I did not have tool chains setup to install ruby-prof from source and I couldn't figure out how to install the pre-built version referenced from their site.&lt;br /&gt;&lt;br /&gt;A quick summary of my initial thoughts&lt;br /&gt;&lt;ul&gt;&lt;li&gt;rubydoctest has poor error output but I love that "!!!" drops you into irb (though I didn't find out about it until I was done). &lt;/li&gt;&lt;li&gt;I was kind of surprised Ruby doesn't have a factorial function.&amp;nbsp; I'm not as surprised about a lack of a permutation function, Python's just special like that.&lt;/li&gt;&lt;li&gt;Very few examples show how to separate module logic from executable logic (Python's "if __name__ == "__main__" idiom)&lt;/li&gt;&lt;li&gt;Optional return's are ugly for most code.&amp;nbsp; The one place they work well is used inside of a block as a predicate for a function (like the comparator for sorting).&lt;/li&gt;&lt;li&gt;Optional parenthesis make it confusing what is a property or method.&amp;nbsp; Not knowing what is going on feels sloppy to me&lt;/li&gt;&lt;li&gt;I got thrown off by changing fairly standard names (exception handling, next/continue) and at first didn't think "next" existed.&lt;/li&gt;&lt;li&gt;Find it a strange concept to use next, break, retry, redo inside of blocks.&amp;nbsp; I'd be curious what the underlying principles are for how the block communicates with its caller to execute those.&lt;/li&gt;&lt;li&gt;Retry and redo seem cool though I am unsure how often I would ever use  them&lt;/li&gt;&lt;li&gt;I like Python's separation of repr from str which makes debug output easy.&amp;nbsp; I was wanting to figure out what some lists I was using were doing but each element was printed on a separate line, making it take up a lot of space and making it hard to distinguish one array from another.&amp;nbsp; I didn't notice some of the pretty print functions till later and haven't had a chance to try them yet.&lt;/li&gt;&lt;li&gt;My program was slow and according to profiling most of it was in iterating.&amp;nbsp; (0...5).each was the fastest, next was 0.upto(5), and then last was doing the looping raw (I think).&amp;nbsp; All of that kind of surprised me, most especially how slow looping was in Ruby.&amp;nbsp; I was impressed the closures for blocks didn't add much overhead (or at least it isn't noticeable compared to how slow ruby is in general).&lt;/li&gt;&lt;li&gt;I kept mixing up whether I was working with an actual iterator and  an Enumerable (and it took me a while to notice the difference)&lt;/li&gt;&lt;li&gt;I really miss the composable iterators of Python (enumerate plus everything in itertools)&lt;/li&gt;&lt;li&gt;Remembering&amp;nbsp; ".." vs "..." is annoying and I end up having to look it up every time (which is very bad for code readability).&lt;/li&gt;&lt;li&gt;A problem that drove me nuts for a while is "x = false or true".&amp;nbsp; The "=" has higher precedence than "or".&amp;nbsp; What I needed is "x = false || true".&amp;nbsp; A blogpost I later came across tries to frame "or" and "and" as flow control operators rather than logical operations. I think there are way too many operators.&amp;nbsp; Can you name the difference between ".."/"...", "=="/"==="/"eq?"/"equal?", etc?&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-602250376031318619?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/602250376031318619/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/08/learning-ruby-vampire-numbers.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/602250376031318619'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/602250376031318619'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/08/learning-ruby-vampire-numbers.html' title='Learning Ruby: Vampire Numbers'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-2420988257487598478</id><published>2010-07-29T21:19:00.000-05:00</published><updated>2010-07-29T21:19:00.893-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>Porting ejpi: Tree Models in Qt</title><content type='html'>For me, one thing that differentiates the quality of a calculator on a mouse or touch driven device is having a calculation history and having it be interactive.&amp;nbsp; In Gtk I implemented this with a TreeView and a ListStore.&amp;nbsp; I had never implemented a custom model in Gtk, the included models were simple enough and flexible enough that I didn't have the need.&lt;br /&gt;&lt;br /&gt;When I ported &lt;a href="http://eopage.blogspot.com/2010/06/porting-gonvert-actual-port.html"&gt;Gonvert to Qt&lt;/a&gt;, all I could find information for was custom models with &lt;a href="http://doc.trolltech.com/4.6/qabstractitemmodel.html"&gt;QAbstractItemModel&lt;/a&gt; and &lt;a href="http://doc.trolltech.com/4.6/qtreewidget.html"&gt;QTreeWidget&lt;/a&gt;/&lt;a href="http://doc.trolltech.com/4.6/qtreewidgetitem.html"&gt;QTreeWidgetItem&lt;/a&gt;.&amp;nbsp; QTreeWidgetItem's seem to only be good for Text.&amp;nbsp; This worked for parts of Gonvert but not for others so I went through the complicated affair of implementing a QAbstractItemModel.&amp;nbsp; I never felt like I fully understood the relationships of various items which usually worries me.&amp;nbsp; I also found it slow due to all of the protection I "should" have in my code which causes a lot of calling back and forth between C++ and Python.&lt;br /&gt;&lt;br /&gt;I'm unsure how I missed it but when I started on ejpi I came across &lt;a href="http://doc.trolltech.com/4.6/qstandarditemmodel.html"&gt;QStandardItemModel&lt;/a&gt;/&lt;a href="http://doc.trolltech.com/4.6/qstandarditem.html"&gt;QStandardItem&lt;/a&gt;.&amp;nbsp; This seems to at least allow a little more flexibility.&amp;nbsp; I can put icons and checkboxes in as well as text into the model.&amp;nbsp; I can also attach random python objects to each item.&amp;nbsp; The downside to a stock model is that you have to externally maintain any invariants but I was already managing those with my Gtk version.&lt;br /&gt;&lt;br /&gt;I would be curious about the various performance merits to each approach but I'll have to pass on that for now.&amp;nbsp; The two main things I found frustrating was finding out about these and how each API was helpful in its own way, sometimes better, sometimes worse than its fellow approaches.&lt;br /&gt;&lt;br /&gt;Most of my API issues were due to being unfamiliar with them and having to fight with the different approaches each model system took to presenting itself to the developer.&amp;nbsp; I still have one unfortunate &lt;a href="https://garage.maemo.org/plugins/ggit/browse.php/?p=ejpi;a=blob;f=src/qhistory.py;h=a853173b7aadfde2e2576d2455a56fc5375a6084;hb=HEAD"&gt;piece of code in ejpi's calucation history &lt;/a&gt;which implements peek through a pop and a push.&lt;br /&gt;&lt;br /&gt;I've not messed with setting the font on any of these (I should have for Gonvert and also for ejpi) so I'm unsure how the font experience is in Qt.&amp;nbsp; Mainly I'm interested in what formatting Pango html-esque tags allowed, changing relative size and basic formatting while keeping everything else to theme defaults.&amp;nbsp; A quick look through the API seems to suggest this is simple but that is yet to be determined.&lt;br /&gt;I still miss GTK's generic way of handling rendering with its use of  CellRenderers.&amp;nbsp; You don't have to be stuck with the built-in choices for  representing items in your model.&amp;nbsp; It also keeps presentation  information away from the model.&lt;br /&gt;&lt;br /&gt;I did enjoy how easy QStandardItem's made user edits (sadly only seems to work on the desktop) and activating of individual items.&amp;nbsp; I didn't get around to exploring drag and drop for history re-arrangement (helpful for RPN calculators) but I don't think I implemented that for the GTK version either.&lt;br /&gt;&lt;br /&gt;My &lt;a href="https://garage.maemo.org/plugins/ggit/browse.php/?p=ejpi;a=blob;f=src/gtkhistory.py;h=000e609f0cee57357a8ae4420dc1ab259e321b63;hb=3584b257e9663f40ad7bdc5d821aa5f684f9c0d7"&gt;GTK version&lt;/a&gt; and my &lt;a href="https://garage.maemo.org/plugins/ggit/browse.php/?p=ejpi;a=blob;f=src/qhistory.py;h=a853173b7aadfde2e2576d2455a56fc5375a6084;hb=HEAD"&gt;Qt version&lt;/a&gt; of my ejpi history are available for comparison.&lt;br /&gt;&lt;br /&gt;I guess the summary would be that overall I'm a fan of QStandardItemModel and wish I had found it sooner.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-2420988257487598478?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/2420988257487598478/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/07/porting-ejpi-tree-models-in-qt.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/2420988257487598478'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/2420988257487598478'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/07/porting-ejpi-tree-models-in-qt.html' title='Porting ejpi: Tree Models in Qt'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-4053239680653064170</id><published>2010-07-29T20:42:00.001-05:00</published><updated>2010-07-29T20:42:58.637-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>Porting ejpi: Icon Theming</title><content type='html'>ejpi includes some custom icons as well as using theme icons.&lt;br /&gt;&lt;br /&gt;The custom icons are used for a couple of buttons.&amp;nbsp; I know the path to the custom icons and I load them up and everything works as expected.&lt;br /&gt;&lt;br /&gt;The stock icons are used for deleting items in the calculator's history as well as a severity indicator and close button for the error info box. &lt;br /&gt;&lt;br /&gt;I ported the GTK code from using theme icon names to &lt;a href="http://doc.trolltech.com/4.6/qicon.html#fromTheme"&gt;QIcon.fromTheme&lt;/a&gt;.&amp;nbsp; It was fun for me to find out that fromTheme was added in Qt 4.6 (I still support Maemo 4.1 with my applications and it only has Qt 4.2 I think).&amp;nbsp; How did applications do this before 4.6?&amp;nbsp; I don't think I've used KDE since v2 but I think its generally supported icon theming along with everything else which precludes the application building all icons in as resources.&lt;br /&gt;&lt;br /&gt;I also had fun with fd.o icon names not being available on all platforms so I had to find alternatives for each and put in fallback code.&lt;br /&gt;&lt;br /&gt;I guess chock this up as another thing to &lt;a href="https://garage.maemo.org/plugins/ggit/browse.php/?p=ejpi;a=blob;f=src/maeqt.py;h=d5eb18bda1908c62e9e6d13f1e13063a2f3058cb;hb=540404d02cff9dd92a4da1cfdd3e56525a6e64e8"&gt;abstract  away when running on various platforms&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I'm not saying this was hard or anything but just another lessons learned in porting to Qt.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-4053239680653064170?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/4053239680653064170/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/07/porting-ejpi-icon-theming.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/4053239680653064170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/4053239680653064170'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/07/porting-ejpi-icon-theming.html' title='Porting ejpi: Icon Theming'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-496002015922745630</id><published>2010-07-17T22:09:00.000-05:00</published><updated>2010-07-17T22:09:01.854-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='spiritual'/><category scheme='http://www.blogger.com/atom/ns#' term='politics'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>"Antenna-gate", Fanboys, and Trolls</title><content type='html'>I just saw a &lt;a href="http://googletesting.blogspot.com/2010/07/there-but-for-grace-of-testing-go-i.html"&gt;good post&lt;/a&gt; on this from the Google Testing Bog.&lt;br /&gt;&lt;br /&gt;Despite my dislike of Apple and their treatment of developers (and my disgust that developers are flocking to receive their flogging) I think we should be careful how we react to this.&amp;nbsp; Problems happen.&amp;nbsp; There is both good and bad to how Apple handled this. If we feel a bit annoyed in how they handled this we should have that same annoyance no matter the source rather than giving in to fanboy-ism&lt;br /&gt;&lt;br /&gt;Do we look at this and think how much better our platform is but get annoyed when others point out the problems with our platform of choice?&lt;br /&gt;&lt;br /&gt;This is a general problem whether it be long standing technology flamewars (VI is better btw), to religion, or to politics.&amp;nbsp; Sometimes the very nature of having &lt;a href="http://en.wikipedia.org/wiki/Prisoner_experiment"&gt;two groups forms an automatic antagonism&lt;/a&gt; (see also &lt;a href="http://en.wikisource.org/wiki/Washington%27s_Farewell_Address#1"&gt;George Washington's Farewell address&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;I find &lt;a href="http://en.wikipedia.org/wiki/Krister_Stendahl"&gt;Krister Stendahl&lt;/a&gt;'s rules for religious understanding to be very applicable to all of these areas of our life:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;When you are trying to understand another religion, you should  ask the adherents of that religion and not its enemies.&lt;/li&gt;&lt;li&gt;Don't compare your best to their worst.&lt;/li&gt;&lt;li&gt;Leave room for "holy envy."&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-496002015922745630?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/496002015922745630/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/07/antenna-gate-fanboys-and-trolls.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/496002015922745630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/496002015922745630'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/07/antenna-gate-fanboys-and-trolls.html' title='&quot;Antenna-gate&quot;, Fanboys, and Trolls'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-6222380071892070998</id><published>2010-07-17T21:38:00.000-05:00</published><updated>2010-07-17T21:38:34.878-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>Concurrently Beating a Dead Horse</title><content type='html'>Sometimes it seems like the horse is already dead but today I came across a &lt;a href="http://learnyousomeerlang.com/the-hitchhikers-guide-to-concurrency?"&gt;fun article describing Erlang's concurrency model&lt;/a&gt;.&amp;nbsp; This is no surprise because Actors (along with STM) seems to be a favorite on the various &lt;a href="http://news.ycombinator.com/"&gt;programming&lt;/a&gt; &lt;a href="http://www.reddit.com/r/programming/"&gt;sites&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;So why continue the beatings?&amp;nbsp; I thought I'd solidify my thoughts by writing them out.&amp;nbsp; I also find exploring these principles beneficial for my projects to improve design even if the high level implementations wouldn't fit within the architecture for some of them. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In any concurrency discussion I think its good to remind ourselves of the pillars of concurrency to help avoid silver-bullet-syndrome.&amp;nbsp; I highly recommend Herb Sutter's Effective Concurrency series,  especially the &lt;a href="http://www.drdobbs.com/high-performance-computing/200001985"&gt;introductory  article&lt;/a&gt; where he talks about Callahan's Pillars.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://i.cmpnet.com/ddj/images/article/2010/1003/pillar_ec_hs_table1.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="323" src="http://i.cmpnet.com/ddj/images/article/2010/1003/pillar_ec_hs_table1.gif" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;(sorry for the text image, that is how the content was stored in the original article) &lt;br /&gt;&lt;br /&gt;&lt;b&gt;STM&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;First two items of background.&amp;nbsp; The first is that I'm one of those odd people who enjoys the area where hardware and software meet.&amp;nbsp; The second is that my current job is in software for test and automation systems.&amp;nbsp; Having to warn customers about the possibility of Death and Dismemberment is not pleasant.&lt;br /&gt;&lt;br /&gt;With those in mind I tend to worry more about how a system, pattern, architecture, whatever talks to the real world than how parallel it can get.&amp;nbsp; This leads me to dislike STM as my default model of concurrency to use because the world is not transactional.&amp;nbsp; If you have a program controlling &lt;a href="http://www.escapistmagazine.com/news/view/93072-Wii-Remote-Controls-Giant-Robot-Arm"&gt;a swinging arm of death&lt;/a&gt;, what does a revert mean?&amp;nbsp; One of Microsoft's researchers on STM.NET &lt;a href="http://www.bluebytesoftware.com/blog/2010/01/03/ABriefRetrospectiveOnTransactionalMemory.aspx"&gt;admits to this problem and many others&lt;/a&gt; (but again it does have its uses).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Dataflow&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I enjoyed my experiences with digital design in college but at the moment it is not the field for me.&amp;nbsp; Also VHDL and Verilog leave much to be desired.&lt;br /&gt;&lt;br /&gt;I find the idea of applying the natural concurrency of digital hardware to software fascinating.&lt;br /&gt;&lt;br /&gt;In the industry I work in there is a popular data flow programming language.&amp;nbsp; For high level integration or large datasets it seems great to have the implicit parallelism.&amp;nbsp; I wonder how much parallelism it really gets with small data sets in simple applications.&amp;nbsp; The language has a couple draw backs to me for the projects I work on outside of work:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Single vendor (never a fan of lock-in)&lt;/li&gt;&lt;li&gt;Except for the clunky implementation of Events, it does not handle other concurrency models which a task might be better for.&lt;/li&gt;&lt;li&gt;Not designed well for general purpose programming situations&lt;/li&gt;&lt;li&gt;Even though some applications seem fast to write the environment feels like it hinders me. &lt;/li&gt;&lt;/ul&gt;&lt;b&gt;Actors&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Now on to actors.&amp;nbsp; I've always been a fan of the simple concept of handling concurrency through shared-nothing message-passing like Erlang.&amp;nbsp; I can easily conceptualize how this would work with hardware.&amp;nbsp; I enjoy the fact that each process is normally short-lived enough that the GC doesn't even need to be called.&amp;nbsp; These combine to give it soft real-time which is a field I've always found fascinating.&lt;br /&gt;&lt;br /&gt;How does it handle various models of concurrency?&amp;nbsp; I like the idea of having access to an Actor's low level primitives in Erlang to more naturally implement something else like a finite-state-machine.&amp;nbsp; The low-level message passing is events so you get that.&amp;nbsp; I don't think I'm doing enough embarrassing parallel tasks to miss having dataflow.&amp;nbsp; I bet you could model a form of STM for groups of actors with the error system.&lt;br /&gt;&lt;br /&gt;Sadly I've never really done anything in Erlang because:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;At work when I do something in my language of choice I need to optimize for implementation time and not reduced run times which my investigation into Erlang seems to indicate it would be poor at.&amp;nbsp;&lt;/li&gt;&lt;li&gt;With my open source work it usually centers around another component for which I need to have a means of talking to.&amp;nbsp; Python has a lot of bindings.&amp;nbsp; I feel like with Erlang I'd have to roll my own.&lt;/li&gt;&lt;/ul&gt;Actors lose their appeal to me in other languages.&amp;nbsp; In Python the boilerplate and the overhead to achieve shared-nothing seems too much.&amp;nbsp; Maybe its just FUD but even in Scala it sounds unappealing.&amp;nbsp; This leads me to my last item &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Events&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Events aren't as high-level of a concurrency model as STM and Actors but they can sometimes have a lower barrier to entry, especially when integrating with certain frameworks.&amp;nbsp; Previously all of my open source applications have been glib based and most were GTK based.&amp;nbsp; I found glib events a pleasure to work with.&lt;br /&gt;&lt;br /&gt;Simple UI callbacks work well.&amp;nbsp; I could simplify more complex sequences of callbacks like with DBus by abstracting them away but I've tended to abstract the concept so I can do things like &lt;a href="https://garage.maemo.org/plugins/ggit/browse.php/?p=theonering;a=blob;f=src/util/tp_utils.py;h=30d7629cc737c0563dee3c4bd649be6b186b4446;hb=8a3c64d3bc33f8f00cd126e25e6e96643ac11c93"&gt;map/reduce DBus calls&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Registering idle and timeout events seem to be atomic which makes life great certain applications of parallelism.&amp;nbsp; What I've tended to do is keep a thread for a group of data (like my connection state for Google Voice).&amp;nbsp; I then push to a queue a task I want the thread to apply to the data (make a GV call, get contacts, etc) and I include a callback that is registered as an idle callback for when the data is ready.&amp;nbsp; I have no management of locks to worry about.&lt;br /&gt;&lt;br /&gt;I've even been able to abstract away the callbacks to keep good spatial locality on the logic in the code.&lt;br /&gt;&lt;br /&gt;An example from The One Ring, my Telepathy Connection Manager for Google Voice:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @misc_utils.log_exception(_moduleLogger)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def RequestStreams(self, contactId, streamTypes):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; """&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; For org.freedesktop.Telepathy.Channel.Type.StreamedMedia&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; @returns [(Stream ID, contact, stream type, stream state, stream direction, pending send flags)]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; """&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; contact = self._conn.get_handle_by_id(telepathy.constants.HANDLE_TYPE_CONTACT, contactId)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; assert self.__contactHandle == contact, "%r != %r" % (self.__contactHandle, contact)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; le = gobject_utils.AsyncLinearExecution(self._conn.session.pool, self._call)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; le.start(contact)&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; streamId = 0&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; streamState = telepathy.constants.MEDIA_STREAM_STATE_CONNECTED&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; streamDirection = telepathy.constants.MEDIA_STREAM_DIRECTION_BIDIRECTIONAL&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; pendingSendFlags = telepathy.constants.MEDIA_STREAM_PENDING_REMOTE_SEND&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return [(streamId, contact, streamTypes[0], streamState, streamDirection, pendingSendFlags)]&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @misc_utils.log_exception(_moduleLogger)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def &lt;b&gt;_call&lt;/b&gt;(self, contact):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; contactNumber = contact.phoneNumber&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self.__calledNumber = contactNumber&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self.CallStateChanged(self.__contactHandle, telepathy.constants.CHANNEL_CALL_STATE_RINGING)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; try:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; result = yield (&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self._conn.session.backend.call,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; (contactNumber, ),&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {},&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; except Exception:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; _moduleLogger.exception("While placing call to %s" % (self.__calledNumber, ))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self._delayedClose.start(seconds=0)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self.CallStateChanged(self.__contactHandle, telepathy.constants.CHANNEL_CALL_STATE_FORWARDED)&lt;br /&gt;&lt;br /&gt;In the DBus callback (as in, happens in the main-loop) &lt;i&gt;RequestStreams&lt;/i&gt; I create an AsyncLinearExecution object (eh, couldn't think of something better for a name) that runs the generator &lt;i&gt;_call&lt;/i&gt; as an idle callback (again, executes in the main-loop).&amp;nbsp; The yield passes a function, args, and kwds to the thread passed into AsyncLinearExecution's __init__ for it to run without blocking the main-loop.&amp;nbsp; When it finishes it takes the results and passes that out of the yield.&amp;nbsp; I can even move the exception from the thread to be thrown at the yield.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I maintain AsyncLinearExecution as an object so I can "cancel" it at anytime.&amp;nbsp; My style of cancellation is for the thread's results to be ignored.&amp;nbsp;&amp;nbsp; In the try/except this gets represented as a StopIteration exception.&amp;nbsp; This style of cancellation greatly simplifies my shutdown logic for a Telepathy Connection.&lt;br /&gt;&lt;br /&gt;I've not read too much about other event based systems for Python but if they don't  have a main-loop I scratch my head as to how they integrate with threading and other features.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;In conclusion:&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;STM: Doesn't seem appropriate for any of my applications&lt;/li&gt;&lt;li&gt;Dataflow: Digital hardware is fun but not a fan of the main implementation in software&lt;/li&gt;&lt;li&gt;Actors: Cool but lack of integration with libraries limits my use of languages designed around it&lt;/li&gt;&lt;li&gt;Raw Events: a lot of fun for my open source applications.&lt;/li&gt;&lt;/ul&gt;I thought I'd also note that we have a fairly young wiki page that &lt;a href="http://wiki.maemo.org/Performance_Considerations_for_Python_Apps#Responsiveness"&gt;touches on threading for Python&lt;/a&gt; and one more specifically for &lt;a href="http://wiki.maemo.org/index.php?title=PyQt_Tips_and_Tricks"&gt;PyQt applications&lt;/a&gt;.&amp;nbsp; I've done some work on them on hope to have more information to add to them later as I continue &lt;a href="http://eopage.blogspot.com/2010/06/from-maemo-to-meego.html"&gt;porting my applications to Qt&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-6222380071892070998?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/6222380071892070998/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/07/concurrently-beating-dead-horse.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/6222380071892070998'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/6222380071892070998'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/07/concurrently-beating-dead-horse.html' title='Concurrently Beating a Dead Horse'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-4233843813357533795</id><published>2010-07-15T22:27:00.001-05:00</published><updated>2010-07-15T22:27:40.247-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>Porting ejpi: Custom Widgets in Qt</title><content type='html'>Because of my off-repeated distaste for making custom widgets unless needed, the pie menus for ejpi are my first real custom widget.&amp;nbsp; Learning to write custom widgets is the reason I chose to port ejpi.&lt;br /&gt;&lt;br /&gt;I started off with the C++ pie menu code from &lt;a href="http://qt.nokia.com/products/appdev/add-on-products/catalog/4/Widgets/qtpiemenu/"&gt;Nokia's add-ons&lt;/a&gt;.&amp;nbsp; I ported it to Python (I doubt anyone would package the binary and making Python bindings available for Maemo any time soon).&amp;nbsp; While at it I simplified the code and made it more re-usable.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Qt Pie Menu Design Evolution&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;QtPieItem is the client-provided object to store everything related to a slice.&amp;nbsp; The two subclasses are QtPieAction and QtPieMenu.&lt;br /&gt;&lt;br /&gt;QtPieMenu works well as a subclass of QtPieItem for when you want submenus but doesn't make sense with the parent QtPieMenu.&amp;nbsp; What does the weight, icon, and text mean?&amp;nbsp; Why not use composition instead?&amp;nbsp; Besides I don't even need sub-menus in my application.&amp;nbsp; So I dropped this (could easily be added later).&lt;br /&gt;&lt;br /&gt;QtPieAction starts to look a lot like QAction.&amp;nbsp; I figured I could just use QActions for all of my slices with a wrapper to track the weight (slice weight / all slices weight gives the percentage of a circle a slice takes up).&lt;br /&gt;&lt;br /&gt;Moving on to QtPieMenu...&lt;br /&gt;&lt;br /&gt;The center of the menu and outside the menu cause a cancellation.&amp;nbsp; I like actions being connected to the center (one of these actions could be a cancel).&amp;nbsp; I also like to throw the mouse so I wanted an option for infinite outer radius.&lt;br /&gt;&lt;br /&gt;Overall I was seeing there were several pieces of code in here that could be reused and built up to make several variants of Pie Menus, depending on what was wanted.&amp;nbsp; So I broke out pie locations (QPieFiling, basically the Model), rendering (QPieArtist, kind of like a View), and then the actual widget (QPieDisplay, QPieButton, QPieMenu).&lt;br /&gt;&lt;br /&gt;This worked really well.&amp;nbsp; I do not use QPieMenu so oh well.&amp;nbsp; A QPieButton can have its representation set with a QActionPieItem.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_dnuI3IgE4aQ/TD_Mcqayi2I/AAAAAAAAC7M/Psz1vyXvSqQ/s1600/NonPopped.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_dnuI3IgE4aQ/TD_Mcqayi2I/AAAAAAAAC7M/Psz1vyXvSqQ/s320/NonPopped.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;When the QPieButton is clicked it shows a QPieDisplay that is filled  up with delicious goodness.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_dnuI3IgE4aQ/TD_Mm7SBBCI/AAAAAAAAC7U/Fa2Pb17zKNM/s1600/Popped.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_dnuI3IgE4aQ/TD_Mm7SBBCI/AAAAAAAAC7U/Fa2Pb17zKNM/s320/Popped.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;Life Implementing a Custom Widget&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This was actually a fairly pleasant experience.&lt;br /&gt;&lt;br /&gt;With the original GTK version of ejpi I struggled to grab the current theme's colors but never was able to.&amp;nbsp; I followed Qt Pie Menu's example in grabbing colors and it actually worked!&amp;nbsp; There was one bug in the original C++ code, they used a "dark" for unselected text when "mid" is what is called for but luckily Qt actually had &lt;a href="http://doc.trolltech.com/4.6/qpalette.html#details"&gt;great documentation&lt;/a&gt; on when to use what color.&lt;br /&gt;&lt;br /&gt;The other major challenge on the desktop I had was sizing.&amp;nbsp; The QtPieMenu only used sizeHint which gives a suggested default size for widgets.&amp;nbsp; For the buttons I wanted a minimum size of what is needed to draw the item with a suggested size of the client specified size.&amp;nbsp; I wanted to then listen to resizes and scale my box accordingly so the user would have button separators.&lt;br /&gt;&lt;br /&gt;For this I overrode minimumSizeHint and resizedEvent.&amp;nbsp; I have the suspicion that widgets are supposed to implement sizeHint, minimumSizeHint, and maximumSizeHint rather than setting the sizes directly to leave it in the wisdom of the client to possibly bypass the hints by setting the actual minimum, actual, and maximum sizes.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def minimumSizeHint(self):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;return self._buttonArtist.centerSize()&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @misc_utils.log_exception(_moduleLogger)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def resizeEvent(self, resizeEvent):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self.setButtonRadius(min(resizeEvent.size().width(), resizeEvent.size().height()) / 2 - 1)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; QtGui.QWidget.resizeEvent(self, resizeEvent)&lt;br /&gt;&lt;br /&gt;When checking how things ran on Maemo I ran into a couple of strange issues.&amp;nbsp; So they wouldn't become modal I registered the menus as SplashScreen.&amp;nbsp; I think the hacking around modality of popups was what killed performance on my GTK version.&lt;br /&gt;&lt;br /&gt;Unlike the GTK version I was getting the frost effect to the whole window minus the square around the pie. That provided quite an awkward look.&amp;nbsp; I didn't find anything for this so I just drop the round pies.&lt;br /&gt;&lt;br /&gt;The other problem which is yet to be resolved is that if an edge button is selected the pie appears off-center from the user's click.&amp;nbsp; The odd part to me is even the middle buttons have the pie go partially off-screen so it must be some kind of how much is it off the screen.&lt;br /&gt;&lt;br /&gt;You can find the source code for these pie menus in ejpi's &lt;a href="https://garage.maemo.org/plugins/ggit/browse.php/?p=ejpi;a=blob;f=src/libraries/qtpie.py;h=884d5cee725c0899819e2a70afec3609b8973cba;hb=25e75759f12c38abf6f93cc8c761d63f619c26c6"&gt;git repo&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-4233843813357533795?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/4233843813357533795/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/07/porting-ejpi-custom-widgets-in-qt.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/4233843813357533795'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/4233843813357533795'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/07/porting-ejpi-custom-widgets-in-qt.html' title='Porting ejpi: Custom Widgets in Qt'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_dnuI3IgE4aQ/TD_Mcqayi2I/AAAAAAAAC7M/Psz1vyXvSqQ/s72-c/NonPopped.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-600020586219503449</id><published>2010-07-12T22:17:00.000-05:00</published><updated>2010-07-12T22:17:43.962-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>Porting ejpi: Dynamic Layouts with (Py)Qt</title><content type='html'>&lt;b&gt;Previous and Future ejpi UI&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;The current ejpi layout does not seem very dynamic&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://static.maemo.org/static/7/7e1c9dec1daf11df939ba5e803ae7e027e02_screenshot-20100219-060815.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="192" src="http://static.maemo.org/static/7/7e1c9dec1daf11df939ba5e803ae7e027e02_screenshot-20100219-060815.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;In the history column an error info box may appear that you can click away (custom made, not the new one available in the latest versions of GTK).&amp;nbsp; The "Trigonometry" button brings up a Touch Selector for choosing which secondary keyboard you want visible.&lt;br /&gt;&lt;br /&gt;Some problems with this layout:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Buttons are oddly shaped&lt;/li&gt;&lt;li&gt;The keys would have to be customized for portrait and landscape&lt;/li&gt;&lt;li&gt;Showing two keyboards would take up too much space in portrait mode&lt;/li&gt;&lt;li&gt;Not enough space left to increase the button text size&lt;/li&gt;&lt;/ul&gt;Below I created a mockup of the adjusted layout in portrait mode&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_dnuI3IgE4aQ/TDud34E3zWI/AAAAAAAAC64/dyICtONnFJg/s1600/7e1c9dec1daf11df939ba5e803ae7e027e02_screenshot-20100219-060815.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_dnuI3IgE4aQ/TDud34E3zWI/AAAAAAAAC64/dyICtONnFJg/s320/7e1c9dec1daf11df939ba5e803ae7e027e02_screenshot-20100219-060815.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Showing only one keyboard at a time will allow the buttons to be a bit nicer and gives more space for the history.&amp;nbsp; Switching the secondary keyboard was two clicks away.&amp;nbsp; With only one keyboard switches might be more frequent so we'll switch to tabs with icon representations for single click access (despite what I remember of the Maemo guidelines discouraging tabs).&amp;nbsp; Moving the Push key out makes it available when any keyboard is selected and reduces the need to specialize the keyboard layouts based on orientation.&lt;br /&gt;&lt;br /&gt;We've not changed too much in terms of how dynamic the UI is.&amp;nbsp; The only change is on rotation we will need to switch the keyboards from being to the right of the history to being below the history.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Comparing GTK and Qt Layout systems&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;GTK's layout system centers around container widgets that provide holes for their children to populate.&amp;nbsp; Also the HBox are VBox are very static.&amp;nbsp; Their base class is either abstract or an interface so you have to actually swap out the class in the widget hierarchy to change between a horizontal and vertical layout.&lt;br /&gt;&lt;br /&gt;The impression I have of Qt so far is that it separates out the concept of layout from the widget container.&amp;nbsp; A way to think of it is the widget is the canvas to draw on while the layout constrains the sizes and locations of the things to be drawn.&amp;nbsp; I actually removed a layout at one point and the widgets stayed visible and in the same location as before.&amp;nbsp; You can have layout hierarchies but the API&amp;nbsp; support for layouts is drastically limited as compared to widgets.&amp;nbsp; Also the separate widget and layout hierarchies can complicate things.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Implementing My Dynamic Layouts&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;Of course when I got started I didn't understand the difference between the way they did layouts.&amp;nbsp; I tried to implement everything as if it was GTK.&amp;nbsp; I had complex layout hierarchies that I was trying to swap out at run time.&amp;nbsp; It seems simple to &lt;a href="http://doc.trolltech.com/4.3/layouts-dynamiclayouts.html"&gt;change up a flat layout hierarchy&lt;/a&gt; but when you are trying to work off of an abstraction the API disparity between widgets and layouts increases the complexity.&amp;nbsp; I tried multiple approaches to get it all to work to no avail.&lt;br /&gt;&lt;br /&gt;I might have come across one possible approach but I ran into the need to do some casting because the API returned QLayoutItem proxies rather than proxies for the derived class QHBoxLayout, etc.&amp;nbsp; With PyGTK I never had to worry about casting so &lt;i&gt;when hitting it with PyQt I gave up in disgust at how nasty that feels in Python&lt;/i&gt;.&amp;nbsp; Please note that I am a C++ developer by trade and &lt;i&gt;have no problems with it in C++&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;It was when I finally connected how layouts work in Qt that I made some progress.&amp;nbsp; I would create intermediary widgets that I'd assign my layouts to.&amp;nbsp; I could then add/remove/show/hide them all I wanted without issue.&amp;nbsp; I think this is the way it was meant to be done.&amp;nbsp; I think one of the reasons I hit a wall with this as compared to others is &lt;a href="http://eopage.blogspot.com/2010/06/porting-gonert-qts-design.html"&gt;&lt;i&gt;my abhorrence for inheriting from QWidget&lt;/i&gt;&lt;/a&gt;.&amp;nbsp; In Gonvert I even changed part of my user experience because I could not access certain event information unless I inherited from the Qt widget.&lt;br /&gt;&lt;br /&gt;Its kind of hard to do code samples without gutting my entire application and plopping it in here so I'll just provide one class and how it sets up its widget/layout hierarchy:&lt;br /&gt;&lt;br /&gt;class QErrorDisplay(object):&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def __init__(self):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self._messages = []&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; icon = QtGui.QIcon.fromTheme("gtk-dialog-error")&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self._severityIcon = icon.pixmap(32, 32)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self._severityLabel = QtGui.QLabel()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self._severityLabel.setPixmap(self._severityIcon)&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self._message = QtGui.QLabel()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self._message.setText("Boo")&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; icon = QtGui.QIcon.fromTheme("gtk-close")&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self._closeLabel = QtGui.QPushButton(icon, "")&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self._closeLabel.clicked.connect(self._on_close)&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self._controlLayout = QtGui.QHBoxLayout()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self._controlLayout.addWidget(self._severityLabel)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self._controlLayout.addWidget(self._message)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self._controlLayout.addWidget(self._closeLabel)&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self._topLevelLayout = QtGui.QHBoxLayout()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self._topLevelLayout.addLayout(self._controlLayout)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self._widget = QtGui.QWidget()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self._widget.setLayout(self._topLevelLayout)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self._hide_message()&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; @property&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; def toplevel(self):&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return self._widget&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br /&gt;&lt;br /&gt;Note the toplevel property.&amp;nbsp; Kind of nasty but its what I use to insert this into the rest of the class hierarchy&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self._controlLayout = QtGui.QVBoxLayout()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self._controlLayout.addWidget(self._errorDisplay.toplevel)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self._controlLayout.addWidget(self._historyView.toplevel)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self._controlLayout.addLayout(self._userEntryLayout)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Something else neat that I noticed is that in Qt, QHBoxLayout and QVBoxLayout are just used for convenience when working with QBoxLayout which dynamically supports switching from horizontal and vertical layouts.&amp;nbsp; This made me happy with Qt for once.&amp;nbsp; I can't imagine there being significance enough of a difference that they should be separate in GTK or if there is that a dynamically switchable layout couldn't be supported.&amp;nbsp; I can't speak too positively of Qt or people might worry.&amp;nbsp; I think its a disservice that Qt has QHBoxLayout and QVBoxLayout and recommends their usage.&amp;nbsp; Do you really need an extra class to not have to type in one extra parameter into the constructor?&amp;nbsp; &lt;i&gt;Really?&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; if maeqt.screen_orientation() == QtCore.Qt.Vertical:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; defaultLayoutOrientation = QtGui.QBoxLayout.TopToBottom&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; else:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; defaultLayoutOrientation = QtGui.QBoxLayout.LeftToRight&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; self._layout = QtGui.QBoxLayout(defaultLayoutOrientation)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; # Actual handling of rotation with setDirection not implemented yet&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Conclusion&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;QVBoxLayout and QHBoxLayout are your enemy, QBoxLayout is your friend.&lt;br /&gt;&lt;br /&gt;Attach layouts to QWidget's to make layout work easy.&amp;nbsp; It is sad that PyQt requires the use of casting.&lt;br /&gt;&lt;br /&gt;I think there is suppose to be some new UI stuff to make dynamic layouts with fancy transitions easy.&amp;nbsp; As I will talk about when I discuss QTreeView's it is a bit annoying trying to figure out what is the recommended approach for what situation so I just went with (1) what I found documentation for and (2) what seemed familiar.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-600020586219503449?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/600020586219503449/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/07/porting-ejpi-dynamic-layouts-with-pyqt.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/600020586219503449'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/600020586219503449'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/07/porting-ejpi-dynamic-layouts-with-pyqt.html' title='Porting ejpi: Dynamic Layouts with (Py)Qt'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_dnuI3IgE4aQ/TDud34E3zWI/AAAAAAAAC64/dyICtONnFJg/s72-c/7e1c9dec1daf11df939ba5e803ae7e027e02_screenshot-20100219-060815.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-5115932094351584026</id><published>2010-07-12T07:58:00.000-05:00</published><updated>2010-07-12T07:58:53.197-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>Porting ejpi from GTK t Qt</title><content type='html'>"&lt;a href="http://en.wikipedia.org/wiki/Eulers_identity"&gt;e**(j * pi) + 1 = 0&lt;/a&gt;" is the more complete name of this project.&amp;nbsp; Throwing the "j" in their might be confusing but blame that on my engineering background.&amp;nbsp; Why yes, I love that fact that Python follows the &lt;a href="http://en.wikipedia.org/wiki/Python_%28programming_language%29#Typing"&gt;EE notation over the Mathematical notation&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The idea for ejpi was born from reading a complaint on &lt;a href="http://planet.gnome.org/"&gt;planet.gnome.org&lt;/a&gt; about how computer calculators overly mimic handheld calculators much to their detriment.&amp;nbsp; On a computer there are a lot more ways to interact with a program than a device with a one-line display and a fixed set of hardware buttons.&lt;br /&gt;&lt;br /&gt;So ejpi is designed as an RPN calculator that has an interactive history.&amp;nbsp; You can delete item and duplicate items.&amp;nbsp; With a one-line calculator it is easy to forget where you are in a multistep calculation, so ejpi shows you not just the result but the equation that got you there.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://static.maemo.org/static/7/7e1c9dec1daf11df939ba5e803ae7e027e02_screenshot-20100219-060815.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="192" src="http://static.maemo.org/static/7/7e1c9dec1daf11df939ba5e803ae7e027e02_screenshot-20100219-060815.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;A 4" device (n8x0) is limited on what all you can put on the screen and shrinking it down to 3.5" (n900) makes it even harder.&amp;nbsp; Making matters worse is that even if the device has a qwerty keyboard (n800 doesn't) its not well suited for math.&amp;nbsp; So I chose to experiment with pie-menus as the keyboard.&amp;nbsp; Typical pie-menus behave more like a context menu and have the middle of the pie be cancel.&amp;nbsp; I changed this up a bit to mimic my favorite keyboard for the Palm, &lt;a href="http://www.exideas.com/ME/index.php"&gt;MessagEase&lt;/a&gt;.&amp;nbsp; The pies are buttons that if you just click will perform the center's operation.&amp;nbsp; If you click-drag the pie will popup and then release in the direction of another symbol for it to perform that operation.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;There is a trade-off in how much of the pie's contents the button shows.&amp;nbsp; If you show too much then it is cluttered.&amp;nbsp; If you show too little then the user has to explore every button to know what operations are supported and where.&lt;br /&gt;&lt;br /&gt;Sadly on Maemo devices, the performance of the pie menus is not what I would like which makes this more of a toy program.&amp;nbsp; I actually use the HP42 clone more than my own calculator&lt;br /&gt;&lt;br /&gt;Unlike when I blogged about Gonvert, I am still working on the ejpi port.&amp;nbsp; I've got all the basic functionality working except switching keyboards.&amp;nbsp; I also plan on adding rotation support, directly editing history, some UI tweaks, and maybe one or two other things that crop up.&amp;nbsp; If the performance of the pies is better I might add an algebraic entry mode to make ejpi more widely appealing.&lt;br /&gt;&lt;br /&gt;So far I plan to write about my experience in writing custom widgets for Qt, handling of dynamic layouts, and the various tree models.&amp;nbsp; We'll see what is left by the time I am finished.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-5115932094351584026?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/5115932094351584026/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/07/porting-ejpi-from-gtk-t-qt.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/5115932094351584026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/5115932094351584026'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/07/porting-ejpi-from-gtk-t-qt.html' title='Porting ejpi from GTK t Qt'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-5630911694398228981</id><published>2010-07-09T20:28:00.000-05:00</published><updated>2010-07-09T20:28:48.217-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='spiritual'/><category scheme='http://www.blogger.com/atom/ns#' term='politics'/><title type='text'>Mordecai</title><content type='html'>In &lt;a href="http://eopage.blogspot.com/2010/07/true-leadership.html"&gt;my previous post&lt;/a&gt; I quoted from The Church of Jesus Christ of Latter-day Saints's Articles of Faith.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;We believe in being subject to kings, presidents,  rulers, and magistrates, in obeying, honoring, and sustaining the law.&lt;br /&gt;&lt;div style="text-align: right;"&gt;&lt;a href="http://scriptures.lds.org/en/a_of_f/1"&gt;Article of Faith 12&lt;/a&gt; &lt;/div&gt;&lt;/blockquote&gt;I wanted to clarify what this means for when those beliefs are in contradiction to the law that we are meant to sustain.&lt;br /&gt;&lt;br /&gt;Some aspects of our belief are encouraged practices and precedence is given to local law, like how we bury the dead.&amp;nbsp; Others are  essential but not contradictory like when laws require a civil marriage  to be performed, couples have performed separately their civil marriage and their sealing of their marriage for time and all eternity.&amp;nbsp; Even though we  see the Gospel as being essential to everyone's happiness and eternal salvation, we proselyte  only in countries that legally allow it.&lt;br /&gt;&lt;br /&gt;Mordecai, Daniel, Shadrach,  Meschach, and Abed-nego are great examples for when the Kings and laws contravenes  our right to worship.&amp;nbsp; Rather than rising up in rebellion, Mordecai and  the people fasted, prayed, and petitioned the King.&amp;nbsp; Daniel, Shadrach,  Meschach, and Abed-nego all broke the law but honorably faced the consequences of  their decision to do that without losing faith.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Please note, these observations are mine alone and are not meant to  represent any of the people I am quoting&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-5630911694398228981?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/5630911694398228981/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/07/mordecai.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/5630911694398228981'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/5630911694398228981'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/07/mordecai.html' title='Mordecai'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-7200916213454625987</id><published>2010-07-09T20:16:00.000-05:00</published><updated>2010-07-09T20:16:23.927-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='politics'/><title type='text'>True Leadership</title><content type='html'>Around the world last Sunday is marked as July 4th, well, as long as you use the Gregorian calendar.&amp;nbsp; For the United States it is the celebration of declaring independence from Great Britain.&lt;br /&gt;&lt;br /&gt;One of the Articles of Faith that I adhere to is&lt;br /&gt;&lt;blockquote&gt;We believe in being subject to kings, presidents, rulers, and magistrates, in obeying, honoring, and sustaining the law.&lt;br /&gt;&lt;div style="text-align: right;"&gt;&lt;a href="http://scriptures.lds.org/en/a_of_f/1"&gt;Article of Faith 12&lt;/a&gt; &lt;/div&gt;&lt;/blockquote&gt;&lt;br /&gt;This was the focal point of a lesson someone gave recently and we talked a bit about what it means to obey, honor, and sustain the law.&lt;br /&gt;&lt;br /&gt;Its amazing what effect the words we chose have on what others say and what we all think.&amp;nbsp; Someone slipped in a comment about "leaders".&amp;nbsp; Nothing outright was said but small feelings I got where the conversation led made me worry a bit for two reasons, 1) what are "leaders", and 2) how we view our "leaders".&lt;br /&gt;&lt;br /&gt;For (1), as I quoted &lt;a href="http://eopage.blogspot.com/2010/06/on-representation.html"&gt;previously&lt;/a&gt; from Hugh Nibley&lt;br /&gt;&lt;blockquote&gt;Leaders are movers and shakers, original, inventive, unpredictable,  imaginative, full of surprises that discomfit the enemy in war and the  main office in peace. For managers  are safe, conservative, predictable,  conforming organization men and team  players, dedicated to the  establishment.&lt;br /&gt;...&lt;br /&gt;For the manager, on the other hand, the idea of  equality is repugnant  and indeed counterproductive. Where promotion,  perks, privilege, and power  are the name of the game, awe and reverence  for &lt;i&gt;rank&lt;/i&gt; is everything,  the inspiration and motivation of all  good men.&lt;br /&gt;&lt;div style="text-align: right;"&gt;&lt;a href="http://speeches.byu.edu/reader/reader.php?id=2553&amp;amp;x=39&amp;amp;y=7"&gt;Leaders  and Managers by Hugh Nibley&lt;/a&gt;&lt;/div&gt;&lt;/blockquote&gt;How many of our representatives, executives, and judges are truly leaders?&amp;nbsp; Personally, it makes me feel dirty calling them "leaders".&lt;br /&gt;&lt;br /&gt;Now for (2) which makes me feel even dirtier.&amp;nbsp; Reading Thomas Paine's comparison of representative governments to monarchical governments in "Rights of Men" has given me cause to reflect.&amp;nbsp; When reading how people view and treat the monarchical court's I wonder if in part we carried too much of that tradition with us and if we also in part reverted back to previous bad habits?&lt;br /&gt;&lt;br /&gt;The elected and nominated officials are our representatives.&amp;nbsp; We are the United States government, not those people filled in their buildings in Washington.&amp;nbsp; They are our employees.&amp;nbsp; Yes, we would love for them to be leaders for that is what is needed to face the challenges they do.&amp;nbsp; Yes, we need to sustain them, but not as some lord or duke but as underlings that we are to empower and provide needed support and correction to.&lt;br /&gt;&lt;br /&gt;Why is it that we use the &lt;a href="http://en.wikipedia.org/wiki/Peter_principle"&gt;Peter Principle&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Dilbert_Principle"&gt;Dilbert Principle&lt;/a&gt; in offering "promotions"?&lt;br /&gt;&lt;br /&gt;Why is it when we have two underlings vying for a promotion that we view it as a competition between the better of two evils? In business when there is no suitable internal candidate for a position, do we still higher one of the unsuitable ones or do we do take the risk of the unknown and perform an external hire to some third party?&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Please note, these observations are mine alone and are not meant to represent any of the people I am quoting&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-7200916213454625987?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/7200916213454625987/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/07/true-leadership.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/7200916213454625987'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/7200916213454625987'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/07/true-leadership.html' title='True Leadership'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-8806992049250275250</id><published>2010-07-08T19:35:00.000-05:00</published><updated>2010-07-08T19:35:21.115-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Trust Issues</title><content type='html'>Where I work we write in C++ but our coding style has been heavily influenced by kernel development and older coding practices.&amp;nbsp; This means we do not use exceptions, even in userspace.&lt;br /&gt;&lt;br /&gt;Rather than using a global variable for errors or peppering our code with return value checks, we pass a reference to an error value into all of our functions.&amp;nbsp; On an incoming error, the function is suppose to be a no-op.&lt;br /&gt;&lt;br /&gt;The group I work in is responsible for shared code by many hardware product teams.&amp;nbsp; One joys of this is when something a hardware group develops is wanted by others, we become the owners.&amp;nbsp; Its also fun when they continue to contribute features to it and we remain weak in our knowledge of it.&amp;nbsp; Oh and we are also clients of some groups that provide shared code for the whole company.&lt;br /&gt;&lt;br /&gt;The group underneath us in the stack has had a bug with their tScopedLock code that  it can cause a BSOD when an error is being passed in in an ISR.&lt;br /&gt;&lt;br /&gt;The code looks something kind of like (changed for simplicity, especially to be free of internal code)&lt;br /&gt;&lt;br /&gt;void tClass::operation(void* param, int&amp;amp; errno)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; tScopedLock lock(memberLock, errno); &lt;br /&gt;&lt;br /&gt;&amp;nbsp; if(errno != 0)&amp;nbsp; {&lt;br /&gt;&amp;nbsp; &amp;nbsp; int tempError = 0;&lt;br /&gt;&amp;nbsp; &amp;nbsp; cleanup(param, tempError); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; ...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Because we technically own the component they sent the bug report our way with a suggested fix that they tested.&lt;br /&gt;&lt;br /&gt;void tClass::operation(void* param, int&amp;amp; errno)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; if(errno != 0) &lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&lt;br /&gt;&amp;nbsp;  tScopedLock lock(memberLock, errno); &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; if(errno != 0)&amp;nbsp; {&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; int tempError = 0;&lt;br /&gt;&amp;nbsp; &amp;nbsp; cleanup(param, tempError); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; ...&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This seemed fishy to me.&amp;nbsp; One issue is the second error check only gets executed if the lock fails to acquire.&amp;nbsp; Seems like a small scope to worry about cleanup and that should be left for later.&amp;nbsp; The second is they probably had a reason to do that cleanup and do it under the lock.&amp;nbsp; I double checked with the implementer and he confirmed it would leak memory.&amp;nbsp; At least its better than a blue screen.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So my solution is found below.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;void tClass::operation(void* param, int&amp;amp; errno)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; int tempError = 0;&amp;nbsp;   &amp;nbsp;  tScopedLock lock(memberLock, tempError); &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; if(errno != 0) &amp;nbsp; {&lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; cleanup(param, tempError);   &amp;nbsp;&amp;nbsp;&amp;nbsp; return;&lt;br /&gt;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; else&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp; &amp;nbsp; errno = tempError; &lt;br /&gt;&amp;nbsp; }&lt;br /&gt;&amp;nbsp; ...&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;All of the code is irrelevant.&amp;nbsp; Who introduced the problem and who made the fix isn't relevant.&amp;nbsp; To me the lesson here is the importance of code ownership (even if you don't know the code you own).&amp;nbsp; Our clients are under pressure to meet their deadlines and don't feel the same level of responsibility for this code.&amp;nbsp; It met their immediate needs and they moved on.&amp;nbsp; We release with them and so have the same deadline but with a smaller bug backlog.&amp;nbsp; Fair enough we do have a bit less stress.&amp;nbsp; I still think our ownership of the code helped us to ensure it had the proper quality for the release looming over us.&lt;br /&gt;&lt;br /&gt;Another great example is we have code repos for "shared code" that have no owner.&amp;nbsp; Yes someone originally put it there but the ownership isn't recognized on the business side of things so when you have deadlines coming up it is hard to justify fixes or improvements.&amp;nbsp; We end up viewing it as the code graveyard.&lt;br /&gt;&lt;br /&gt;I'm not saying any of this is novel.&amp;nbsp; I just think it was a nice clean example, one of those "huh, nice" type of things.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-8806992049250275250?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/8806992049250275250/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/07/trust-issues.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/8806992049250275250'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/8806992049250275250'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/07/trust-issues.html' title='Trust Issues'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-679659930015868366</id><published>2010-06-29T20:12:00.001-05:00</published><updated>2010-07-12T07:14:35.717-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>Maemo and Android</title><content type='html'>Lately I've been reflecting on my commitment to Maemo.&amp;nbsp; &lt;a href="http://www.tester.ca/2010/06/26/n900-vs-nexus-one-a-comparison/"&gt;Olivier's blog post&lt;/a&gt; made some great points in both directions.&lt;br /&gt;&lt;br /&gt;Since I like to ramble, how about some background? &lt;br /&gt;&lt;br /&gt;I've been a Linux user full-time (at home) for about 8 years.&amp;nbsp; I've dual-booted for probably another 4 years before that.&amp;nbsp; I've gone from Slackware to Red Hat (wow, color printing support!) to Debian to Gentoo to Ubuntu.&amp;nbsp; I remember staying up through the entire night going through Debian's package list one at a time deciding what all amazing pieces of software I wanted installed.&lt;br /&gt;&lt;br /&gt;I loved Gentoo's USE flags.&amp;nbsp; I was importing all of my music collection as Flac.&amp;nbsp; Debian didn't have Flac enabled for all packages but with USE flags I could enable Flac for everything that could build it in.&amp;nbsp; I started tiring of Gentoo's multiple day install process.&amp;nbsp; I would slip up somewhere somehow and wouldn't detect it until the entire system had compiled.&amp;nbsp; I didn't know what was wrong so I would start over from scratch.&amp;nbsp; This almost made me abandon Linux.&amp;nbsp; With Windows everything "just worked". &amp;nbsp; The "freedom to leave" kept me strong until I decided to "take the wimpy way out" and switch to Ubuntu.&amp;nbsp; That is the main motivating force behind the software and web apps I use.&lt;br /&gt;&lt;br /&gt;For handhelds I originally used palm devices.&amp;nbsp; More of my data was moving to the web and at college I had wifi everywhere.&amp;nbsp; I wanted a handheld device that could match my circumstances and wants.&amp;nbsp; I chose Maemo and have been using it for about 3 years.&amp;nbsp; It wasn't too long after that that I started contributing to projects.&lt;br /&gt;&lt;br /&gt;The lack of polish makes me sometimes wonder about alternatives.&amp;nbsp; I sadly admit that for a couple months I used an iPod Touch as my 770 was dying and I was hoping the n900 would release soon (it didn't and I got an n810).&amp;nbsp; That convinced me I couldn't go iOS.&amp;nbsp; Android is starting to look attractive though.&amp;nbsp; I've even felt it was the best thing to recommend to some family members who originally followed me onto Maemo.&amp;nbsp; That was a sad moment.&lt;br /&gt;&lt;br /&gt;Some questions I ask myself include:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Why should I stay on Maemo when Android is blossoming?&lt;/li&gt;&lt;li&gt;Does Maemo have staying power in the market?&lt;/li&gt;&lt;li&gt;Would I need to invest as much time in development if I had Android's larger (free) market available?&lt;/li&gt;&lt;/ul&gt;I then remind myself&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Working on the projects I do is a great way to develop skills independent of what work projects I do.&lt;/li&gt;&lt;li&gt;If I do decide to work on a project, I much prefer VIM + Python to Eclipse + Java. I write my apps on the desktop and validate they transition smoothly to the device.&amp;nbsp; SSHing into my device is great.&amp;nbsp; Modifying the source right there and trying things out is great.&lt;/li&gt;&lt;li&gt;Maemo has a much better chance as Meego due to becoming decoupled from a single vendor.&amp;nbsp; I didn't say it would be like Android but it'll be better.&lt;/li&gt;&lt;li&gt;The flexibility of the architecture.&amp;nbsp; DBus is a great system.&amp;nbsp; I love that Maemo uses telepathy.&amp;nbsp; After the long process of learning it I was able to integrate Google Voice support both in my phone and my desktop system.&amp;nbsp; I've started work on a Bluetooth plugin but that has stalled due to other projects.&amp;nbsp; The types of customizations people develop is great.&lt;/li&gt;&lt;/ul&gt;So for now I will be sticking to Maemo/Meego.&amp;nbsp; I hope I keep having reason to stick to the platform.&amp;nbsp; In the meantime I will keep writing software for it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-679659930015868366?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/679659930015868366/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/06/maemo-and-android.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/679659930015868366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/679659930015868366'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/06/maemo-and-android.html' title='Maemo and Android'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-5472052190042241130</id><published>2010-06-29T19:20:00.018-05:00</published><updated>2010-07-12T07:14:39.651-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>Porting Gonvert: Meaningless Results</title><content type='html'>So let's see how the two versions of Gonvert compare:&lt;br /&gt;&lt;br /&gt;Qt Version&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Feature parity with the GTK version &lt;/li&gt;&lt;li&gt;5 Windows (Two ways of unit conversion, quick jump, and recent)&lt;br /&gt;&lt;/li&gt;&lt;li&gt; 1985 LOCs&lt;/li&gt;&lt;li&gt;From May 26 to June 15th&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;GTK Version&lt;br /&gt;&lt;ul&gt;&lt;li&gt;1 Window&lt;/li&gt;&lt;li&gt;1658 LOCs (766 of that is hildonize.py which Gonvert doesn't use  all of it)&lt;/li&gt;&lt;li&gt;From October 29th to January 9th&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;LOCs are measured by "wc -l" rather than getting fancy.&amp;nbsp; I wrote both  apps and they were written in a similar style with similar amounts of  whitespace and documentation.&lt;br /&gt;&lt;br /&gt;So for all of my criticism of Qt this went fairly quickly without a lot of code. I look forward maintaining this code base going forward.&amp;nbsp; It is still hard to compare the numbers because of how meaningless they are.&amp;nbsp; How much should hildonize.py count towards the GTK version?&amp;nbsp; How much of the GTK development time was me learning the code and providing a smooth refactored path through revision history rather than doing a fresh rewrite?&lt;br /&gt;&lt;br /&gt;One nice side benefit of not having to modify the actual unit list or the base conversions is that I'm still shipping the GTK version in case someone really doesn't like the new stuff.&amp;nbsp; Now that I'm well beyond feature parity I don't think that is as much of a concern anymore.&lt;br /&gt;&lt;br /&gt;I've already started on the next phase of my Qt learning process, porting ejpi.&amp;nbsp; Some outside things have come up which has slowed down my progress.&amp;nbsp; I'll follow up with posts on that later.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-5472052190042241130?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/5472052190042241130/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/06/porting-gonvert-meaningless-results.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/5472052190042241130'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/5472052190042241130'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/06/porting-gonvert-meaningless-results.html' title='Porting Gonvert: Meaningless Results'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-6801744864161106236</id><published>2010-06-29T07:33:00.015-05:00</published><updated>2010-07-12T07:14:44.380-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>Porting Gonvert: The Actual Port</title><content type='html'>Starting from scratch made it a bit easier to redo the  architecture and pieces of the UI.&lt;br /&gt;&lt;br /&gt;I started off with  one class named Gonvert that acted as my application class.&amp;nbsp; It owned  all of the global QActions (which I coupled to my settings) and  top-level windows.&amp;nbsp; Ironically enough I did not have it own the  QApplication.&amp;nbsp; I left that to my main function.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I dislike circular references but with Gonvert owning all of the  global QActions I passed the instance down into its children so they  could add them to their QWidgets and menus.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Gonvert also managed loading and saving of settings.&amp;nbsp; I normally  manage settings manually and then load/save them through Python's ini  handling code.&amp;nbsp; This time I created dictionaries with QAction values  being the values.&amp;nbsp; I then serialized/deserialized using simplejson.&amp;nbsp;  This worked well.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I decided to take better advantage of stacked windows and made  Categories a window rather than a dialog.&amp;nbsp; Like with other GTK applications, I ran into  issues with modality and stacked windows when deploying to Maemo so I  had to restructure things to allow everything to run on the desktop  without being modal.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;GTK's way of creating list views and tree views requires a lot of  boilerplate but uses minimal inheritance internally and requires  minimal inheritance to customize.&amp;nbsp; I think all you need to inherit for  is creating custom cell renderers and creating your on model if you  decide to not re-use theirs.&amp;nbsp; I loved that I could put any data type,  including complex python types into the default models.&amp;nbsp; I never created  my own model (though I probably should have in some places).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I must admit, I lied earlier.&amp;nbsp; I had to use concrete inheritance  to do a custom model with Qt.&amp;nbsp; The models I was seeing were very  restrictive and seemed only focused on QStrings.&amp;nbsp; With Gonvert I need to  do math on data in the model and I like to center on the decimal  place.&amp;nbsp; So I had to create a custom model to internally store the raw  value and then to have a column for left of the decimal place and a  column for the right of the decimal place.&amp;nbsp; The customizing I did in GTK  with CellRenderers seems to be coupled into the Qt model which is  really sad.&amp;nbsp; Why does my model care about presentation?&amp;nbsp; Why?&amp;nbsp; Why?&amp;nbsp; So  it looks like for a lot of things I'll have to create custom models.&amp;nbsp;  Sadly creating a model was confusing but since I never did it in GTK I  can't say if it is easier or harder.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Gonvert tends to have a lot of units.&amp;nbsp; For some this is cool in a  geeky sort of way.&amp;nbsp; For others it means they have to scroll through  more to find what they want.&amp;nbsp; I went ahead and implemented favorites.&amp;nbsp;  It worked out pretty easy to write it all.&amp;nbsp; The favorites editor uses strings only so I took  advantage of the built in model.&amp;nbsp; I originally implemented it by having  the user select the row.&amp;nbsp; This played a tad bit better than GTK with  scrolling on Maemo but it was still a bit finicky.&amp;nbsp; A drag to scroll was  sometimes interpreted as a drag to select or unselect.&amp;nbsp; I eventually switched it to togglable items which got the favorites editor to work smoothly.&amp;nbsp; I then would have the category and unit selection windows hide the non-favorite rows.&amp;nbsp; There is a filter to both sort and filter but I had read some bad things about it and just decided to do both manually.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;On a related note to scrolling and lists I noticed strange  behavior when adding my "Quick Convert" or "Condensed View".&amp;nbsp; When you  drag a list to scroll, the widget fires a selection changed event for  the row you started the drag on and then it fires an event to put you  back where you were.&amp;nbsp; Kind of hacky.&amp;nbsp; I shared code between  programmaticly setting a unit type and the user selecting one.&amp;nbsp; In the  programmatic case we want to scroll to the unit.&amp;nbsp; In the user case this  caused their scrolling to jump around because of these selection events  firing.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The main view in Gonvert has tended to be a bit slow.&amp;nbsp; In the Qt  version it was even slower especially with Favorites added.&amp;nbsp; The main  view has an edit box where the user types in a value and then below that  is a list of all units and what that value gets converted into.&amp;nbsp; The unit values get updated, and resorted on every keypress.&amp;nbsp; This  with sorting caused odd issues with me setting rows as hidden for  favorites so I had to update that every time the user put in a value.&amp;nbsp;  The slow downs:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Marked the model as modified more times than needed&lt;/li&gt;&lt;li&gt;Modifying setRowHidden more times than needed&lt;/li&gt;&lt;li&gt;Doing a lot of calls back into Qt in the innerloop of Qt calling  into my code.&lt;/li&gt;&lt;/ul&gt;When updating all the values I limited re-sorts to only happen when  the value column is selected for sort.&amp;nbsp; I also made it so we would not  signal the model as modified first for the modification and then again  for the sort.&amp;nbsp; I also throttled updating of favorites.&amp;nbsp; When the user  edits the value a QTimer gets started if it hasn't already.&amp;nbsp; At the end  of the timer the model gets updated.&amp;nbsp; This introduces a minor delay in  the updating (set to 100ms right now) but reduces the amount of time we  block the users editing by good enough amount.&amp;nbsp; Sadly whenever the timer  goes off and the user is still pressing a lot of numbers, there is a  slight pause.&lt;br /&gt;&lt;br /&gt;Other things&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I played around with the favorites.&lt;/li&gt;&lt;li&gt;I removed a lot of the error checking in my model (like checking  to see if the index was valid).&amp;nbsp; This proved very beneficial (as long as  the View is written correctly).&lt;/li&gt;&lt;li&gt;I think I also did some other optimizations but those were the  main ones.&lt;/li&gt;&lt;/ul&gt;Yes, I guided myself in this with the use of a profiler.&lt;br /&gt;&lt;br /&gt;One nice thing about this port has been that I've not had to touch anything not related to UI like the loading of units and converting a single unit.&amp;nbsp; Sadly my model before and after has been coupled to the UI.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-6801744864161106236?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/6801744864161106236/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/06/porting-gonvert-actual-port.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/6801744864161106236'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/6801744864161106236'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/06/porting-gonvert-actual-port.html' title='Porting Gonvert: The Actual Port'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-6418704822400410684</id><published>2010-06-28T07:30:00.002-05:00</published><updated>2010-07-12T07:14:48.522-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>Porting Gonert: Qt's Design</title><content type='html'>All of the tutorials probably followed the bad example of Qt for  concrete inheritance.&amp;nbsp; Some features are &lt;a href="http://doc.trolltech.com/4.6/qwidget.html#closeEvent"&gt;only  available through inheritance&lt;/a&gt;.&amp;nbsp; Others have &lt;a href="http://labs.trolltech.com/blogs/2010/06/17/youre-doing-it-wrong"&gt;only  recently allowed for composition&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Luckily I was  able to get through all of Gonvert without concrete inheritance.&amp;nbsp; A nice  trick to avoid inheriting from QObject to create signals is to hijack  QAction.&amp;nbsp; I actually used QActions for what they were intended in  Gonvert but in some future apps I might abuse them.&amp;nbsp; I find the class  hierarchies odd as compared to GTK.&amp;nbsp; Just one example is GTK encourages  inserting widgets into scroll windows but Qt has widgets inherit from  them.&amp;nbsp; I do admit this probably lets them couple the concepts closely  enough that it makes it easier to give a native feel on platforms.&lt;br /&gt;&lt;br /&gt;The  sweet taste of bloat in the morning.&amp;nbsp; Qt let's you show any QWidget as a  window.&amp;nbsp; This requires less boiletplate for debugging my own custom  widgets (which I left for my next porting exercise) but it makes each  widget feel bloated that they can completely handle being a window in of  themselves.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Qt was designed when C++ had a less extensive set of  libraries.&amp;nbsp; Why does that have to bleed over into the Python bindings  though?&amp;nbsp; When I first dived into GTK I was nervous about my interactions  with the underlying types and ownership.&amp;nbsp; I eventually learned I could  just ignore all of it and it felt great.&amp;nbsp; GTK had a feel that is very  native to Python.&amp;nbsp; Tutorials for PyQt on the other hand have to go into  long discussions of the trade-offs between native data types and Qt's  data types.&amp;nbsp; They also had to go over object ownership rules.&amp;nbsp; This left  a bad taste in my mouth.&lt;br /&gt;&lt;br /&gt;I also see people  recommending Qt equivalents of python objects. I'd rather not couple  myself that tightly to the UI framework.&amp;nbsp; You can keep your database  access, your XML, and (I hope) your threading.&amp;nbsp; That last one I have yet  to explore how worth while it is to do.&lt;br /&gt;&lt;br /&gt;A minor  annoyance, ctrl+c in the shell does not seem to kill Qt.&amp;nbsp; If things went  wrong setting everything up I have to go and &lt;i&gt;kill&lt;/i&gt; my  application.&amp;nbsp; That can be annoying for keeping debug cycles short.&amp;nbsp; I  also had it crash on exit a lot.&amp;nbsp; I have no clue what I changed that  removed that.&lt;br /&gt;&lt;br /&gt;The old-style signal syntax is nasty  in Qt.&amp;nbsp; The new stuff is pretty good.&amp;nbsp; I dislike that I don't get a  token to use to unregister a slot but I pass in the same function.&amp;nbsp; This  is annoying when your slot is a lambda.&amp;nbsp; It is also annoying if for  some crazy reason you wanted to register a slot multiple times.&amp;nbsp;  Registering multiple times and my use of lambdas brings up another  annoyance.&amp;nbsp; GTK is written in C and so all callbacks had to offer a  void* data pointer at the end so anything can be done with them.&amp;nbsp; In  PyGTK this was cool because they exposed that to the user by allowing  arbitrary objects to be passed in there (the object was already being  passed in when using a bound method).&amp;nbsp; They even implemented it through &lt;i&gt;*args&lt;/i&gt;  so you didn't have it bundle up multiple objects yourself, it would do  it for you.&amp;nbsp; In DialCentral I use a single slot for the dialpad and then  use the data parameter to differentiate the key.&amp;nbsp; Qt is designed around  slots being on objects I think and is used to member function  pointers.&amp;nbsp; This sadly means they didn't have to have the &lt;i&gt;void*&lt;/i&gt; of  C days and you have to go through extra steps to pass arbitrary data to  a slot.&lt;br /&gt;&lt;br /&gt;I do really enjoy QActions.&amp;nbsp; At least I  said something positive, right?&amp;nbsp; I'll probably have more gripes and more  things to praise it for as I continue porting my applications over.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-6418704822400410684?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/6418704822400410684/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/06/porting-gonert-qts-design.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/6418704822400410684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/6418704822400410684'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/06/porting-gonert-qts-design.html' title='Porting Gonert: Qt&apos;s Design'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-1621317144244802105</id><published>2010-06-26T17:00:00.002-05:00</published><updated>2010-07-12T07:14:52.804-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>Porting Gonvert: Qt's Documentation</title><content type='html'>Why do almost all &lt;a href="http://zetcode.com/tutorials/pyqt4/widgets/"&gt;UI examples&lt;/a&gt; rely  heavily on concrete inheritance?&amp;nbsp; As I looked for tutorials, examples,  and references, I kept seeing concrete inheritance come up.&amp;nbsp; It is bad  design and it muddles up the examples.&amp;nbsp; Are they creating a function in  the class for their own use or are they overriding a method?&amp;nbsp; How  critical is it they override it to be able to get functionality X?&lt;br /&gt;&lt;br /&gt;PyGTK  &lt;a href="http://www.moeraki.com/pygtkreference/pygtk2tutorial/index.html"&gt;tutorial&lt;/a&gt;  and &lt;a href="http://www.pygtk.org/pygtk2reference/"&gt;reference&lt;/a&gt; were  great.&amp;nbsp; Everything is easily found in the reference and almost  everything I needed to know was in the tutorial.&amp;nbsp; Qt's &lt;a href="http://doc.trolltech.com/4.6/classes.html"&gt;reference&lt;/a&gt; is good,  PyQt's is a bit more &lt;a href="http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/classes.html"&gt;so-so&lt;/a&gt;.&amp;nbsp;  As for tutorials I have not found one concrete tutorial that covers 90%  of what I need but instead &lt;a href="http://www.commandprompt.com/community/pyqt/book1"&gt;need&lt;/a&gt; &lt;a href="http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/pyqt4ref.html#connecting-disconnecting-and-emitting-signals"&gt;to&lt;/a&gt;  &lt;a href="http://zetcode.com/tutorials/pyqt4/widgets/"&gt;jump&lt;/a&gt; &lt;a href="http://cep.xor.aps.anl.gov/software/qt4-x11-4.2.2/painting-basicdrawing.html"&gt;from&lt;/a&gt;  &lt;a href="http://www.rkblog.rk.edu.pl/w/p/introduction-pyqt4/"&gt;tutorial&lt;/a&gt;  to &lt;a href="http://diotavelli.net/PyQtWiki/Tutorials"&gt;tutorial&lt;/a&gt;  depending on the specific thing I am doing.&amp;nbsp; I've even done &lt;a href="http://nullege.com/"&gt;searches through source code&lt;/a&gt; to try and  find how to use somethings but that didn't get me much.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-1621317144244802105?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/1621317144244802105/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/06/porting-gonvert-qts-documentation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/1621317144244802105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/1621317144244802105'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/06/porting-gonvert-qts-documentation.html' title='Porting Gonvert: Qt&apos;s Documentation'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-7486319855933088844</id><published>2010-06-26T11:16:00.001-05:00</published><updated>2010-07-12T07:14:58.186-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>Porting Gonvert from GTK to Qt</title><content type='html'>On &lt;a href="http://talk.maemo.org/"&gt;t.m.o&lt;/a&gt; I sometimes see requests to port applications from a previous generation of Maemo (like Quicknote and Multilist) or to port a desktop application to Maemo (like Gonvert).&lt;br /&gt;&lt;br /&gt;I must be asking for punishment taking on a lot of these.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://maemo.org/downloads/product/Maemo5/gonvert/#"&gt;Gonvert&lt;/a&gt; started off as a unit converter for the desktop.&amp;nbsp; The &lt;a href="http://www.unihedron.com/projects/gonvert/index.php"&gt;UI was not well suited for mobile devices&lt;/a&gt;.&amp;nbsp; I had to make the UI more minimal and use my hildonize.py code to make it auto-hildonize.&amp;nbsp; Underneath the surface I had to do drastic code cleanup to even figure out how all the parts interact (btw if you want to see refactoring in action, check out &lt;a href="https://garage.maemo.org/plugins/ggit/browse.php/?p=gonvert"&gt;my early git history with Gonvert&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;As part of &lt;a href="http://eopage.blogspot.com/2010/06/from-maemo-to-meego.html"&gt;my plan for learning Qt and preparing for Meego&lt;/a&gt;, I decided Gonvert would be my first port.&amp;nbsp; No custom widgets, no threading, just taking user input and processing it to generate output.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So I'm going to look at Qt's documentation and design, what my experience was like porting Gonvert, and some meaningless statistics on the port.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-7486319855933088844?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/7486319855933088844/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/06/porting-gonvert-from-gtk-to-qt.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/7486319855933088844'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/7486319855933088844'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/06/porting-gonvert-from-gtk-to-qt.html' title='Porting Gonvert from GTK to Qt'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-6568008447690765962</id><published>2010-06-20T11:58:00.000-05:00</published><updated>2010-06-26T08:59:52.011-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='politics'/><title type='text'>On Representation</title><content type='html'>&lt;blockquote&gt;There is a bastard kind of generosity, which, by being extended to all men, is as fatal to society, on one hand, as the want of true generosity is on the other.  A lax manner of administering justice, falsely termed moderation, has a tendency both to dispirit public virtue, and promote the growth of public evils.&lt;br /&gt;&lt;div style="text-align: right;"&gt;Common Sense, Rights of Man, and Other Writings of Thomas Paine&lt;br /&gt;pg 81&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;Lately (as in over the last year or more) I've been reading various writings of Thomas Paine.  In Rights of Man he defends free governments against Edmond Burke's attacks and Paine himself attacks back against monarchy.&lt;br /&gt;&lt;br /&gt;How do we compare today with what the propagandist claims us to be on transparency, the role of our "leaders", and taxes:&lt;br /&gt;&lt;blockquote&gt;But the case is, that the representative system diffuses such a body of knowledge throughout a Nation on the subject of Government, as to explode ignorance and preclude imposition.  The craft of [royal] courts cannot be acted on that ground.  There is no place for mystery, nowhere for it to begin.  Those who are not in the representation know as much of the nature of business as those who are.  An affection of mysterious importance would there be scouted.  Nations can have no secrets; and the secrets of courts, like those of individuals, are always their defects.&lt;br /&gt;&lt;br /&gt;In the representative system, the reason for everything must publicly appear.  Every man is a proprietor in Government and considers it a necessary part of his business to understand.  It concerns his interest, because it affects his property.  He examines the cost, and compares it with the advantages, and above all, he does not adopt the slavish custom of following what in other Governments are called LEADERS.&lt;br /&gt;&lt;br /&gt;It can only be by blinding the understanding of man, and making him believe that Government is some wonderful mysterious thing, that excessive revenues are obtained.  Monarchy is well calculate to ensure this end.  It is the popery of Government, a thing kept up to amuse the ignorant and quiet them into taxes.&lt;br /&gt;&lt;br /&gt;The Government of a free country, properly speaking, is not in the persons, but in the laws.  The enacting of those requires no great expense; and when they are administered the whole of civil Government is performed - the rest is all [royal] court contrivance.&lt;br /&gt;&lt;div style="text-align: right;"&gt;Common Sense, Rights of Man, and Other Writings of Thomas Paine&lt;br /&gt;pg 293&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;How much mystery do we have in our government?  The race to declare negotiations of counterfeiting treaties as state secrets, the convoluting of processes, back room deals, hiding pork in large "public good" bills.  How do these things take affect and how do we stop it? I've heard Tocqueville would attribute it to apathy and I believe that would be a good chunk of it.  What do we do about it though?&lt;br /&gt;&lt;br /&gt;Also look how we inflate the role of &lt;span style="font-style: italic;"&gt;public servants&lt;/span&gt; from being represenatives, judges, and executors to the great epitaph of Leaders.  Most do not deserve that moniker and are at best managers working for their own good.  I turn to Hugh Nibley for a good description of the difference between Leaders and Managers&lt;br /&gt;&lt;blockquote&gt;Leaders are movers and shakers, original, inventive, unpredictable, imaginative, full of surprises that discomfit the enemy in war and the main office in peace. For managers  are safe, conservative, predictable, conforming organization men and team  players, dedicated to the establishment.&lt;br /&gt;...&lt;br /&gt;For the manager, on the other hand, the idea of equality is repugnant  and indeed counterproductive. Where promotion, perks, privilege, and power  are the name of the game, awe and reverence for &lt;i&gt;rank&lt;/i&gt; is everything,  the inspiration and motivation of all good men.  ...&lt;br /&gt;&lt;br /&gt;"If you love me," said the Greatest of all leaders, "you will keep my commandments." "If you know what is good for me," says the manager, "you will keep &lt;i&gt;my&lt;/i&gt; commandments, and not make waves." That is why the rise of management always marks the decline of culture.&lt;br /&gt;&lt;div style="text-align: right;"&gt;&lt;a href="http://speeches.byu.edu/reader/reader.php?id=2553&amp;amp;x=39&amp;amp;y=7"&gt;Leaders and Managers by Hugh Nibley&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/blockquote&gt;I highly recommend reading the rest of that commencement address he gave.&lt;br /&gt;&lt;br /&gt;Another great quote to contemplate on representative governments accomplishing good:&lt;br /&gt;&lt;blockquote&gt;It is always the interest of a far greater number of people in a Nation to have things right than to let them remain wrong; and when public matters are open to a debate, and the public judgment free it will not decide wrong, unless it decides too hastily.&lt;br /&gt;&lt;div style="text-align: right;"&gt;Common Sense, Rights of Man, and Other Writings of Thomas Paine&lt;br /&gt;pg 301&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;With managers representing us, we have those who create, pass, and sign laws that contain the worst of both sides to an argument without the benefits of either  rather than working from principle and compromising for the greater  good.  How many politicians have passed laws so hastily that they have not read the very law they are passing?  How long will we be hurting from this haste when these laws are such wide sweeping things as covering outrageously sized stimulus plans or national health care?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-6568008447690765962?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/6568008447690765962/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/06/on-representation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/6568008447690765962'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/6568008447690765962'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/06/on-representation.html' title='On Representation'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-2915903624656493715</id><published>2010-06-17T21:33:00.001-05:00</published><updated>2010-07-12T07:15:02.743-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><title type='text'>From Maemo to Meego</title><content type='html'>&lt;blockquote&gt;Seek out any project that has one of the following resume-ready words in its description:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Multimedia&lt;/li&gt;&lt;li&gt;Worldwide&lt;/li&gt;&lt;li&gt;Advanced&lt;/li&gt;&lt;li&gt;Strategic&lt;/li&gt;&lt;li&gt;Revenue&lt;/li&gt;&lt;li&gt;Market&lt;/li&gt;&lt;li&gt;Technology&lt;/li&gt;&lt;li&gt;Rapid&lt;/li&gt;&lt;li&gt;Competitive&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: right;"&gt;The Dilbert Principle, pg 81&lt;br /&gt;by Scott Adams&lt;/div&gt;&lt;/blockquote&gt;I'm thinking it best to start off with a little background.  On &lt;a href="http://www.blogger.com/talk.maemo.org"&gt;talk.maemo.org&lt;/a&gt; and throughout the rest of &lt;a href="http://www.blogger.com/maemo.org"&gt;maemo.org&lt;/a&gt; I am known as "epage" (I tend not to be too Original).  I joined the community when I got myself a Nokia 770 to replace my Palm Pilot I used for keeping myself organized at school.  My old college campus has wifi everywhere and I had moved a lot of my data over to online services so I needed a device that could handle my changing needs.&lt;br /&gt;&lt;br /&gt;I started off contributing to a project called "GCDialer" a Grand Central client for Maemo.  GCDialer would use your browsers cookies file with wget to communicate with Grand Central.  This worked great on Maemo but my desktop had already switched to a version of Firefox that changed how cookies were stored.  To get this to work on my desktop I took an ActiveState recipe for downloading pages with cookies and integrated it into GCDialer.  Since then the other contributors backed off, we switched the name to DialCentral (pre-GV, for trademark concerns), moved over to Maemo 4.1, added a host of features when adding Google Voice support, and added Maemo 5 support.&lt;br /&gt;&lt;br /&gt;I'm now the sole maintainer of &lt;a href="http://maemo.org/downloads/product/Maemo5/dialcentral/"&gt;DialCentral&lt;/a&gt;, &lt;a href="http://maemo.org/downloads/product/Maemo5/quicknote/#"&gt;Quicknote&lt;/a&gt;, &lt;a href="http://maemo.org/packages/view/multilist/"&gt;Multilist&lt;/a&gt;, &lt;a href="http://maemo.org/downloads/product/Maemo5/ejpi/"&gt;ejpi&lt;/a&gt;, &lt;a href="http://maemo.org/downloads/product/Maemo5/gonvert/"&gt;Gonvert&lt;/a&gt;, and &lt;a href="http://maemo.org/packages/view/telepathy-theonering/"&gt;The One Ring&lt;/a&gt;.  I've also contributed to &lt;a href="http://maemo.org/packages/view/nqaap/"&gt;NQA&lt;/a&gt; and flirted with &lt;a href="http://gitorious.org/epage-mer"&gt;Mer&lt;/a&gt;.  This list slowly evoled as I've either start new projects (ejpi, The One Ring), I wanted to make improvements to things I use regularly (DialCentral, Quicknote), or people have requested ports (Multilist, Gonvert, NQA).&lt;br /&gt;&lt;br /&gt;Recently I've been trying to help out on the wiki with &lt;a href="http://wiki.maemo.org/Performance_Considerations_for_Python_Apps"&gt;Python Performance&lt;/a&gt; and &lt;a href="http://wiki.maemo.org/PyQt_Tips_and_Tricks"&gt;PyQt&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;That last one is where I'm going with this.   I have a couple projects in the pipeline.  One is for a non-profit and I'm waiting on them to give the "Ok" before releasing.  Developing an app that was not for my specific needs or the needs of other community members but for a longer term benefit of a non-profit motivated me to finally start preparing for Meego.&lt;br /&gt;&lt;br /&gt;With Maemo 6 we were told Qt was the future and GTK was community-support only.  I think I saw in the transition from Maemo 6 to Meego that GTK was going to be fully supported.  I took that from the Maemo perspective (rather than Moblin) and assumed GTK/Hildon was to be supported.  This made me complacent to learning Qt and switching over.  It took long enough switching my applications to support Maemo 5 in addition to Maemo 4.1 but to switch the toolkit also?.  After &lt;a href="http://lists.meego.com/pipermail/meego-dev/2010-May/002442.html"&gt;some discussion on the mailing list&lt;/a&gt; about Hildon on Meego it looks like &lt;a href="http://lists.meego.com/pipermail/meego-dev/2010-June/003201.html"&gt;Stskeeps is going to pull through on this one&lt;/a&gt; though I wonder what Hildon is like without the custom GTK underneath. &lt;br /&gt;&lt;br /&gt;I still figure I should learn Qt.  My plan is the following:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Port Gonvert for an intro into the basic Qt UIs&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Port ejpi to learn about custom widgets&lt;/li&gt;&lt;li&gt;Port DialCentral to develop strategies for threading&lt;/li&gt;&lt;/ul&gt;I've actually finished Gonvert and plan to write up my experience from that.  The main reason I finally got around to starting a blog was to provide a source of slightly less outdated information than what I kept running into.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-2915903624656493715?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/2915903624656493715/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/06/from-maemo-to-meego.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/2915903624656493715'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/2915903624656493715'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/06/from-maemo-to-meego.html' title='From Maemo to Meego'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-2517704899085977752</id><published>2010-06-16T08:28:00.000-05:00</published><updated>2010-06-26T08:59:52.020-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Temporary Death</title><content type='html'>&lt;blockquote&gt;Your roof, as you know very well, has been recently repaired, and has no aperture by which even a Woman could penetrate.&lt;br /&gt;&lt;div style="text-align: right;"&gt;Flatland, pg 81&lt;br /&gt;by Edwin A. Abbott&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;My group at work has three main clients: 1) customers who use our product in our tightly integrated ecosystem, 2) customers who use a variant in a more traditional environment, and 3) internal clients using us to build even more complex products for customers.&lt;br /&gt;&lt;br /&gt;Sadly (1) is what we end up testing the most.&lt;br /&gt;&lt;br /&gt;One part of our system is heavily used by (2) and (3) but not (1).  So it is no wonder that we just now found out (internally) about a race condition with a delay loaded object in software that is about 7 years old and used in mission critical applications.  I know what you might be thinking but this will not be a sordid tale about the woes of singletons.&lt;br /&gt;&lt;br /&gt;We have a critical section around the delay loading.  I recently got a bug report on a crash when we have two threads racing to use the object on process start.  I sat back baffled for a bit not seeing the problem in our code so moving on to blaming the tools.  I know, big mistake but at some point libraries do fail.  It turns out the problem was with us and was fairly simple&lt;br /&gt;&lt;br /&gt;A little background for non-C++ folk:&lt;br /&gt;In C++ there is an idiom called  &lt;a href="http://en.wikipedia.org/wiki/RAII"&gt;RAII &lt;/a&gt;which allows for  easy handling of resources.  In this case when tScopedLock is created  the lock is acquired.  At the end of scope the lock is released.   Whenever I see a garbage collected OOP language without an equivalent a  little part of me dies having to see all of those "finally" clauses.  I  was very glad Python added the "with" statement and "from __future__  import with_statement" can be found in most of my python scripts.&lt;br /&gt;&lt;pre&gt;void tClass::loadIfNeeded()&lt;br /&gt;{&lt;br /&gt;    tScopedLock(lock);&lt;br /&gt;    if(!loaded)&lt;br /&gt;    {&lt;br /&gt;        load();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;With a coding convention that is discouraging of spaces things tend to bleed together.  So sadly it took me digging into the Windows Critical Sections data structure to realize when the count inside it was being modified.  So I went and put the fix in&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;void tClass::loadIfNeeded()&lt;br /&gt;{&lt;br /&gt;    tScopedLock scopedLock(lock);&lt;br /&gt;    if(!loaded)&lt;br /&gt;    {&lt;br /&gt;        load();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Oh the joys of accidental temporaries and their scope which &lt;a href="http://www.google.com/url?sa=t&amp;amp;source=web&amp;amp;cd=2&amp;amp;ved=0CBYQFjAB&amp;amp;url=http%3A%2F%2Fwww.informit.com%2Fguides%2Fcontent.aspx%3Fg%3Dcplusplus%26seqNum%3D198&amp;amp;ei=xNMaTPqQOJzwNOvRtY0N&amp;amp;usg=AFQjCNEsvB-f83FC39jhrlz4sKM36DL2Jg&amp;amp;sig2=QLs-S6Rx3bJZRvmXDn03-Q"&gt;lasts for the expression they appear in&lt;/a&gt; (&lt;a href="http://www.google.com/url?sa=t&amp;amp;source=web&amp;amp;cd=3&amp;amp;ved=0CB8QFjAC&amp;amp;url=http%3A%2F%2Fwww.informit.com%2Fblogs%2Fblog.aspx%3Fuk%3D30-C-Tips-in-30-Days-Tip-28-the-lifetime-of-a-temporary-object-bound-to-a-reference&amp;amp;ei=xNMaTPqQOJzwNOvRtY0N&amp;amp;usg=AFQjCNGsm02XoqVHQontVk0vbv5X7a3M8Q&amp;amp;sig2=X-W3hlYW9aigyr44FaeyIA"&gt;usually&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Of course I was a (mostly) good citizen.  I grepped through our code and fixed about 5 instances of this problem.  I then added a check in our (very limited) static analysis to watch for people adding them.  On an internal forum people came up with some pre-proc magic to try and help.  Maybe later I'll investigate that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-2517704899085977752?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/2517704899085977752/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/06/temporary-death.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/2517704899085977752'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/2517704899085977752'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/06/temporary-death.html' title='Temporary Death'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-6237524693321580212</id><published>2010-06-16T07:21:00.000-05:00</published><updated>2010-06-26T08:59:52.024-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='spiritual'/><title type='text'>"It's because people are stupid!"</title><content type='html'>&lt;blockquote style="color: rgb(0, 0, 0);"&gt;It was reported that when Dr. Willard Richards ... first saw a copy of the Book of Mormon he opened it in the center and read a few pages.  He closed the book with this statement: "That book was either written by God or the devil, and I am going to find out who wrote it."&lt;br /&gt;&lt;div style="text-align: right;"&gt;A Marvelous Work And A Wonder, pg 81&lt;br /&gt;By LeGrand Richards&lt;/div&gt;&lt;/blockquote&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;I've occasionally played catch up with BYU's Tuesday Morning Devotionals.  Recently I read "&lt;/span&gt;&lt;a style="color: rgb(0, 0, 0);" href="http://speeches.byu.edu/reader/reader.php?id=13035&amp;amp;x=34&amp;amp;y=7"&gt;Scholarship and Faith&lt;/a&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;" by Ross Spencer. I'd like to start off with his introduction to Dr Henry Eyring and Dr Eyring's comments:&lt;/span&gt; &lt;blockquote style="color: rgb(0, 0, 0);"&gt;Dr. Henry Eyring, the great LDS chemist and father of President Henry B. Eyring, was a great  example of how to combine professional excellence with faith and humility. He was world-famous for his work on chemical reactions and was  also known both to his scientific colleagues and to members of the Church as a man of faith and devotion. He said:&lt;i&gt;&lt;br /&gt;...&lt;br /&gt;So this, then, is sort of the picture that I would give you and end on the note that I can’t see any difference between the  kinds of arguments that you make to support religion and the arguments that you make to support science. I understand, of course,  that there are contradictions of all kinds in science, and there are contradictions between science and religion, and there are  contradictions between various parts of religion in every human mind  (but not in God’s mind; in a billion years you’ll have your problems solved, if you  can wait).&lt;/i&gt; [Henry Eyring, “You Don’t Have to Make All  the Mistakes There Are,” speech given at Brigham Young University, no  date, Henry Eyring Papers, Manuscript Division, Special Collections,  J. Willard Marriott Library, University of Utah, box 20, folder  23;quoted in Henry J. Eyring, &lt;i&gt;Mormon Scientist,&lt;/i&gt; 302]&lt;/blockquote&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;I know that there is a God.  I do not feel the need to conform my religion to science or science to my religion.  I feel confident in holding two views in my mind that some may feel are opposite.  I've not always felt that confidence and sought to bring them together but I've come to understand that of the vast universe I have an insignificant knowledge of both and that it would be futile for me to take my limited and incorrect perception of God and His Laws (moral and physical, if they can even be divided like that) and conform it to my misunderstanding of a bunch of observations and mathematical predictions we've made about the world around us. &lt;br /&gt;&lt;br /&gt;Even if I interpret the written and spoken word to be contradictory to established theories of Science I still see value in learning from those theories for even if they happen to be incorrect they provide valuable insight into how God's creations work.&lt;/span&gt;  &lt;span style="color: rgb(0, 0, 0);"&gt;Sometimes it seems both "religious communities" and "intellectual communities" are far from learning the valuable lesson that Ross Spencer learned from Isaac Asimov:&lt;/span&gt; &lt;p style="color: rgb(0, 0, 0);"&gt;&lt;/p&gt;&lt;blockquote style="color: rgb(0, 0, 0);"&gt;&lt;p&gt; I received a similar message from a rather unlikely source early in my career. When I was just out of graduate school, I  attended my first meeting of the American Physical Society in New York City. It was a heady experience, and a highlight was a special event  arranged by the conference organizers: the great science fiction writer Isaac Asimov had been invited to speak to us.&lt;/p&gt;&lt;p&gt; He began by telling  us about something that had happened to him when he was a young student. He was hired to help a historian do research on social  resistance to technological change. Hour after hour he wrote down the  stories he found in books in the university library about people protesting the  invention of things like machines to spin thread and to weave cloth, steam-powered trains, automobiles, airplanes, etc. All of these advances  were perceived by the general public either to be physically dangerous or to be a threat to the livelihoods of workers in trades that were  about to be destroyed by these advances.&lt;/p&gt;&lt;p&gt; He regaled us with these stories for a long time, and they were very funny, but it went on so  long that I began to wonder where he was going. Finally he got to the point. He said that when he started to write science fiction, he  remembered all of this work he had done. So while his fellow writers  were all rhapsodizing about the thrill of rockets and space travel (long before  such things were possible), he wrote a story about how the local  populace showed up at the launch site with torches and pitchforks in opposition  to space travel. Years later, when rockets and travel outside of the earth’s atmosphere became possible, there were protests, and many of Mr.  Asimov’s colleagues were astounded that he had predicted so far in advance that this would occur.&lt;/p&gt;&lt;p&gt; “Why,” Mr. Asimov then asked us,  “among all of these talented and visionary writers, was I the only one who was able to predict that this resistance to change would  occur?” He let us think about the question for an uncomfortably silent minute, then leaned into the microphone and said in an intense voice  that I still vividly remember: “It’s because people are stupid!” And he included himself. He said that if he hadn’t had this idea pounded  into his head daily for several months, he was sure that he wouldn’t have been able to foresee it either.&lt;/p&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-6237524693321580212?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/6237524693321580212/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/06/because-people-are-stupid.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/6237524693321580212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/6237524693321580212'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/06/because-people-are-stupid.html' title='&amp;quot;It&amp;#39;s because people are stupid!&amp;quot;'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-9067587969247094223</id><published>2010-06-15T21:31:00.000-05:00</published><updated>2010-06-26T08:59:52.030-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='politics'/><title type='text'>Laws of the Land</title><content type='html'>&lt;blockquote&gt;He thought it proper however that the true nature of the existing confederacy should be investigated, and he was not anxious to strengthen the foundations on which it now stands.&lt;br /&gt;&lt;div style="text-align: right;"&gt;The Anti-Federalist Papers, Opposition to the New Jersey Plan, pg 81&lt;br /&gt;by James Madison&lt;/div&gt;&lt;/blockquote&gt;On social news sites I came across an interesting article &lt;a href="http://www.usatoday.com/news/opinion/forum/2010-06-15-column15_ST_N.htm"&gt;"Do laws even matter today?"&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Cushioning the consequences of people's bad decisions from hurting themselves makes me wonder sometimes why I bother to be careful.  If everyone else is in debt and has no savings, why should I maintain self-discipline to not get into debt and save for retirement?  The government will cushion the pain for people.  If it can't then it is probably because it is buckling and breaking from its own paternal nature.  At that point what good will my self-discipline have done me if money isn't even worth anything (fiat or otherwise)?&lt;br /&gt;&lt;br /&gt;Another area I find interesting in this the effect of unavoidable law breaking has on the mores of a nation.  I came across a quote from Bastiat (who I've now added every book of his to my reading list) that says&lt;br /&gt;&lt;h3 class="UIIntentionalStory_Message" ft="{&amp;quot;type&amp;quot;:&amp;quot;msg&amp;quot;}"&gt;&lt;blockquote&gt;&lt;span style="font-weight: normal;"&gt;When law and morality contradict  each other, the citizen has the cruel alternative of either  losing his moral sense or losing his respect for the law. These two  evils are of equal consequence, and it would be difficult for a  person to choose between them.&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: right;"&gt;&lt;span style="font-weight: normal;"&gt;The Law, by Bastiat&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;span class="UIStory_Message"&gt;&lt;span class="text_exposed_show"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h3&gt;In college I took a course titled "History of Creativity" to fulfill my Civilization credit.  One of the things we discussed was the affect of prohibition on the mores of the nation.  Overnight the nation became a nation of criminals.  When this happens people turn a blind eye to other crime.  How can they condemn others in the court of law when they are criminals themselves?&lt;br /&gt;&lt;br /&gt;This leads me to wonder about other things like the "War" on Drugs and Speed Limits.  Are we making people tolerant of worst crimes by outlawing these?  If we legalized these and other crimes become the new rage where do we draw the line on legalizing these verse taking a stand for what is right and what is wrong?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-9067587969247094223?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/9067587969247094223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/06/laws-of-land.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/9067587969247094223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/9067587969247094223'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/06/laws-of-land.html' title='Laws of the Land'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14883822.post-2968322520159405684</id><published>2010-06-15T21:13:00.000-05:00</published><updated>2010-06-26T08:59:52.035-05:00</updated><title type='text'>Sweet-and-Sour Bitter Melon</title><content type='html'>&lt;blockquote&gt;But to the hackers it was all part of the system.  It made no human sense, but it had its logic.  It was The Right Thing&lt;br /&gt;&lt;div style="text-align: right;"&gt;Hackers, pg 81, by Steven Levy&lt;br /&gt;&lt;/div&gt;&lt;/blockquote&gt;I've been meaning to start a blog for a while (which can be interpreted as I'll be playing catch up on post ideas for a while).  I plan to have this serve as way to collect my thoughts on things political, spiritual, electronic, and personal.&lt;br /&gt;&lt;br /&gt;As a side benefit I will also get to explore what page 81 says in each of my books.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14883822-2968322520159405684?l=eopage.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://eopage.blogspot.com/feeds/2968322520159405684/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://eopage.blogspot.com/2010/06/sweet-and-sour-bitter-melon.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/2968322520159405684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14883822/posts/default/2968322520159405684'/><link rel='alternate' type='text/html' href='http://eopage.blogspot.com/2010/06/sweet-and-sour-bitter-melon.html' title='Sweet-and-Sour Bitter Melon'/><author><name>Ed Page</name><uri>http://www.blogger.com/profile/14704668441707649581</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_dnuI3IgE4aQ/TCYQ4XmvVeI/AAAAAAAAC6E/-03RZYSaAj0/S220/BuddyIcon-Work.jpg'/></author><thr:total>0</thr:total></entry></feed>
