Using Chandler as an IDE

February 24th, 2006 1 Comment »
I’ve been working on what I’ve been calling MultiBitmapButton for a while now. At first I was using the ports version of wxPython to test a small script that had my class in it. It seemed like a good way to do it, since trying to edit a class in the Chandler code and then waiting for Chandler to start up to test it was slow at best.

This worked quite well at first. I was getting this warning, but it didn’t seem to affect anything:

/opt/local/lib/python2.4/site-packages/wx-2.6-mac-unicode/wx/_core.py:13155: UserWarning: wxPython/wxWidgets release number mismatch
warnings.warn(”wxPython/wxWidgets release number mismatch“)
This meant I was running wxPython version 2.6.1, but was using wxWidgets (the C++ library that wxPython wraps) version 2.6.2.

I had a window showing up, and was using sizers with normal buttons just to verify that everything was okay. But then I tried to add a MultiBitmapButton. *Boom*, the script would fail after flashing a window with what looked like the error info I needed. So I tried using Komodo, a Python IDE. You can see what it looked like when it hit the error if you click on the image below.

Komodo debugging in action
Komodo debugging my script
(click for larger version)

It told me that the error was:

Looking at object failed - exceptions.AttributeError: ‘Frame’ object has no attribute ‘this’

Knowing what I do about C++ and how it uses “this”, I knew that this meant it was something wayyyy down deep, and was probably a result of the release mismatch between wxWidgets and wxPython. So, I tried to update my ports install of wxPython to v 2.6.1, but it doesn’t look like ports has updated yet.

You know, I’ve been meaning to find out how to set up a port myself so I could contribute some they are missing. In this case, I could update wxPython myself. But I haven’t, so I didn’t, so oh well.

Now, I had heard about this shell you could bring up in Chandler via the “Test” menu. Given what I knew about Python and modules etc., I figured that it should be possible to use that shell to at least paste in my code and get some kind of feedback. What the heck.

Wow, did I ever hit the motherload.

I started up Chandler and chose the menu item “Test→Show Python Shell”. I got a terminal-ish looking window with the usual “>>> ” prompt. So, I started to type in some simple code to create a wx Frame, as a proof of concept. I noticed right away that this wasn’t just a terminal-ish window!

pyshell in action

PyShell is fully interactive, and gives you a lot of help as you type your code. Code completion, argument templates - the works. Along with this you have the native Python help facility, which you get to by just entering “help()” and hitting return:

>>> help()

Welcome to Python 2.4! This is the online help utility.

If this is your first time using Python, you should definitely check out the tutorial on the Internet at http://www.python.org/doc/tut/.

Enter the name of any module, keyword, or topic to get help on writing Python programs and using Python modules. To quit this help utility and return to the interpreter, just type “quit”.

To get a list of available modules, keywords, or topics, type “modules”, “keywords”, or “topics”. Each module also comes with a one-line summary of what it does; to list the modules whose summaries contain a given word such as “spam”, type “modules spam”.

help>

Wow.

Now, I’ve managed to osmose a few Python tricks from Jeremy and others. Key is the “dir” command, which tells you a lot about an object, module, what have you. But I didn’t realize until I read that help blurb that I could get a list of all modules from which to start. Woah. So.. I typed “modules” and stood back!

Please wait a moment while I gather a list of all available modules...

