Gnome Applets.

Being an avid Ubuntu user, I wanted to tinker in building for the Gnome interface.  An applet was the perfect idea but a tutorial on the internet was hard to find.  I found a few like these that are in C, which I’m fond of C but for rapid development and tinkering, Python works much better.  Besides, that is my primary programming language and kindly, Ubuntu came with all the required modules to build in this way.  Most tutorials for Python were out of date.  One of the best I found in Python was this one and my personal favorite which shows a good use of classes.

Onto the tutorial!

The first thing you need to do is build a server file.  This will go to /usr/lib/bonobo/servers with root access.  The reason for this file is for Gnome to be able find your file and set it as an applet.   The lines to pay attention to are:

Line 4:          This is the full path to your source code file.
Lines 9-10:  Name and describe your applet.
Line 20-23: These are the options you can set for the applet browser.

<oaf_info>
    <oaf_server iid="OAFIID:SampleApplet_Factory"
        type="exe"
        location="/home/zbert/Desktop/testing/py/applet.py">
        <oaf_attribute name="repo_ids" type="stringv">
            <item value="IDL:Bonobo/GenericFactory:1.0"/>
            <item value="IDL:Bonobo/Unknown:1.0"/>
        </oaf_attribute>
        <oaf_attribute name="name" type="string" value="Sample Applet Factory"/>
        <oaf_attribute name="description" type="string" value="Sample Applet's Factory that launches the applet"/>
    </oaf_server>
    <oaf_server iid="OAFIID:SampleApplet"
        type="factory"
        location="OAFIID:SampleApplet_Factory">
        <oaf_attribute name="repo_ids" type="stringv">
            <item value="IDL:GNOME/Vertigo/PanelAppletShell:1.0"/>
            <item value="IDL:Bonobo/Control:1.0"/>
            <item value="IDL:Bonobo/Unknown:1.0"/>
        </oaf_attribute>
        <oaf_attribute name="name" type="string" value="Sample Applet"/>
        <oaf_attribute name="description" type="string" value="Sample applet's description."/>
        <oaf_attribute name="panel:category" type="string" value="Utility"/>
        <oaf_attribute name="panel:icon" type="string" value="gnome-laptop.png"/>
    </oaf_server>
</oaf_info>

Now with the server file in place, it’s time to build the applet. I used a picture to show my applet as a small 16×16 PNG smiley face.   As for the coding, I’ve commented what needs to be done here.

#!/usr/bin/env python
### NORMAL IMPORTS
import sys
import gtk
import pygtk
import gnomeapplet

pygtk.require('2.0')

### CREATE A MENU WITH XML
def create_menu(applet):
    xml = """
    <popup name="button3">
        <menuitem name="Item 1" verb="Networks" label="_Networks...."
            pixtype = "stock" pixname="gtk-properties"/>
        <menuitem name="Item 2" verb="Help" label="_Help"
            pixtype = "stock" pixname="gtk-help"/>
        <separator/>
        <menuitem name="Item 3" verb="About" label="_About..."
            pixtype = "stock" pixname="gnome-stock-about"/>
    </popup>
    """
    verbs = [('Networks',show_networks), ('Help',show_help), ('About',show_about)]
    applet.setup_menu(xml, verbs, None)

### WHAT HAPPENS WHEN MENU ITEM IS CLICKED
def show_about(*arguments):
    print(arguments)

### THE ASTERIK ALLOWS MULTIPLE ARGUMENTS TO BE PASSED
def show_networks(*arguments):
    print(arguments)

### ALL OF THESE SHOW IN THE DEBUG (-d) OPTION
def show_help(*arguments):
    print(arguments)

### WHERE IT ALL HAPPENS
def applet_factory(applet, iid):
    # CREATE THE XML MENU
    create_menu(applet)
    # CREATE AN IMAGE OBJECT
    im = gtk.Image()
    # SET THE FILE FOR THE IMAGE
    im.set_from_file("/home/zbert/Desktop/testing/py/face2.png")
    # ENABLE TRANSPARENCY
    applet.set_background_widget(applet)
    # CREATE AN EVENT FOR CLICKING THE IMAGE
    applet.connect('button-press-event',button_press)
    # ADD IT ALL TO THE APPLET
    applet.add(im)
    # SHOW IT!
    applet.show_all()
    # DEBUG EVENT
    print('Factory started')
    return True