Audio_mac           _bsddb              fpformat            repository (package)
BaseHTTPServer      _builtinSuites (package) ftplib              repr
Bastion             _codecs             gc                  resource
CGIHTTPServer       _codecs_cn          gensuitemodule      rexec
Canvas              _codecs_hk          gestalt             rfc822
Carbon (package)    _codecs_iso2022     getopt              rgbimg
Chandler            _codecs_jp          getpass             rlcompleter
CodeWarrior (package) _codecs_kr          gettext             robotparser
ColorPicker         _codecs_tw          glob                samples (package)
ConfigParser        _csv                gopherlib           sched
Cookie              _curses             grp                 select
Dialog              _curses_panel       gzip                sets
DocXMLRPCServer     _heapq              heapq               sgmllib
EasyDialogs         _hotshot            hmac                sha
Explorer (package)  _locale             hotshot (package)   shelve
FileDialog          _multibytecodec     htmlentitydefs      shlex
Finder (package)    _random             htmllib             shutil
FixTk               _socket             httplib             signal
FrameWork           _sre                i18n (package)      site
HTMLParser          _ssl                ic                  smtpd
IN                  _strptime           icglue              smtplib
M2Crypto (package)  _symtable           icopen              sndhdr
MacOS               _testcapi           idlelib (package)   socket
MimeWriter          _threading_local    ihooks              sre
MiniAEFrame         _weakref            imageop             sre_compile
Nav                 aepack              imaplib             sre_constants
Netscape (package)  aetools             imghdr              sre_parse
OSATerminology      aetypes             imp                 stat
PixMapWrapper       aifc                imputil             statcache
PyICU               amazon (package)    inspect             statvfs
PyICU_bases         anydbm              itertools           string
PyICU_calendar      applesingle         jabber              stringold
PyICU_collator      appletrawmain       keyword             stringprep
PyICU_dateformat    appletrunner        libxml2             strop
PyICU_errors        application (package) libxml2mod          struct
PyICU_format        argvemulator        linecache           subprocess
PyICU_iterators     array               locale              sunau
PyICU_locale        asynchat            logging (package)   sunaudio
PyICU_numberformat  asyncore            logilab (package)   symbol
PyLucene            atexit              macerrors           symtable
Queue               audiodev            macfs               sys
SOAPpy (package)    audioop             macostools          syslog
ScrolledText        autoGIL             macpath             tabnanny
SimpleDialog        base64              macresource         tarfile
SimpleHTTPServer    bdb                 macurl2path         telnetlib
SimpleXMLRPCServer  bgenlocations       mailbox             tempfile
SocketServer        binascii            mailcap             terminalcommand
StdSuites (package) binhex              markupbase          termios
StringIO            bisect              marshal             textwrap
SystemEvents (package) bsddb (package)     math                this
Terminal (package)  bsddb185            md5                 thread
Tix                 buildtools          mhlib               threading
Tkconstants         bundlebuilder       mimetools           time
Tkdnd               bz2                 mimetypes           timeit
Tkinter             cPickle             mimify              timing
UserDict            cStringIO           mmap                tkColorChooser
UserList            calendar            modulefinder        tkCommonDialog
UserString          cfmfile             multifile           tkFileDialog
WASTEconst          cgi                 mutex               tkFont
_AE                 cgitb               netrc               tkMessageBox
_AH                 chandlerdb (package) new                 tkSimpleDialog
_App                chunk               nis                 toaiff
_CF                 cmath               nntplib             token
_CG                 cmd                 ntpath              tokenize
_CarbonEvt          code                nturl2path          tools (package)
_Cm                 codecs              opcode              trace
_Ctl                codeop              operator            traceback
_Dlg                collections         optik (package)     tty
_Drag               colorsys            optparse            turtle
_Evt                commands            os                  twisted (package)
_File               compileall          os2emxpath          types
_Fm                 compiler (package)  osaf (package)      tzparse
_Folder             cookielib           parser              unicodedata
_Help               copy                pdb                 unittest
_IBCarbon           copy_reg            photos (package)    urllib
_Icn                crypt               pickle              urllib2
_LWPCookieJar       csv                 pickletools         urlparse
_Launch             curses (package)    pimp                user
_List               datetime            pipes               util (package)
_Menu               dateutil (package)  pkgutil             uu
_Mlte               dbhash              platform            version
_MozillaCookieJar   dbm                 plistlib            videoreader
_OSA                decimal             popen2              vobject (package)
_PyICU              difflib             poplib              warnings
_PyICU_bases        dircache            posix               wave
_PyICU_calendar     dis                 posixfile           weakref
_PyICU_collator     distutils (package) posixpath           webbrowser
_PyICU_dateformat   doctest             pprint              whichdb
_PyICU_errors       drv_libxml2         profile             whrandom
_PyICU_format       dumbdbm             pstats              wx (package)
_PyICU_iterators    dummy_thread        pty                 wxPython (package)
_PyICU_locale       dummy_threading     pwd                 xdrlib
_PyICU_numberformat email (package)     py_compile          xml (package)
_PyLucene           encodings (package) pychecker (package) xmllib
_Qd                 epydoc (package)    pyclbr              xmlrpclib
_Qdoffs             errno               pydoc               xmlstream
_Qt                 exceptions          pyexpat             xxsubtype
_Res                fcntl               pylint (package)    zanshin (package)
_Scrap              feeds (package)     quopri              zipfile
_Snd                filecmp             random              zipimport
_TE                 fileinput           re                  zlib
_Win                findertools         reconvert           zope (package)
__builtin__         flickr (package)    regex               
__future__          fnmatch             regex_syntax        
_bisect             formatter           regsub              

Enter any module name to get more help.  Or, type "modules spam" to search
for modules whose descriptions contain the word "spam".

*Whew*!

I think I’m really starting to like this.
:-D

Third-Party Packages and Mac OS X

February 23rd, 2006 No Comments »
Huxley, the Darwin mascot
Huxley, the Darwin mascot
There are useful things out there that, on Linux and BSD, are installed as packages in the OS. Versions of Python or Ruby, Gnu gcj, etc. Some of these have true Mac packages (ending in “.pkg” or “.mpkg”), which install in various places in the file system like /usr/bin, /Applications, etc.

However, there are two major packaging systems that:
(a) have a large number of packages, and
(b) are fairly easy to use on the command line.

Fink These are DarwinPorts (or just “ports”), and Fink. Of the two, I always use ports.

ports To install, say, “pygame“, using ports, you would simply type this command into a terminal (Terminal or iTerm will do nicely):

sudo port install py-game

Obviously, before doing this you need to *install* ports. Fortunately, there is (irony of ironies) a pkg package you can download and double-click to do just that.

One recent thing I’ve done is to install some of Gnome onto my Mac. Then I copied /etc/X11/xinit/xinitrc to ~/.xinitrc and changed the last two lines thusly:

#exec quartz-wm
exec gnome-session

Commenting out the quartz window manager allows Gnome to take over. However, I also had to change the preferences for my X11 app to allow “Enter Full Screen” under Preference➞Output. Very cool, my PowerBook now feels like a Linux laptop! And I can continue to use ports to install many more Gnome (and KDE!) applications.

Now, the reason I am going on at length about this is that it would be truly wonderful if, instead of having a lot of libraries custom-built for it, Chandler could use libraries on the OS, put there by ports or fink, then Chandler could be a lot more light-weight.

Unfortunately, at this point in time, Chandler is dependent upon features that are as yet unavailable in the released versions of most of these libraries.

Lisa on IT Conversations

February 22nd, 2006 No Comments »
Lisa The Dec 14 2005 episode of IT Conversations includes a chat with Lisa Dusseault, a fellow OSAF worker. Lisa is very big on CalDAV, an offshoot of WebDAV with calendaring functionality. You can read RFC 2518, of which Lisa is the editor.

Lisa’s also been involved with WebDAV and IMAP extensions.

“affordances”

February 20th, 2006 No Comments »
This word is used quite a bit in OSAF correspondence. It refers to UI elements that hint at functionality. I think a better, easier-to-understand word or phrase would be better suited to discussion. Maybe “cue” or “UI element”. It varies with context.

Recent examples and better phrasing (I’m trying not to pick on anyone here…):
before: I wish that the “Appears in:” affordance was at the top of the column
after: I wish that the “Appears in:” list was at the top of the column before: The difficulty is that the UI affordances appropriate for 1,2 and 3 are potentially very different after: The difficulty is that the UI’s appropriate for 1,2 and 3 are potentially very different before: Interaction affordances after: UI elements before: We need to iterate on what affordances we provide to help users understand [..] after: We need to try several different UI designs to help users understand [..]

It’s a buzzword, and it’s one that encumbers comprehension.

A mental stumbling block.

Begone.

How to change wx tarball versions

February 17th, 2006 No Comments »
Overheard in IRC.. :-)

[14:51] aparna: mikeal-fu: you want to try changing the wx tarball to relver 35 and try?
[14:51] mikeal-fu: i haven’t done it before
[14:51] mikeal-fu: but I’ll try
[14:51] ovaltofu: here are the steps mikeal-fu:
[14:51] ovaltofu: change wxPython in chandler/Makefile to 35
[14:52] ovaltofu: then remove the wsPython-*-.inst files in release
[14:52] ovaltofu: make wxPython (in chandler)
[14:52] heikkit: ovaltofu, mikeal-fu: just to be sure, might want to rm wx* in site-packages before the make command

Just thought this might prove useful later..

Resolved: that the Markup Bar does not need to be a “toolbar”

February 15th, 2006 No Comments »
After looking into things a bit, I’ve found out that the term “toolbar” means different things to different platforms.

On the Mac, there is one (1) toolbar per window, and it lives directly under the window’s title bar. No ifs, ands or buts.

Meanwhile, on Windows, a toolbar can be anywhere, can have customizable tools, can be dragged out of a window sometimes, and turned into its own little palette window.

Linux pretty much follows Windows in this regard.

So, we have an unfortunate conflict of terms here. I would say that the Windows “toolbar” is more like a “pane”, or perhaps the Mac “toolbar” is really a “windowbar”. I dunno. But the two “toolbars” need to be divorced from each other in terms of implementation.