### CREATE A DIALOG TO POP UP WHEN APPLET IS CLICKED
def test(*arguments):
    print(arguments)
    dia = gtk.Dialog("Message",None,gtk.DIALOG_MODAL)
    lbl = gtk.Label("this is a message")
    dia.vbox.pack_start(lbl)
    lbl.show()
    dia.run()
    dia.connect("destroy",dia.destroy)

### HANDLE THE IMAGE CLICK
def button_press(button, event):
    # LEFT BUTTON ACTIVATES THE CUSTOM MENU
    if event.button == 1:
        print "button 1"
        # CREATE A CUSTOM MENU
        m = gtk.Menu()
        i = gtk.MenuItem("Hello")
        i.show()
        # CONNECT THIS MENU ITEM TO THE DIALOG
        i.connect("activate",test,"Hello")
        m.append(i)
        # FINISH THE POPUP MENU
        m.popup(None, None, None, event.button, event.time, None)
    # RIGHT BUTTON ACTIVATES THE STANDARD MENU
    elif event.button == 2:
        # DEBUG
        print "button 2"

### STANDARD ENTRY
if __name__ == '__main__':
    # DEBUG
    print('Starting factory')
    # RUN THE APPLET AS A GTK WINDOW IN DEBUG (-d) MODE
    if len(sys.argv) > 1 and sys.argv[1] == '-d': #
        mainWindow = gtk.Window()
        mainWindow.set_title('Applet window')
        mainWindow.connect('destroy',gtk.main_quit)
        applet = gnomeapplet.Applet()
        applet_factory(applet, None)
        applet.reparent(mainWindow)
        mainWindow.show_all()
        gtk.main()
        sys.exit()
    # LET GNOME TAKE CARE OF IT AS AN APPLET
    else:
        gnomeapplet.bonobo_factory('OAFIID:SampleApplet_Factory',
            gnomeapplet.Applet.__gtype__,
            'Sample Applet', '0.1',
            applet_factory)

You can see in these pictures how the applet sits like any other in the corner.  A left click will bring up our custom coded menu with one selection, ‘Hello’ which when clicked brings up a GTK Dialog that is made in the button_press() event.  If you right click, you get the standard menu, plus our XML menu which, when in Debug (-d) mode, you will see the arguments sent by a click outputted in your terminal.  As I mentitoned, there are a handful of great resources for this that detail current Python modules with information on setting this up as I did or in a class for bigger projects.  I hope this tutorial has been helpful, and let me know what you think of these lessons with the comments interface!

VirtualBox – USB Devices

As a military member, I am issued a CAC card, which is a smart card carrying a PKI certificate for logging onto web interfaces and signing documents.  As  Linux user, I’ve been frustrated by the Windows specifics for utilizing CAC cards and have been happy to find alternatives through libcoolkey and pcsc_lite.  These work well with Firefox and I can log onto web interfaces just fine, but have not had a viable, Linux solution to signing documents.  In the military, we use an IBM product, PureEdge to utilize our forms which are *.xfdl documents.

The solution I have come to, although not purely Linux, allows me to sign documents without rebooting to another OS.  For testing purposes, I have had Windows XP running in VirtualBox so I decided to utilize that.  The problem came in that I was using virtualbox-ose and needed to not use the open source version for access to the USB devices.   The process then is relatively and well documented with simple Google searches:

  1. Set vboxuser in the user’s group.
  2. Configure your USB devices (in this case the CAC card reader) to be detected by the guest OS.
  3. Run the guest OS and install ActivClient 6.0 and Silinas ApproveIt to be able to sign *.xfdl documents.

See, simple… hmm, that sounds too close to Windows 7 add but I promise it is not!  I may be a PC but Windows 7 was NOT my idea!!

Update.

So for anyone reading this blog, I am still here, just have not added anything this week.  I’m working and have not been able to update the blog but I will soon have links and information to my linux Cribbage game.  This is near completion and I have written it using pygtk.  It is using card and game modules that I had designed for a text based run of the program and figuring no one would want to use the text based, I’ve switched to a GTK interface, which is obviously, much better.