Hm, went on a bit of a tangent there. I was going to say that after talking with Mimi, Sheila, Philippe and Bryan, I am going to remove the “toolbar” from underneath the Markup Bar buttons. This should make life much easier, because this makes them just a bunch-o’-buttons.

Now I can make my own button class and be a happy camper.

wxRuby

February 15th, 2006 No Comments »
wxRuby Hey, I just found out that there is a wxRuby! This is interesting because Chandler is a big wxPython app, and I’ve always been a fan of Ruby myself.

I wonder if the two could be made to talk to each other? Maybe extend Chandler to handle other languages.

Developers tend to be very protective of their language-of-choice.

Enhancing buttons in the Markup bar

February 7th, 2006 No Comments »
I’m looking at making the buttons at the top of the sidebar (which area is known as “the markup bar”). I looked at wxWidgets and wxPython, and I think the best approach is to just make a new Python class that inherits from wx.BitmapButton and adds functionality.

Multiple States

The first feature required is having more than one normal “state”. That is, when the button is not being pressed or disabled or what have you, it needs to have different representations. For example, the “mail” button need to represent the states of “this item can be turned into an email item” and “this item *is* an email item”. This is multiplied by the usual “pressed” and “disabled” versions of each state.

I figure this is the easiest part to implement, as I can just subclass wx.BitmapButton and store a series of bitmaps, with a setState() method to set which bitmap to use at any particular moment. It’s a pretty thin wrapper around just calling the SetBitmap{Disabled,Focus,Selected} methods of wxBitmapButton.

Note that John warned me that there is a bug for Windows where wxBitmapButton can peg the CPU if you’re not careful - it seems to continually redraw the button. I could see how that could happen if there was some sort of loop in the bitmap-changing logic combined with the refresh logic. I will keep an eye out for that.

Roll-Over

The second feature is to have roll-over state, so that when the mouse moves over the button, it is drawn in some higlighted manner, common to today’s applications.

The obvious way to implement this is to use BEGIN_EVENT_TABLE et al to add support for the wxMouseEvents EVT_ENTER_WINDOW and EVT_LEAVE_WINDOW. I’m not sure if the “WINDOW’ mentioned means the window the control is in, or the control itself. If the former, then it may require using EVT_MOTION instead, and checking for entering/leaving the control manually.

Menus

The third feature, which is not an immediate requirement is to have a menu drop down, presumably if the button is clicked and held long enough (like the “back” buttonin most browsers), or perhaps a specific area of the button is clicked (perhaps a small down-arrow tothe right?), or just if the button has items to display in a menu (like folders in a browsers link bar). This obviously need more thinking.

Sounding off on design doc in yesterday’s dev meeting

February 3rd, 2006 No Comments »
In yesterday’s dev meeting, we were talking about what we should do to address points made in the 0.6 debrief. I noticed quite a few items relating to design documents and thought many of them could be addressed by having one central design document from which everything else flowed. However, I think I came off as a bit to harsh in the meeting. Some of this is because of phoning in to the meeting, I think. You feel like you have this limited chunk of bandwidth, and you should spend it to make your point as clearly and forcefully as possible. Maybe a bit too forcefully.

I was going to mention that I thought I was a bit pedantic in my blurb, but it didn’t happen. So if anyone from the design team sees this - sorry if I seemed to be attacking the design team. I really didn’t mean to. But I think that’s how it sounded. Alas.

tags are collections are tags?

February 1st, 2006 No Comments »
Off and on people have been mentioning tags for Chandler items in the design list. It made me think more about “collections” and their place in Chandler.

Items in Chandler belong to one or more collections.
Items in Chandler have zero or more attributes.
Items in Chandler would have zero or more tags.

Attributes are different from collections and tags in that they have two parts: the key and the value.

The only difference between tags and colelctions is the UI. An item can have one or more tags and be in one or more collections. I find this confusing in how I use Chandler.

Now, to be sure, collections have other uses, like being shareable. However, I am wondering: should items be restricted to being in one collection? Otherwise the mental model is a bit confused between tags and collections.

On the other hand, it’s nice to be able to have items in two collections, each of which can have different sharing setups. But I wonder, should the concept of “tags” and “collections” be merged?


If it’s not clear, this entry is somewhat stream-of-conciousness, so feel free to bail.
What about making tags that are “heavy” enough to be shared? Then the UI would be the only distinction between tags and collections.

Okay, that’s enough for now.