NOT FULLY WORKING, got the main keyboard showing up. Just show the secondary one...
authorEd Page <eopage@byu.net>
Wed, 7 Jul 2010 01:20:23 +0000 (20:20 -0500)
committerEd Page <eopage@byu.net>
Wed, 7 Jul 2010 01:20:23 +0000 (20:20 -0500)
35 files changed:
src/ejpi.glade [deleted file]
src/ejpi_cli.py [deleted file]
src/ejpi_glade.py [deleted file]
src/ejpi_qt.py
src/gtk_toolbox.py [deleted file]
src/gtkhistory.py [deleted file]
src/hildonize.py [deleted file]
src/libraries/gtkpie.py [deleted file]
src/libraries/gtkpieboard.py [deleted file]
src/libraries/images/alt.png [deleted file]
src/libraries/images/arrows.png [deleted file]
src/libraries/images/backspace.png [deleted file]
src/libraries/images/clear.png [deleted file]
src/libraries/images/control.png [deleted file]
src/libraries/images/newline.png [deleted file]
src/libraries/images/shift.png [deleted file]
src/libraries/images/space.png [deleted file]
src/libraries/images/super.png [deleted file]
src/libraries/images/symbols.dia [deleted file]
src/libraries/images/tab.png [deleted file]
src/libraries/qtpie.py
src/libraries/qtpieboard.py [new file with mode: 0755]
src/plugin_utils.py
src/plugins/images/alt.png [new file with mode: 0644]
src/plugins/images/arrows.png [new file with mode: 0644]
src/plugins/images/backspace.png [new file with mode: 0644]
src/plugins/images/clear.png [new file with mode: 0644]
src/plugins/images/control.png [new file with mode: 0644]
src/plugins/images/newline.png [new file with mode: 0644]
src/plugins/images/shift.png [new file with mode: 0644]
src/plugins/images/space.png [new file with mode: 0644]
src/plugins/images/super.png [new file with mode: 0644]
src/plugins/images/symbols.dia [new file with mode: 0644]
src/plugins/images/tab.png [new file with mode: 0644]
src/qhistory.py

diff --git a/src/ejpi.glade b/src/ejpi.glade
deleted file mode 100644 (file)
index fe1f0ab..0000000
+++ /dev/null
@@ -1,272 +0,0 @@
-<?xml version="1.0"?>
-<glade-interface>
-  <!-- interface-requires gtk+ 2.16 -->
-  <!-- interface-naming-policy toplevel-contextual -->
-  <widget class="GtkWindow" id="mainWindow">
-    <property name="title" translatable="yes">Cluttered Calc</property>
-    <property name="default_width">800</property>
-    <property name="default_height">480</property>
-    <child>
-      <widget class="GtkVBox" id="mainLayout">
-        <property name="visible">True</property>
-        <child>
-          <widget class="GtkMenuBar" id="mainMenubar">
-            <property name="visible">True</property>
-            <child>
-              <widget class="GtkMenuItem" id="fileMenuItem">
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">_File</property>
-                <property name="use_underline">True</property>
-                <child>
-                  <widget class="GtkMenu" id="fileMenu">
-                    <property name="visible">True</property>
-                    <child>
-                      <widget class="GtkImageMenuItem" id="quitMenuItem">
-                        <property name="label">gtk-quit</property>
-                        <property name="visible">True</property>
-                        <property name="use_underline">True</property>
-                        <property name="use_stock">True</property>
-                        <signal name="activate" handler="on_calculator_quit"/>
-                      </widget>
-                    </child>
-                  </widget>
-                </child>
-              </widget>
-            </child>
-            <child>
-              <widget class="GtkMenuItem" id="editMenuItem">
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">_Edit</property>
-                <property name="use_underline">True</property>
-                <child>
-                  <widget class="GtkMenu" id="editMenuIte">
-                    <property name="visible">True</property>
-                    <child>
-                      <widget class="GtkImageMenuItem" id="copyMenuItem">
-                        <property name="label">gtk-copy</property>
-                        <property name="visible">True</property>
-                        <property name="use_underline">True</property>
-                        <property name="use_stock">True</property>
-                      </widget>
-                    </child>
-                    <child>
-                      <widget class="GtkImageMenuItem" id="copyEquationMenuItem">
-                        <property name="label" translatable="yes">Copy Equation</property>
-                        <property name="visible">True</property>
-                        <property name="use_stock">False</property>
-                        <child internal-child="image">
-                          <widget class="GtkImage" id="image1">
-                            <property name="visible">True</property>
-                            <property name="stock">gtk-copy</property>
-                          </widget>
-                        </child>
-                      </widget>
-                    </child>
-                    <child>
-                      <widget class="GtkImageMenuItem" id="pasteMenuItem">
-                        <property name="label">gtk-paste</property>
-                        <property name="visible">True</property>
-                        <property name="use_underline">True</property>
-                        <property name="use_stock">True</property>
-                        <signal name="activate" handler="on_paste"/>
-                      </widget>
-                    </child>
-                    <child>
-                      <widget class="GtkImageMenuItem" id="deleteMenuItem">
-                        <property name="label">Clear _History</property>
-                        <property name="visible">True</property>
-                        <property name="use_underline">True</property>
-                        <property name="use_stock">False</property>
-                        <signal name="activate" handler="on_clear_history"/>
-                        <child internal-child="image">
-                          <widget class="GtkImage" id="image2">
-                            <property name="visible">True</property>
-                            <property name="stock">gtk-delete</property>
-                          </widget>
-                        </child>
-                      </widget>
-                    </child>
-                  </widget>
-                </child>
-              </widget>
-            </child>
-            <child>
-              <widget class="GtkMenuItem" id="helpMenuItem">
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">_Help</property>
-                <property name="use_underline">True</property>
-                <child>
-                  <widget class="GtkMenu" id="helpMenu">
-                    <property name="visible">True</property>
-                    <child>
-                      <widget class="GtkImageMenuItem" id="aboutMenuItem">
-                        <property name="label">gtk-about</property>
-                        <property name="visible">True</property>
-                        <property name="use_underline">True</property>
-                        <property name="use_stock">True</property>
-                        <signal name="activate" handler="on_about"/>
-                      </widget>
-                    </child>
-                  </widget>
-                </child>
-              </widget>
-            </child>
-          </widget>
-          <packing>
-            <property name="expand">False</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-        <child>
-          <widget class="GtkHBox" id="calculatorLayout">
-            <property name="visible">True</property>
-            <child>
-              <widget class="GtkVBox" id="historyLayout">
-                <property name="visible">True</property>
-                <child>
-                  <widget class="GtkScrolledWindow" id="scrollingHistory">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="hscrollbar_policy">never</property>
-                    <property name="vscrollbar_policy">automatic</property>
-                    <property name="window_placement">bottom-left</property>
-                    <property name="window_placement_set">True</property>
-                    <child>
-                      <widget class="GtkTreeView" id="historyView">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="headers_visible">False</property>
-                        <property name="reorderable">True</property>
-                        <property name="rules_hint">True</property>
-                        <property name="enable_search">False</property>
-                      </widget>
-                    </child>
-                  </widget>
-                  <packing>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkEventBox" id="errorEventBox">
-                    <property name="visible">True</property>
-                    <property name="events">GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
-                    <child>
-                      <widget class="GtkHBox" id="errorBox">
-                        <property name="visible">True</property>
-                        <child>
-                          <widget class="GtkImage" id="errorImage">
-                            <property name="visible">True</property>
-                            <property name="stock">gtk-dialog-error</property>
-                          </widget>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">False</property>
-                            <property name="position">0</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <widget class="GtkLabel" id="errorDescription">
-                            <property name="visible">True</property>
-                            <property name="use_markup">True</property>
-                            <property name="ellipsize">end</property>
-                            <property name="single_line_mode">True</property>
-                          </widget>
-                          <packing>
-                            <property name="position">1</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <widget class="GtkImage" id="errorClose">
-                            <property name="visible">True</property>
-                            <property name="stock">gtk-close</property>
-                          </widget>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="position">2</property>
-                          </packing>
-                        </child>
-                      </widget>
-                    </child>
-                  </widget>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkEntry" id="entryView">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="editable">False</property>
-                    <property name="invisible_char">&#x25CF;</property>
-                  </widget>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="position">2</property>
-                  </packing>
-                </child>
-              </widget>
-              <packing>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkVBox" id="functionLayout">
-                <property name="visible">True</property>
-                <child>
-                  <widget class="GtkButton" id="keyboardSelectionButton">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
-                  </widget>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkHBox" id="pluginKeyboard">
-                    <property name="visible">True</property>
-                    <child>
-                      <placeholder/>
-                    </child>
-                  </widget>
-                  <packing>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkHSeparator" id="hseparator1">
-                    <property name="visible">True</property>
-                  </widget>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="position">2</property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkHBox" id="mainKeyboard">
-                    <property name="visible">True</property>
-                    <child>
-                      <placeholder/>
-                    </child>
-                  </widget>
-                  <packing>
-                    <property name="position">3</property>
-                  </packing>
-                </child>
-              </widget>
-              <packing>
-                <property name="position">1</property>
-              </packing>
-            </child>
-          </widget>
-          <packing>
-            <property name="position">1</property>
-          </packing>
-        </child>
-      </widget>
-    </child>
-  </widget>
-</glade-interface>
diff --git a/src/ejpi_cli.py b/src/ejpi_cli.py
deleted file mode 100755 (executable)
index 8fc34c3..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-#!/usr/bin/env python
-
-import os
-
-import plugin_utils
-import history
-
-
-PLUGIN_SEARCH_PATHS = [
-       os.path.join(os.path.dirname(__file__), "plugins/"),
-]
-
-
-OPERATIONS = {}
-
-CONSTANTS = {}
-
-
-class CliEntry(object):
-
-       def __init__(self):
-               self.value = ""
-
-       def set_value(self, value):
-               self.value = value
-
-       def get_value(self):
-               return self.value
-
-       def clear(self):
-               self.value = ""
-
-
-def parse_command(userInput):
-       return OPERATIONS[userInput.strip()]
-
-
-def ambiguous_parse(calc, userInput):
-       try:
-               Node = parse_command(userInput)
-               calc.apply_operation(Node)
-               return True
-       except KeyError:
-               return False
-
-
-def repl():
-       entry = CliEntry()
-       stack = history.CalcHistory()
-       rpnCalc = history.RpnCalcHistory(
-               stack,
-               entry, history.ErrorWarning(),
-               CONSTANTS, OPERATIONS
-       )
-       while True:
-               userInput = raw_input(">")
-               isUsed = ambiguous_parse(rpnCalc, userInput)
-               if not isUsed:
-                       entry.set_value(userInput)
-                       rpnCalc.push_entry()
-
-               if 0 < len(stack):
-                       node = stack.peek()
-                       print "\t= %s" % str(node)
-                       print "\t~= %s" % str(node.simplify(**CONSTANTS))
-
-
-def main():
-       constantPlugins = plugin_utils.ConstantPluginManager()
-       constantPlugins.add_path(*PLUGIN_SEARCH_PATHS)
-       constantPlugins.enable_plugin(constantPlugins.lookup_plugin("Builtin"))
-       CONSTANTS.update(constantPlugins.constants)
-
-       operatorPlugins = plugin_utils.OperatorPluginManager()
-       operatorPlugins.add_path(*PLUGIN_SEARCH_PATHS)
-       operatorPlugins.enable_plugin(operatorPlugins.lookup_plugin("Builtin"))
-       OPERATIONS.update(operatorPlugins.operators)
-
-       repl()
-
-if __name__ == "__main__":
-       main()
diff --git a/src/ejpi_glade.py b/src/ejpi_glade.py
deleted file mode 100755 (executable)
index 5dc3554..0000000
+++ /dev/null
@@ -1,476 +0,0 @@
-#!/usr/bin/python
-
-"""
-Some useful things on Maemo
-@li http://maemo.org/api_refs/4.1/libosso-2.16-1/group__Statesave.html
-@li http://maemo.org/api_refs/4.1/libosso-2.16-1/group__Autosave.html
-"""
-
-
-from __future__ import with_statement
-
-
-import sys
-import gc
-import os
-import string
-import logging
-import warnings
-
-import gtk
-import gtk.glade
-
-import hildonize
-import gtk_toolbox
-
-import constants
-from libraries import gtkpie
-from libraries import gtkpieboard
-import util.misc as misc_utils
-import plugin_utils
-import history
-import gtkhistory
-
-
-_moduleLogger = logging.getLogger(__name__)
-
-PLUGIN_SEARCH_PATHS = [
-       os.path.join(os.path.dirname(__file__), "plugins/"),
-]
-
-PROFILE_STARTUP = False
-
-
-class ValueEntry(object):
-
-       def __init__(self, widget):
-               self.__widget = widget
-               self.__actualEntryDisplay = ""
-
-       def get_value(self):
-               value = self.__actualEntryDisplay.strip()
-               if any(
-                       0 < value.find(whitespace)
-                       for whitespace in string.whitespace
-               ):
-                       self.clear()
-                       raise ValueError('Invalid input "%s"' % value)
-               return value
-
-       def set_value(self, value):
-               value = value.strip()
-               if any(
-                       0 < value.find(whitespace)
-                       for whitespace in string.whitespace
-               ):
-                       raise ValueError('Invalid input "%s"' % value)
-               self.__actualEntryDisplay = value
-               self.__widget.set_text(value)
-
-       def append(self, value):
-               value = value.strip()
-               if any(
-                       0 < value.find(whitespace)
-                       for whitespace in string.whitespace
-               ):
-                       raise ValueError('Invalid input "%s"' % value)
-               self.set_value(self.get_value() + value)
-
-       def pop(self):
-               value = self.get_value()[0:-1]
-               self.set_value(value)
-
-       def clear(self):
-               self.set_value("")
-
-       value = property(get_value, set_value, clear)
-
-
-class Calculator(object):
-
-       _glade_files = [
-               '/usr/lib/ejpi/ejpi.glade',
-               os.path.join(os.path.dirname(__file__), "ejpi.glade"),
-               os.path.join(os.path.dirname(__file__), "../lib/ejpi.glade"),
-       ]
-
-       _plugin_search_paths = [
-               "/usr/lib/ejpi/plugins/",
-               os.path.join(os.path.dirname(__file__), "plugins/"),
-       ]
-
-       _user_data = constants._data_path_
-       _user_settings = "%s/settings.ini" % _user_data
-       _user_history = "%s/history.stack" % _user_data
-
-       MIN_BUTTON_SIZE = min(800, 480) // 6 - 20
-
-       def __init__(self):
-               self.__constantPlugins = plugin_utils.ConstantPluginManager()
-               self.__constantPlugins.add_path(*self._plugin_search_paths)
-               for pluginName in ["Builtin", "Trigonometry", "Computer", "Alphabet"]:
-                       try:
-                               pluginId = self.__constantPlugins.lookup_plugin(pluginName)
-                               self.__constantPlugins.enable_plugin(pluginId)
-                       except:
-                               warnings.warn("Failed to load plugin %s" % pluginName)
-
-               self.__operatorPlugins = plugin_utils.OperatorPluginManager()
-               self.__operatorPlugins.add_path(*self._plugin_search_paths)
-               for pluginName in ["Builtin", "Trigonometry", "Computer", "Alphabet"]:
-                       try:
-                               pluginId = self.__operatorPlugins.lookup_plugin(pluginName)
-                               self.__operatorPlugins.enable_plugin(pluginId)
-                       except:
-                               warnings.warn("Failed to load plugin %s" % pluginName)
-
-               self.__keyboardPlugins = plugin_utils.KeyboardPluginManager()
-               self.__keyboardPlugins.add_path(*self._plugin_search_paths)
-               self.__activeKeyboards = []
-
-               for path in self._glade_files:
-                       if os.path.isfile(path):
-                               self._widgetTree = gtk.glade.XML(path)
-                               break
-               else:
-                       self.display_error_message("Cannot find ejpi.glade")
-                       gtk.main_quit()
-                       return
-               try:
-                       os.makedirs(self._user_data)
-               except OSError, e:
-                       if e.errno != 17:
-                               raise
-
-               self._clipboard = gtk.clipboard_get()
-               self._window = self._widgetTree.get_widget("mainWindow")
-
-               self._app = None
-               self._isFullScreen = False
-               self._app = hildonize.get_app_class()()
-               self._window = hildonize.hildonize_window(self._app, self._window)
-
-               menu = hildonize.hildonize_menu(
-                       self._window,
-                       self._widgetTree.get_widget("mainMenubar"),
-               )
-
-               for scrollingWidgetName in (
-                       "scrollingHistory",
-               ):
-                       scrollingWidget = self._widgetTree.get_widget(scrollingWidgetName)
-                       assert scrollingWidget is not None, scrollingWidgetName
-                       hildonize.hildonize_scrollwindow_with_viewport(scrollingWidget)
-
-               self.__errorDisplay = gtk_toolbox.ErrorDisplay(self._widgetTree)
-               self.__userEntry = ValueEntry(self._widgetTree.get_widget("entryView"))
-               self.__stackView = self._widgetTree.get_widget("historyView")
-               self.__pluginButton = self._widgetTree.get_widget("keyboardSelectionButton")
-
-               self.__historyStore = gtkhistory.GtkCalcHistory(self.__stackView)
-               self.__history = history.RpnCalcHistory(
-                       self.__historyStore,
-                       self.__userEntry, self.__errorDisplay,
-                       self.__constantPlugins.constants, self.__operatorPlugins.operators
-               )
-               self.__load_history()
-
-               # Basic keyboard stuff
-               self.__sliceStyle = gtkpie.generate_pie_style(gtk.Button())
-               self.__handler = gtkpieboard.KeyboardHandler(self._on_entry_direct)
-               self.__handler.register_command_handler("push", self._on_push)
-               self.__handler.register_command_handler("unpush", self._on_unpush)
-               self.__handler.register_command_handler("backspace", self._on_entry_backspace)
-               self.__handler.register_command_handler("clear", self._on_entry_clear)
-
-               # Main keyboard
-               builtinKeyboardId = self.__keyboardPlugins.lookup_plugin("Builtin")
-               self.__keyboardPlugins.enable_plugin(builtinKeyboardId)
-               self.__builtinPlugin = self.__keyboardPlugins.keyboards["Builtin"].construct_keyboard()
-               self.__builtinKeyboard = self.__builtinPlugin.setup(self.__history, self.__sliceStyle, self.__handler)
-               self._widgetTree.get_widget("mainKeyboard").pack_start(self.__builtinKeyboard)
-               for child in self.__builtinKeyboard.get_children():
-                       child.set_size_request(self.MIN_BUTTON_SIZE, self.MIN_BUTTON_SIZE)
-
-               # Plugins
-               self.enable_plugin(self.__keyboardPlugins.lookup_plugin("Trigonometry"))
-               self.enable_plugin(self.__keyboardPlugins.lookup_plugin("Computer"))
-               self.enable_plugin(self.__keyboardPlugins.lookup_plugin("Alphabet"))
-               self._set_plugin_kb(0)
-
-               # Callbacks
-               if not hildonize.IS_FREMANTLE_SUPPORTED:
-                       # Menus aren't used in the Fremantle version
-                       callbackMapping = {
-                               "on_calculator_quit": self._on_close,
-                               "on_paste": self._on_paste,
-                               "on_clear_history": self._on_clear_all,
-                               "on_about": self._on_about_activate,
-                       }
-                       self._widgetTree.signal_autoconnect(callbackMapping)
-                       self._widgetTree.get_widget("copyMenuItem").connect("activate", self._on_copy)
-                       self._widgetTree.get_widget("copyEquationMenuItem").connect("activate", self._on_copy_equation)
-               self._window.connect("key-press-event", self._on_key_press)
-               self._window.connect("window-state-event", self._on_window_state_change)
-               self._widgetTree.get_widget("entryView").connect("activate", self._on_push)
-               self.__pluginButton.connect("clicked", self._on_kb_plugin_selection_button)
-
-               hildonize.set_application_name("%s" % constants.__pretty_app_name__)
-               self._window.connect("destroy", self._on_close)
-               self._window.show_all()
-
-               if not hildonize.IS_HILDON_SUPPORTED:
-                       _moduleLogger.warning("No hildonization support")
-
-               try:
-                       import osso
-               except ImportError:
-                       osso = None
-               self._osso = None
-               self._deviceState = None
-               if osso is not None:
-                       self._osso = osso.Context(constants.__app_name__, constants.__version__, False)
-                       self._deviceState = osso.DeviceState(self._osso)
-                       self._deviceState.set_device_state_callback(self._on_device_state_change, 0)
-               else:
-                       _moduleLogger.warning("No OSSO support")
-
-       def display_error_message(self, msg):
-               error_dialog = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE, msg)
-
-               def close(dialog, response, editor):
-                       editor.about_dialog = None
-                       dialog.destroy()
-               error_dialog.connect("response", close, self)
-               error_dialog.run()
-
-       def enable_plugin(self, pluginId):
-               self.__keyboardPlugins.enable_plugin(pluginId)
-               pluginData = self.__keyboardPlugins.plugin_info(pluginId)
-               pluginName = pluginData[0]
-               plugin = self.__keyboardPlugins.keyboards[pluginName].construct_keyboard()
-               pluginKeyboard = plugin.setup(self.__history, self.__sliceStyle, self.__handler)
-               for child in pluginKeyboard.get_children():
-                       child.set_size_request(self.MIN_BUTTON_SIZE, self.MIN_BUTTON_SIZE)
-
-               self.__activeKeyboards.append({
-                       "pluginName": pluginName,
-                       "plugin": plugin,
-                       "pluginKeyboard": pluginKeyboard,
-               })
-
-       @misc_utils.log_exception(_moduleLogger)
-       def _on_kb_plugin_selection_button(self, *args):
-               pluginNames = [plugin["pluginName"] for plugin in self.__activeKeyboards]
-               oldIndex = pluginNames.index(self.__pluginButton.get_label())
-               newIndex = hildonize.touch_selector(self._window, "Keyboards", pluginNames, oldIndex)
-               self._set_plugin_kb(newIndex)
-
-       def _set_plugin_kb(self, pluginIndex):
-               plugin = self.__activeKeyboards[pluginIndex]
-               self.__pluginButton.set_label(plugin["pluginName"])
-
-               pluginParent = self._widgetTree.get_widget("pluginKeyboard")
-               oldPluginChildren = pluginParent.get_children()
-               if oldPluginChildren:
-                       assert len(oldPluginChildren) == 1, "%r" % (oldPluginChildren, )
-                       pluginParent.remove(oldPluginChildren[0])
-                       oldPluginChildren[0].hide()
-               pluginKeyboard = plugin["pluginKeyboard"]
-               pluginParent.pack_start(pluginKeyboard)
-
-               pluginKeyboard.show_all()
-
-       def __load_history(self):
-               serialized = []
-               try:
-                       with open(self._user_history, "rU") as f:
-                               serialized = (
-                                       (part.strip() for part in line.split(" "))
-                                       for line in f.readlines()
-                               )
-               except IOError, e:
-                       if e.errno != 2:
-                               raise
-               self.__history.deserialize_stack(serialized)
-
-       def __save_history(self):
-               serialized = self.__history.serialize_stack()
-               with open(self._user_history, "w") as f:
-                       for lineData in serialized:
-                               line = " ".join(data for data in lineData)
-                               f.write("%s\n" % line)
-
-       @misc_utils.log_exception(_moduleLogger)
-       def _on_device_state_change(self, shutdown, save_unsaved_data, memory_low, system_inactivity, message, userData):
-               """
-               For system_inactivity, we have no background tasks to pause
-
-               @note Hildon specific
-               """
-               if memory_low:
-                       gc.collect()
-
-               if save_unsaved_data or shutdown:
-                       self.__save_history()
-
-       @misc_utils.log_exception(_moduleLogger)
-       def _on_window_state_change(self, widget, event, *args):
-               if event.new_window_state & gtk.gdk.WINDOW_STATE_FULLSCREEN:
-                       self._isFullScreen = True
-               else:
-                       self._isFullScreen = False
-
-       @misc_utils.log_exception(_moduleLogger)
-       def _on_close(self, *args, **kwds):
-               try:
-                       self.__save_history()
-
-                       try:
-                               self._deviceState.close()
-                       except AttributeError:
-                               pass # Either None or close was removed (in Fremantle)
-                       try:
-                               self._osso.close()
-                       except AttributeError:
-                               pass # Either None or close was removed (in Fremantle)
-               finally:
-                       gtk.main_quit()
-
-       @misc_utils.log_exception(_moduleLogger)
-       def _on_copy(self, *args):
-               equationNode = self.__history.history.peek()
-               result = str(equationNode.evaluate())
-               self._clipboard.set_text(result)
-
-       @misc_utils.log_exception(_moduleLogger)
-       def _on_copy_equation(self, *args):
-               equationNode = self.__history.history.peek()
-               equation = str(equationNode)
-               self._clipboard.set_text(equation)
-
-       @misc_utils.log_exception(_moduleLogger)
-       def _on_paste(self, *args):
-               contents = self._clipboard.wait_for_text()
-               self.__userEntry.append(contents)
-
-       @misc_utils.log_exception(_moduleLogger)
-       def _on_key_press(self, widget, event, *args):
-               RETURN_TYPES = (gtk.keysyms.Return, gtk.keysyms.ISO_Enter, gtk.keysyms.KP_Enter)
-               if (
-                       event.keyval == gtk.keysyms.F6 or
-                       event.keyval in RETURN_TYPES and event.get_state() & gtk.gdk.CONTROL_MASK
-               ):
-                       if self._isFullScreen:
-                               self._window.unfullscreen()
-                       else:
-                               self._window.fullscreen()
-               elif event.keyval == ord("c") and event.get_state() & gtk.gdk.CONTROL_MASK:
-                       equationNode = self.__history.history.peek()
-                       result = str(equationNode.evaluate())
-                       self._clipboard.set_text(result)
-               elif event.keyval == ord("l") and event.get_state() & gtk.gdk.CONTROL_MASK:
-                       with open(constants._user_logpath_, "r") as f:
-                               logLines = f.xreadlines()
-                               log = "".join(logLines)
-                               self._clipboard.set_text(str(log))
-               elif event.keyval == gtk.keysyms.BackSpace and event.get_state() & gtk.gdk.CONTROL_MASK:
-                       self.__historyStore.unpush()
-               elif event.keyval == gtk.keysyms.BackSpace:
-                       self.__userEntry.pop()
-               elif event.keyval in RETURN_TYPES:
-                       self.__history.push_entry()
-
-       @misc_utils.log_exception(_moduleLogger)
-       def _on_push(self, *args):
-               self.__history.push_entry()
-
-       @misc_utils.log_exception(_moduleLogger)
-       def _on_unpush(self, *args):
-               self.__historyStore.unpush()
-
-       @misc_utils.log_exception(_moduleLogger)
-       def _on_entry_direct(self, keys, modifiers):
-               if "shift" in modifiers:
-                       keys = keys.upper()
-               self.__userEntry.append(keys)
-
-       @misc_utils.log_exception(_moduleLogger)
-       def _on_entry_backspace(self, *args):
-               self.__userEntry.pop()
-
-       @misc_utils.log_exception(_moduleLogger)
-       def _on_entry_clear(self, *args):
-               self.__userEntry.clear()
-
-       @misc_utils.log_exception(_moduleLogger)
-       def _on_clear_all(self, *args):
-               self.__history.clear()
-
-       @misc_utils.log_exception(_moduleLogger)
-       def _on_about_activate(self, *args):
-               dlg = gtk.AboutDialog()
-               dlg.set_name(constants.__pretty_app_name__)
-               dlg.set_version(constants.__version__)
-               dlg.set_copyright("Copyright 2008 - LGPL")
-               dlg.set_comments("""
-ejpi A Touch Screen Optimized RPN Calculator for Maemo and Linux.
-
-RPN: Stack based math, its fun
-Buttons: Try both pressing and hold/drag
-History: Try dragging things around, deleting them, etc
-""")
-               dlg.set_website("http://ejpi.garage.maemo.org")
-               dlg.set_authors(["Ed Page <eopage@byu.net>"])
-               dlg.run()
-               dlg.destroy()
-
-
-def run_doctest():
-       import doctest
-
-       failureCount, testCount = doctest.testmod()
-       if not failureCount:
-               print "Tests Successful"
-               sys.exit(0)
-       else:
-               sys.exit(1)
-
-
-def run():
-       gtk.gdk.threads_init()
-
-       gtkpie.IMAGES.add_path(os.path.join(os.path.dirname(__file__), "libraries/images"), )
-       if hildonize.IS_HILDON_SUPPORTED:
-               gtk.set_application_name(constants.__pretty_app_name__)
-       handle = Calculator()
-       if not PROFILE_STARTUP:
-               gtk.main()
-
-
-class DummyOptions(object):
-
-       def __init__(self):
-               self.test = False
-
-
-if __name__ == "__main__":
-       logging.basicConfig(level=logging.DEBUG)
-       if len(sys.argv) > 1:
-               try:
-                       import optparse
-               except ImportError:
-                       optparse = None
-
-               if optparse is not None:
-                       parser = optparse.OptionParser()
-                       parser.add_option("-t", "--test", action="store_true", dest="test", help="Run tests")
-                       (commandOptions, commandArgs) = parser.parse_args()
-       else:
-               commandOptions = DummyOptions()
-               commandArgs = []
-
-       if commandOptions.test:
-               run_doctest()
-       else:
-               run()
index 813e821..e7af6bf 100755 (executable)
@@ -6,6 +6,7 @@ from __future__ import with_statement
 import sys
 import os
 import simplejson
+import string
 import logging
 
 from PyQt4 import QtGui
@@ -15,6 +16,10 @@ import constants
 import maeqt
 from util import misc as misc_utils
 
+from libraries import qtpie
+from libraries import qtpieboard
+import plugin_utils
+import history
 import qhistory
 
 
@@ -24,6 +29,11 @@ _moduleLogger = logging.getLogger(__name__)
 IS_MAEMO = True
 
 
+PLUGIN_SEARCH_PATHS = [
+       os.path.join(os.path.dirname(__file__), "plugins/"),
+]
+
+
 class Calculator(object):
 
        def __init__(self, app):
@@ -32,7 +42,6 @@ class Calculator(object):
                self._hiddenCategories = set()
                self._hiddenUnits = {}
                self._clipboard = QtGui.QApplication.clipboard()
-
                self._mainWindow = None
 
                self._fullscreenAction = QtGui.QAction(None)
@@ -120,15 +129,145 @@ class Calculator(object):
                self._close_windows()
 
 
+class QErrorDisplay(object):
+
+       def __init__(self):
+               self._messages = []
+
+               icon = QtGui.QIcon.fromTheme("gtk-dialog-error")
+               self._severityIcon = icon.pixmap(32, 32)
+               self._severityLabel = QtGui.QLabel()
+               self._severityLabel.setPixmap(self._severityIcon)
+
+               self._message = QtGui.QLabel()
+               self._message.setText("Boo")
+
+               icon = QtGui.QIcon.fromTheme("gtk-close")
+               self._closeIcon = icon.pixmap(32, 32)
+               self._closeLabel = QtGui.QLabel()
+               self._closeLabel.setPixmap(self._closeIcon)
+
+               self._controlLayout = QtGui.QHBoxLayout()
+               self._controlLayout.addWidget(self._severityLabel)
+               self._controlLayout.addWidget(self._message)
+               self._controlLayout.addWidget(self._closeLabel)
+
+               self._topLevelLayout = QtGui.QHBoxLayout()
+
+       @property
+       def toplevel(self):
+               return self._topLevelLayout
+
+       def push_message(self, message):
+               self._messages.append(message)
+               if 1 == len(self._messages):
+                       self._show_message(message)
+
+       def push_exception(self):
+               userMessage = str(sys.exc_info()[1])
+               self.push_message(userMessage)
+               _moduleLogger.exception(userMessage)
+
+       def pop_message(self):
+               del self._messages[0]
+               if 0 == len(self._messages):
+                       self._hide_message()
+               else:
+                       self._message.setText(self._messages[0])
+
+       def _on_close(self, *args):
+               self.pop_message()
+
+       def _show_message(self, message):
+               self._message.set_text(message)
+               self._topLevelLayout.addLayout(self._controlLayout)
+
+       def _hide_message(self):
+               self._message.set_text("")
+               self._topLevelLayout.removeItem(self._controlLayout)
+
+
+class QValueEntry(object):
+
+       def __init__(self):
+               self._widget = QtGui.QLineEdit("")
+               self._widget.setInputMethodHints(QtCore.Qt.ImhPreferNumbers)
+               self._actualEntryDisplay = ""
+
+       @property
+       def toplevel(self):
+               return self._widget
+
+       def get_value(self):
+               value = self._actualEntryDisplay.strip()
+               if any(
+                       0 < value.find(whitespace)
+                       for whitespace in string.whitespace
+               ):
+                       self.clear()
+                       raise ValueError('Invalid input "%s"' % value)
+               return value
+
+       def set_value(self, value):
+               value = value.strip()
+               if any(
+                       0 < value.find(whitespace)
+                       for whitespace in string.whitespace
+               ):
+                       raise ValueError('Invalid input "%s"' % value)
+               self._actualEntryDisplay = value
+               self._widget.setText(value)
+
+       def append(self, value):
+               value = value.strip()
+               if any(
+                       0 < value.find(whitespace)
+                       for whitespace in string.whitespace
+               ):
+                       raise ValueError('Invalid input "%s"' % value)
+               self.set_value(self.get_value() + value)
+
+       def pop(self):
+               value = self.get_value()[0:-1]
+               self.set_value(value)
+
+       def clear(self):
+               self.set_value("")
+
+       value = property(get_value, set_value, clear)
+
+
 class MainWindow(object):
 
+       _plugin_search_paths = [
+               "/opt/epi/lib/plugins/",
+               "/usr/lib/ejpi/plugins/",
+               os.path.join(os.path.dirname(__file__), "plugins/"),
+       ]
+
+       _user_history = "%s/history.stack" % constants._data_path_
+
        def __init__(self, parent, app):
                self._app = app
 
                self._historyView = qhistory.QCalcHistory()
 
-               self._layout = QtGui.QVBoxLayout()
-               self._layout.addWidget(self._historyView.toplevel)
+               self._errorDisplay = QErrorDisplay()
+
+               self._userEntry = QValueEntry()
+
+               self._controlLayout = QtGui.QVBoxLayout()
+               self._controlLayout.addLayout(self._errorDisplay.toplevel)
+               self._controlLayout.addWidget(self._historyView.toplevel)
+               self._controlLayout.addWidget(self._userEntry.toplevel)
+
+               self._pluginKeyboardSpot = QtGui.QVBoxLayout()
+               self._inputLayout = QtGui.QVBoxLayout()
+               self._inputLayout.addLayout(self._pluginKeyboardSpot)
+
+               self._layout = QtGui.QHBoxLayout()
+               self._layout.addLayout(self._controlLayout)
+               self._layout.addLayout(self._inputLayout)
 
                centralWidget = QtGui.QWidget()
                centralWidget.setLayout(self._layout)
@@ -163,6 +302,55 @@ class MainWindow(object):
 
                self._window.addAction(self._app.logAction)
 
+               self._constantPlugins = plugin_utils.ConstantPluginManager()
+               self._constantPlugins.add_path(*self._plugin_search_paths)
+               for pluginName in ["Builtin", "Trigonometry", "Computer", "Alphabet"]:
+                       try:
+                               pluginId = self._constantPlugins.lookup_plugin(pluginName)
+                               self._constantPlugins.enable_plugin(pluginId)
+                       except:
+                               _moduleLogger.info("Failed to load plugin %s" % pluginName)
+
+               self._operatorPlugins = plugin_utils.OperatorPluginManager()
+               self._operatorPlugins.add_path(*self._plugin_search_paths)
+               for pluginName in ["Builtin", "Trigonometry", "Computer", "Alphabet"]:
+                       try:
+                               pluginId = self._operatorPlugins.lookup_plugin(pluginName)
+                               self._operatorPlugins.enable_plugin(pluginId)
+                       except:
+                               _moduleLogger.info("Failed to load plugin %s" % pluginName)
+
+               self._keyboardPlugins = plugin_utils.KeyboardPluginManager()
+               self._keyboardPlugins.add_path(*self._plugin_search_paths)
+               self._activeKeyboards = []
+
+               self._history = history.RpnCalcHistory(
+                       self._historyView,
+                       self._userEntry, self._errorDisplay,
+                       self._constantPlugins.constants, self._operatorPlugins.operators
+               )
+               self._load_history()
+
+               # Basic keyboard stuff
+               self._handler = qtpieboard.KeyboardHandler(self._on_entry_direct)
+               self._handler.register_command_handler("push", self._on_push)
+               self._handler.register_command_handler("unpush", self._on_unpush)
+               self._handler.register_command_handler("backspace", self._on_entry_backspace)
+               self._handler.register_command_handler("clear", self._on_entry_clear)
+
+               # Main keyboard
+               builtinKeyboardId = self._keyboardPlugins.lookup_plugin("Builtin")
+               self._keyboardPlugins.enable_plugin(builtinKeyboardId)
+               self._builtinPlugin = self._keyboardPlugins.keyboards["Builtin"].construct_keyboard()
+               self._builtinKeyboard = self._builtinPlugin.setup(self._history, self._handler)
+               self._inputLayout.addLayout(self._builtinKeyboard.toplevel)
+
+               # Plugins
+               self.enable_plugin(self._keyboardPlugins.lookup_plugin("Trigonometry"))
+               self.enable_plugin(self._keyboardPlugins.lookup_plugin("Computer"))
+               self.enable_plugin(self._keyboardPlugins.lookup_plugin("Alphabet"))
+               self._set_plugin_kb(0)
+
                self.set_fullscreen(self._app.fullscreenAction.isChecked())
                self._window.show()
 
@@ -197,14 +385,84 @@ class MainWindow(object):
                for child in self.walk_children():
                        child.set_fullscreen(isFullscreen)
 
+       def enable_plugin(self, pluginId):
+               self._keyboardPlugins.enable_plugin(pluginId)
+               pluginData = self._keyboardPlugins.plugin_info(pluginId)
+               pluginName = pluginData[0]
+               plugin = self._keyboardPlugins.keyboards[pluginName].construct_keyboard()
+               pluginKeyboard = plugin.setup(self._history, self._handler)
+
+               self._activeKeyboards.append({
+                       "pluginName": pluginName,
+                       "plugin": plugin,
+                       "pluginKeyboard": pluginKeyboard,
+               })
+
+       def _set_plugin_kb(self, pluginIndex):
+               plugin = self._activeKeyboards[pluginIndex]
+               # @todo self._pluginButton.set_label(plugin["pluginName"])
+
+               for i in xrange(self._pluginKeyboardSpot.count()):
+                       self._pluginKeyboardSpot.removeItem(self._pluginKeyboardSpot.itemAt(i))
+               pluginKeyboard = plugin["pluginKeyboard"]
+               self._pluginKeyboardSpot.addItem(pluginKeyboard.toplevel)
+
+       def _load_history(self):
+               serialized = []
+               try:
+                       with open(self._user_history, "rU") as f:
+                               serialized = (
+                                       (part.strip() for part in line.split(" "))
+                                       for line in f.readlines()
+                               )
+               except IOError, e:
+                       if e.errno != 2:
+                               raise
+               self._history.deserialize_stack(serialized)
+
+       def _save_history(self):
+               serialized = self._history.serialize_stack()
+               with open(self._user_history, "w") as f:
+                       for lineData in serialized:
+                               line = " ".join(data for data in lineData)
+                               f.write("%s\n" % line)
+
+       @misc_utils.log_exception(_moduleLogger)
+       def _on_entry_direct(self, keys, modifiers):
+               if "shift" in modifiers:
+                       keys = keys.upper()
+               self._userEntry.append(keys)
+
+       @misc_utils.log_exception(_moduleLogger)
+       def _on_push(self, *args):
+               self._history.push_entry()
+
+       @misc_utils.log_exception(_moduleLogger)
+       def _on_unpush(self, *args):
+               self._historyStore.unpush()
+
+       @misc_utils.log_exception(_moduleLogger)
+       def _on_entry_backspace(self, *args):
+               self._userEntry.pop()
+
+       @misc_utils.log_exception(_moduleLogger)
+       def _on_entry_clear(self, *args):
+               self._userEntry.clear()
+
+       @misc_utils.log_exception(_moduleLogger)
+       def _on_clear_all(self, *args):
+               self._history.clear()
+
        @misc_utils.log_exception(_moduleLogger)
        def _on_close_window(self, checked = True):
+               self._save_history()
                self.close()
 
 
 def run():
        app = QtGui.QApplication([])
        handle = Calculator(app)
+       qtpie.init_pies()
        return app.exec_()
 
 
diff --git a/src/gtk_toolbox.py b/src/gtk_toolbox.py
deleted file mode 100644 (file)
index f687e6b..0000000
+++ /dev/null
@@ -1,772 +0,0 @@
-#!/usr/bin/python
-
-from __future__ import with_statement
-
-import os
-import errno
-import sys
-import time
-import itertools
-import functools
-import contextlib
-import logging
-import threading
-import Queue
-
-import gobject
-import gtk
-
-
-_moduleLogger = logging.getLogger(__name__)
-
-
-def get_screen_orientation():
-       width, height = gtk.gdk.get_default_root_window().get_size()
-       if width < height:
-               return gtk.ORIENTATION_VERTICAL
-       else:
-               return gtk.ORIENTATION_HORIZONTAL
-
-
-def orientation_change_connect(handler, *args):
-       """
-       @param handler(orientation, *args) -> None(?)
-       """
-       initialScreenOrientation = get_screen_orientation()
-       orientationAndArgs = list(itertools.chain((initialScreenOrientation, ), args))
-
-       def _on_screen_size_changed(screen):
-               newScreenOrientation = get_screen_orientation()
-               if newScreenOrientation != orientationAndArgs[0]:
-                       orientationAndArgs[0] = newScreenOrientation
-                       handler(*orientationAndArgs)
-
-       rootScreen = gtk.gdk.get_default_root_window()
-       return gtk.connect(rootScreen, "size-changed", _on_screen_size_changed)
-
-
-@contextlib.contextmanager
-def flock(path, timeout=-1):
-       WAIT_FOREVER = -1
-       DELAY = 0.1
-       timeSpent = 0
-
-       acquired = False
-
-       while timeSpent <= timeout or timeout == WAIT_FOREVER:
-               try:
-                       fd = os.open(path, os.O_CREAT | os.O_EXCL | os.O_RDWR)
-                       acquired = True
-                       break
-               except OSError, e:
-                       if e.errno != errno.EEXIST:
-                               raise
-               time.sleep(DELAY)
-               timeSpent += DELAY
-
-       assert acquired, "Failed to grab file-lock %s within timeout %d" % (path, timeout)
-
-       try:
-               yield fd
-       finally:
-               os.unlink(path)
-
-
-@contextlib.contextmanager
-def gtk_lock():
-       gtk.gdk.threads_enter()
-       try:
-               yield
-       finally:
-               gtk.gdk.threads_leave()
-
-
-def find_parent_window(widget):
-       while True:
-               parent = widget.get_parent()
-               if isinstance(parent, gtk.Window):
-                       return parent
-               widget = parent
-
-
-def make_idler(func):
-       """
-       Decorator that makes a generator-function into a function that will continue execution on next call
-       """
-       a = []
-
-       @functools.wraps(func)
-       def decorated_func(*args, **kwds):
-               if not a:
-                       a.append(func(*args, **kwds))
-               try:
-                       a[0].next()
-                       return True
-               except StopIteration:
-                       del a[:]
-                       return False
-
-       return decorated_func
-
-
-def asynchronous_gtk_message(original_func):
-       """
-       @note Idea came from http://www.aclevername.com/articles/python-webgui/
-       """
-
-       def execute(allArgs):
-               args, kwargs = allArgs
-               with gtk_lock():
-                       original_func(*args, **kwargs)
-               return False
-
-       @functools.wraps(original_func)
-       def delayed_func(*args, **kwargs):
-               gobject.idle_add(execute, (args, kwargs))
-
-       return delayed_func
-
-
-def synchronous_gtk_message(original_func):
-       """
-       @note Idea came from http://www.aclevername.com/articles/python-webgui/
-       """
-
-       @functools.wraps(original_func)
-       def immediate_func(*args, **kwargs):
-               with gtk_lock():
-                       return original_func(*args, **kwargs)
-
-       return immediate_func
-
-
-def autostart(func):
-       """
-       >>> @autostart
-       ... def grep_sink(pattern):
-       ...     print "Looking for %s" % pattern
-       ...     while True:
-       ...             line = yield
-       ...             if pattern in line:
-       ...                     print line,
-       >>> g = grep_sink("python")
-       Looking for python
-       >>> g.send("Yeah but no but yeah but no")
-       >>> g.send("A series of tubes")
-       >>> g.send("python generators rock!")
-       python generators rock!
-       >>> g.close()
-       """
-
-       @functools.wraps(func)
-       def start(*args, **kwargs):
-               cr = func(*args, **kwargs)
-               cr.next()
-               return cr
-
-       return start
-
-
-@autostart
-def printer_sink(format = "%s"):
-       """
-       >>> pr = printer_sink("%r")
-       >>> pr.send("Hello")
-       'Hello'
-       >>> pr.send("5")
-       '5'
-       >>> pr.send(5)
-       5
-       >>> p = printer_sink()
-       >>> p.send("Hello")
-       Hello
-       >>> p.send("World")
-       World
-       >>> # p.throw(RuntimeError, "Goodbye")
-       >>> # p.send("Meh")
-       >>> # p.close()
-       """
-       while True:
-               item = yield
-               print format % (item, )
-
-
-@autostart
-def null_sink():
-       """
-       Good for uses like with cochain to pick up any slack
-       """
-       while True:
-               item = yield
-
-
-@autostart
-def comap(function, target):
-       """
-       >>> p = printer_sink()
-       >>> cm = comap(lambda x: x+1, p)
-       >>> cm.send((0, ))
-       1
-       >>> cm.send((1.0, ))
-       2.0
-       >>> cm.send((-2, ))
-       -1
-       """
-       while True:
-               try:
-                       item = yield
-                       mappedItem = function(*item)
-                       target.send(mappedItem)
-               except Exception, e:
-                       _moduleLogger.exception("Forwarding exception!")
-                       target.throw(e.__class__, str(e))
-
-
-def _flush_queue(queue):
-       while not queue.empty():
-               yield queue.get()
-
-
-@autostart
-def queue_sink(queue):
-       """
-       >>> q = Queue.Queue()
-       >>> qs = queue_sink(q)
-       >>> qs.send("Hello")
-       >>> qs.send("World")
-       >>> qs.throw(RuntimeError, "Goodbye")
-       >>> qs.send("Meh")
-       >>> qs.close()
-       >>> print [i for i in _flush_queue(q)]
-       [(None, 'Hello'), (None, 'World'), (<type 'exceptions.RuntimeError'>, 'Goodbye'), (None, 'Meh'), (<type 'exceptions.GeneratorExit'>, None)]
-       """
-       while True:
-               try:
-                       item = yield
-                       queue.put((None, item))
-               except Exception, e:
-                       queue.put((e.__class__, str(e)))
-               except GeneratorExit:
-                       queue.put((GeneratorExit, None))
-                       raise
-
-
-def decode_item(item, target):
-       if item[0] is None:
-               target.send(item[1])
-               return False
-       elif item[0] is GeneratorExit:
-               target.close()
-               return True
-       else:
-               target.throw(item[0], item[1])
-               return False
-
-
-def nonqueue_source(queue, target):
-       isDone = False
-       while not isDone:
-               item = queue.get()
-               isDone = decode_item(item, target)
-               while not queue.empty():
-                       queue.get_nowait()
-
-
-def threaded_stage(target, thread_factory = threading.Thread):
-       messages = Queue.Queue()
-
-       run_source = functools.partial(nonqueue_source, messages, target)
-       thread = thread_factory(target=run_source)
-       thread.setDaemon(True)
-       thread.start()
-
-       # Sink running in current thread
-       return queue_sink(messages)
-
-
-def log_exception(logger):
-
-       def log_exception_decorator(func):
-
-               @functools.wraps(func)
-               def wrapper(*args, **kwds):
-                       try:
-                               return func(*args, **kwds)
-                       except Exception:
-                               logger.exception(func.__name__)
-
-               return wrapper
-
-       return log_exception_decorator
-
-
-class LoginWindow(object):
-
-       def __init__(self, widgetTree):
-               """
-               @note Thread agnostic
-               """
-               self._dialog = widgetTree.get_widget("loginDialog")
-               self._parentWindow = widgetTree.get_widget("mainWindow")
-               self._serviceCombo = widgetTree.get_widget("serviceCombo")
-               self._usernameEntry = widgetTree.get_widget("usernameentry")
-               self._passwordEntry = widgetTree.get_widget("passwordentry")
-
-               self._serviceList = gtk.ListStore(gobject.TYPE_INT, gobject.TYPE_STRING)
-               self._serviceCombo.set_model(self._serviceList)
-               cell = gtk.CellRendererText()
-               self._serviceCombo.pack_start(cell, True)
-               self._serviceCombo.add_attribute(cell, 'text', 1)
-               self._serviceCombo.set_active(0)
-
-               widgetTree.get_widget("loginbutton").connect("clicked", self._on_loginbutton_clicked)
-               widgetTree.get_widget("logins_close_button").connect("clicked", self._on_loginclose_clicked)
-
-       def request_credentials(self,
-               parentWindow = None,
-               defaultCredentials = ("", "")
-       ):
-               """
-               @note UI Thread
-               """
-               if parentWindow is None:
-                       parentWindow = self._parentWindow
-
-               self._serviceCombo.hide()
-               self._serviceList.clear()
-
-               self._usernameEntry.set_text(defaultCredentials[0])
-               self._passwordEntry.set_text(defaultCredentials[1])
-
-               try:
-                       self._dialog.set_transient_for(parentWindow)
-                       self._dialog.set_default_response(gtk.RESPONSE_OK)
-                       response = self._dialog.run()
-                       if response != gtk.RESPONSE_OK:
-                               raise RuntimeError("Login Cancelled")
-
-                       username = self._usernameEntry.get_text()
-                       password = self._passwordEntry.get_text()
-                       self._passwordEntry.set_text("")
-               finally:
-                       self._dialog.hide()
-
-               return username, password
-
-       def request_credentials_from(self,
-               services,
-               parentWindow = None,
-               defaultCredentials = ("", "")
-       ):
-               """
-               @note UI Thread
-               """
-               if parentWindow is None:
-                       parentWindow = self._parentWindow
-
-               self._serviceList.clear()
-               for serviceIdserviceName in services:
-                       self._serviceList.append(serviceIdserviceName)
-               self._serviceCombo.set_active(0)
-               self._serviceCombo.show()
-
-               self._usernameEntry.set_text(defaultCredentials[0])
-               self._passwordEntry.set_text(defaultCredentials[1])
-
-               try:
-                       self._dialog.set_transient_for(parentWindow)
-                       self._dialog.set_default_response(gtk.RESPONSE_OK)
-                       response = self._dialog.run()
-                       if response != gtk.RESPONSE_OK:
-                               raise RuntimeError("Login Cancelled")
-
-                       username = self._usernameEntry.get_text()
-                       password = self._passwordEntry.get_text()
-               finally:
-                       self._dialog.hide()
-
-               itr = self._serviceCombo.get_active_iter()
-               serviceId = int(self._serviceList.get_value(itr, 0))
-               self._serviceList.clear()
-               return serviceId, username, password
-
-       def _on_loginbutton_clicked(self, *args):
-               self._dialog.response(gtk.RESPONSE_OK)
-
-       def _on_loginclose_clicked(self, *args):
-               self._dialog.response(gtk.RESPONSE_CANCEL)
-
-
-def safecall(f, errorDisplay=None, default=None, exception=Exception):
-       '''
-       Returns modified f. When the modified f is called and throws an
-       exception, the default value is returned
-       '''
-       def _safecall(*args, **argv):
-               try:
-                       return f(*args,**argv)
-               except exception, e:
-                       if errorDisplay is not None:
-                               errorDisplay.push_exception(e)
-                       return default
-       return _safecall
-
-
-class ErrorDisplay(object):
-
-       def __init__(self, widgetTree):
-               super(ErrorDisplay, self).__init__()
-               self.__errorBox = widgetTree.get_widget("errorEventBox")
-               self.__errorDescription = widgetTree.get_widget("errorDescription")
-               self.__errorClose = widgetTree.get_widget("errorClose")
-               self.__parentBox = self.__errorBox.get_parent()
-
-               self.__errorBox.connect("button_release_event", self._on_close)
-
-               self.__messages = []
-               self.__parentBox.remove(self.__errorBox)
-
-       def push_message_with_lock(self, message):
-               with gtk_lock():
-                       self.push_message(message)
-
-       def push_message(self, message):
-               self.__messages.append(message)
-               if 1 == len(self.__messages):
-                       self.__show_message(message)
-
-       def push_exception_with_lock(self):
-               with gtk_lock():
-                       self.push_exception()
-
-       def push_exception(self):
-               userMessage = str(sys.exc_info()[1])
-               self.push_message(userMessage)
-               _moduleLogger.exception(userMessage)
-
-       def pop_message(self):
-               del self.__messages[0]
-               if 0 == len(self.__messages):
-                       self.__hide_message()
-               else:
-                       self.__errorDescription.set_text(self.__messages[0])
-
-       def _on_close(self, *args):
-               self.pop_message()
-
-       def __show_message(self, message):
-               self.__errorDescription.set_text(message)
-               self.__parentBox.pack_start(self.__errorBox, False, False)
-               self.__parentBox.reorder_child(self.__errorBox, 1)
-
-       def __hide_message(self):
-               self.__errorDescription.set_text("")
-               self.__parentBox.remove(self.__errorBox)
-
-
-class DummyErrorDisplay(object):
-
-       def __init__(self):
-               super(DummyErrorDisplay, self).__init__()
-
-               self.__messages = []
-
-       def push_message_with_lock(self, message):
-               self.push_message(message)
-
-       def push_message(self, message):
-               if 0 < len(self.__messages):
-                       self.__messages.append(message)
-               else:
-                       self.__show_message(message)
-
-       def push_exception(self, exception = None):
-               userMessage = str(sys.exc_value)
-               _moduleLogger.exception(userMessage)
-
-       def pop_message(self):
-               if 0 < len(self.__messages):
-                       self.__show_message(self.__messages[0])
-                       del self.__messages[0]
-
-       def __show_message(self, message):
-               _moduleLogger.debug(message)
-
-
-class MessageBox(gtk.MessageDialog):
-
-       def __init__(self, message):
-               parent = None
-               gtk.MessageDialog.__init__(
-                       self,
-                       parent,
-                       gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
-                       gtk.MESSAGE_ERROR,
-                       gtk.BUTTONS_OK,
-                       message,
-               )
-               self.set_default_response(gtk.RESPONSE_OK)
-               self.connect('response', self._handle_clicked)
-
-       def _handle_clicked(self, *args):
-               self.destroy()
-
-
-class MessageBox2(gtk.MessageDialog):
-
-       def __init__(self, message):
-               parent = None
-               gtk.MessageDialog.__init__(
-                       self,
-                       parent,
-                       gtk.DIALOG_DESTROY_WITH_PARENT,
-                       gtk.MESSAGE_ERROR,
-                       gtk.BUTTONS_OK,
-                       message,
-               )
-               self.set_default_response(gtk.RESPONSE_OK)
-               self.connect('response', self._handle_clicked)
-
-       def _handle_clicked(self, *args):
-               self.destroy()
-
-
-class PopupCalendar(object):
-
-       def __init__(self, parent, displayDate, title = ""):
-               self._displayDate = displayDate
-
-               self._calendar = gtk.Calendar()
-               self._calendar.select_month(self._displayDate.month, self._displayDate.year)
-               self._calendar.select_day(self._displayDate.day)
-               self._calendar.set_display_options(
-                       gtk.CALENDAR_SHOW_HEADING |
-                       gtk.CALENDAR_SHOW_DAY_NAMES |
-                       gtk.CALENDAR_NO_MONTH_CHANGE |
-                       0
-               )
-               self._calendar.connect("day-selected", self._on_day_selected)
-
-               self._popupWindow = gtk.Window()
-               self._popupWindow.set_title(title)
-               self._popupWindow.add(self._calendar)
-               self._popupWindow.set_transient_for(parent)
-               self._popupWindow.set_modal(True)
-               self._popupWindow.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
-               self._popupWindow.set_skip_pager_hint(True)
-               self._popupWindow.set_skip_taskbar_hint(True)
-
-       def run(self):
-               self._popupWindow.show_all()
-
-       def _on_day_selected(self, *args):
-               try:
-                       self._calendar.select_month(self._displayDate.month, self._displayDate.year)
-                       self._calendar.select_day(self._displayDate.day)
-               except Exception, e:
-                       _moduleLogger.exception(e)
-
-
-class QuickAddView(object):
-
-       def __init__(self, widgetTree, errorDisplay, signalSink, prefix):
-               self._errorDisplay = errorDisplay
-               self._manager = None
-               self._signalSink = signalSink
-
-               self._clipboard = gtk.clipboard_get()
-
-               self._taskNameEntry = widgetTree.get_widget(prefix+"-nameEntry")
-               self._addTaskButton = widgetTree.get_widget(prefix+"-addButton")
-               self._pasteTaskNameButton = widgetTree.get_widget(prefix+"-pasteNameButton")
-               self._clearTaskNameButton = widgetTree.get_widget(prefix+"-clearNameButton")
-               self._onAddId = None
-               self._onAddClickedId = None
-               self._onAddReleasedId = None
-               self._addToEditTimerId = None
-               self._onClearId = None
-               self._onPasteId = None
-
-       def enable(self, manager):
-               self._manager = manager
-
-               self._onAddId = self._addTaskButton.connect("clicked", self._on_add)
-               self._onAddClickedId = self._addTaskButton.connect("pressed", self._on_add_pressed)
-               self._onAddReleasedId = self._addTaskButton.connect("released", self._on_add_released)
-               self._onPasteId = self._pasteTaskNameButton.connect("clicked", self._on_paste)
-               self._onClearId = self._clearTaskNameButton.connect("clicked", self._on_clear)
-
-       def disable(self):
-               self._manager = None
-
-               self._addTaskButton.disconnect(self._onAddId)
-               self._addTaskButton.disconnect(self._onAddClickedId)
-               self._addTaskButton.disconnect(self._onAddReleasedId)
-               self._pasteTaskNameButton.disconnect(self._onPasteId)
-               self._clearTaskNameButton.disconnect(self._onClearId)
-
-       def set_addability(self, addability):
-               self._addTaskButton.set_sensitive(addability)
-
-       def _on_add(self, *args):
-               try:
-                       name = self._taskNameEntry.get_text()
-                       self._taskNameEntry.set_text("")
-
-                       self._signalSink.stage.send(("add", name))
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _on_add_edit(self, *args):
-               try:
-                       name = self._taskNameEntry.get_text()
-                       self._taskNameEntry.set_text("")
-
-                       self._signalSink.stage.send(("add-edit", name))
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _on_add_pressed(self, widget):
-               try:
-                       self._addToEditTimerId = gobject.timeout_add(1000, self._on_add_edit)
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _on_add_released(self, widget):
-               try:
-                       if self._addToEditTimerId is not None:
-                               gobject.source_remove(self._addToEditTimerId)
-                       self._addToEditTimerId = None
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _on_paste(self, *args):
-               try:
-                       entry = self._taskNameEntry.get_text()
-                       addedText = self._clipboard.wait_for_text()
-                       if addedText:
-                               entry += addedText
-                       self._taskNameEntry.set_text(entry)
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _on_clear(self, *args):
-               try:
-                       self._taskNameEntry.set_text("")
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-
-class TapOrHold(object):
-
-       def __init__(self, widget):
-               self._widget = widget
-               self._isTap = True
-               self._isPointerInside = True
-               self._holdTimeoutId = None
-               self._tapTimeoutId = None
-               self._taps = 0
-
-               self._bpeId = None
-               self._breId = None
-               self._eneId = None
-               self._lneId = None
-
-       def enable(self):
-               self._bpeId = self._widget.connect("button-press-event", self._on_button_press)
-               self._breId = self._widget.connect("button-release-event", self._on_button_release)
-               self._eneId = self._widget.connect("enter-notify-event", self._on_enter)
-               self._lneId = self._widget.connect("leave-notify-event", self._on_leave)
-
-       def disable(self):
-               self._widget.disconnect(self._bpeId)
-               self._widget.disconnect(self._breId)
-               self._widget.disconnect(self._eneId)
-               self._widget.disconnect(self._lneId)
-
-       def on_tap(self, taps):
-               print "TAP", taps
-
-       def on_hold(self, taps):
-               print "HOLD", taps
-
-       def on_holding(self):
-               print "HOLDING"
-
-       def on_cancel(self):
-               print "CANCEL"
-
-       def _on_button_press(self, *args):
-               # Hack to handle weird notebook behavior
-               self._isPointerInside = True
-               self._isTap = True
-
-               if self._tapTimeoutId is not None:
-                       gobject.source_remove(self._tapTimeoutId)
-                       self._tapTimeoutId = None
-
-               # Handle double taps
-               if self._holdTimeoutId is None:
-                       self._tapTimeoutId = None
-
-                       self._taps = 1
-                       self._holdTimeoutId = gobject.timeout_add(1000, self._on_hold_timeout)
-               else:
-                       self._taps = 2
-
-       def _on_button_release(self, *args):
-               assert self._tapTimeoutId is None
-               # Handle release after timeout if user hasn't double-clicked
-               self._tapTimeoutId = gobject.timeout_add(100, self._on_tap_timeout)
-
-       def _on_actual_press(self, *args):
-               if self._holdTimeoutId is not None:
-                       gobject.source_remove(self._holdTimeoutId)
-               self._holdTimeoutId = None
-
-               if self._isPointerInside:
-                       if self._isTap:
-                               self.on_tap(self._taps)
-                       else:
-                               self.on_hold(self._taps)
-               else:
-                       self.on_cancel()
-
-       def _on_tap_timeout(self, *args):
-               self._tapTimeoutId = None
-               self._on_actual_press()
-               return False
-
-       def _on_hold_timeout(self, *args):
-               self._holdTimeoutId = None
-               self._isTap = False
-               self.on_holding()
-               return False
-
-       def _on_enter(self, *args):
-               self._isPointerInside = True
-
-       def _on_leave(self, *args):
-               self._isPointerInside = False
-
-
-if __name__ == "__main__":
-       if True:
-               win = gtk.Window()
-               win.set_title("Tap'N'Hold")
-               eventBox = gtk.EventBox()
-               win.add(eventBox)
-
-               context = ContextHandler(eventBox, coroutines.printer_sink())
-               context.enable()
-               win.connect("destroy", lambda w: gtk.main_quit())
-
-               win.show_all()
-
-       if False:
-               import datetime
-               cal = PopupCalendar(None, datetime.datetime.now())
-               cal._popupWindow.connect("destroy", lambda w: gtk.main_quit())
-               cal.run()
-
-       gtk.main()
diff --git a/src/gtkhistory.py b/src/gtkhistory.py
deleted file mode 100755 (executable)
index 7b4c55c..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-#!/usr/bin/env python
-
-"""
-http://www.grigoriev.ru/svgmath/ (MathML->SVG in Python)
-http://helm.cs.unibo.it/mml-widget/ (MathML widget in C++)
-"""
-
-import logging
-
-import gobject
-import pango
-import gtk
-
-
-import util.misc as misc_utils
-import hildonize
-import history
-import operation
-
-
-_moduleLogger = logging.getLogger(__name__)
-
-
-class GtkCalcHistory(history.AbstractHistory):
-
-       BUTTON_IDX = 0
-       VIEW_DATA_IDX = 1
-       VIEW_RESULT_IDX = 2
-       DATA_IDX = 3
-       RESULT_IDX = 4
-
-       def __init__(self, view):
-               super(GtkCalcHistory, self).__init__()
-               self.__prettyRenderer = operation.render_number()
-               self._historyView = view
-
-               # stock-id, display, value
-               self.__historyStore = gtk.ListStore(
-                       gobject.TYPE_STRING, # stock id for pixbuf
-                       gobject.TYPE_STRING, # view of data
-                       gobject.TYPE_STRING, # view of result
-                       object, # data
-                       object, # result
-               )
-               self._historyView.set_model(self.__historyStore)
-
-               # create the TreeViewColumns to display the data
-               self.__closeColumn = gtk.TreeViewColumn('')
-               self._historyView.append_column(self.__closeColumn)
-
-               self.__historyColumn = gtk.TreeViewColumn('History')
-               self.__historyColumn.set_sort_column_id(0)
-               self.__historyColumn.set_expand(True)
-               self._historyView.append_column(self.__historyColumn)
-
-               self.__resultColumn = gtk.TreeViewColumn('')
-               self.__resultColumn.set_sort_column_id(0)
-               self._historyView.append_column(self.__resultColumn)
-
-               # create a CellRenderers to render the data
-               self.__closeCell = gtk.CellRendererPixbuf()
-               hildonize.set_pix_cell_thumb_selectable(self.__closeCell)
-               self.__closeColumn.pack_start(self.__closeCell, False)
-               self.__closeColumn.set_attributes(self.__closeCell, stock_id=0)
-
-               self.__expressionCell = gtk.CellRendererText()
-               self.__expressionCell.set_property("ellipsize", pango.ELLIPSIZE_MIDDLE)
-               self.__historyColumn.pack_start(self.__expressionCell, True)
-               self.__historyColumn.set_attributes(self.__expressionCell, text=1)
-
-               self.__valueCell = gtk.CellRendererText()
-               self.__valueCell.set_property("ellipsize", pango.ELLIPSIZE_NONE)
-               self.__resultColumn.pack_end(self.__valueCell, False)
-               self.__resultColumn.set_attributes(self.__valueCell, text=2)
-
-               self._historyView.set_reorderable(True)
-               self._historyView.get_selection().set_mode(gtk.SELECTION_SINGLE)
-               self._historyView.connect("row-activated", self._on_close_activated)
-
-       def push(self, node):
-               simpleNode = node.simplify()
-               self.__historyStore.append([
-                       gtk.STOCK_CLOSE,
-                       operation.render_operation(self.__prettyRenderer, node),
-                       operation.render_operation(self.__prettyRenderer, simpleNode),
-                       node,
-                       simpleNode
-               ])
-               selection = self._historyView.get_selection()
-               selectionPath = (len(self.__historyStore)-1, )
-               selection.select_path(selectionPath)
-               self._historyView.scroll_to_cell(selectionPath)
-
-       def pop(self):
-               if len(self.__historyStore) == 0:
-                       raise IndexError("Not enough items in the history for the operation")
-
-               row = self.__historyStore[-1]
-               data = row[self.DATA_IDX]
-               del self.__historyStore[-1]
-
-               return data
-
-       def peek(self):
-               if len(self.__historyStore) == 0:
-                       raise IndexError("Not enough items in the history for the operation")
-               row = self.__historyStore[-1]
-               data = row[self.DATA_IDX]
-               return data
-
-       def clear(self):
-               self.__historyStore.clear()
-
-       def __len__(self):
-               return len(self.__historyStore)
-
-       def __iter__(self):
-               for row in iter(self.__historyStore):
-                       data = row[self.DATA_IDX]
-                       yield data
-
-       @misc_utils.log_exception(_moduleLogger)
-       def _on_close_activated(self, treeView, path, viewColumn):
-               if viewColumn is self.__closeColumn:
-                       del self.__historyStore[path[0]]
-               elif viewColumn is self.__resultColumn:
-                       row = self.__historyStore[path[0]]
-                       data = row[self.RESULT_IDX]
-                       self.push(data)
-               elif viewColumn is self.__historyColumn:
-                       row = self.__historyStore[path[0]]
-                       data = row[self.DATA_IDX]
-                       self.push(data)
-               else:
-                       assert False
diff --git a/src/hildonize.py b/src/hildonize.py
deleted file mode 100755 (executable)
index 339eb2a..0000000
+++ /dev/null
@@ -1,766 +0,0 @@
-#!/usr/bin/env python
-
-"""
-Open Issues
-       @bug not all of a message is shown
-       @bug Buttons are too small
-"""
-
-
-import gobject
-import gtk
-import dbus
-
-
-class _NullHildonModule(object):
-       pass
-
-
-try:
-       import hildon as _hildon
-       hildon  = _hildon # Dumb but gets around pyflakiness
-except (ImportError, OSError):
-       hildon = _NullHildonModule
-
-
-IS_HILDON_SUPPORTED = hildon is not _NullHildonModule
-
-
-class _NullHildonProgram(object):
-
-       def add_window(self, window):
-               pass
-
-
-def _hildon_get_app_class():
-       return hildon.Program
-
-
-def _null_get_app_class():
-       return _NullHildonProgram
-
-
-try:
-       hildon.Program
-       get_app_class = _hildon_get_app_class
-except AttributeError:
-       get_app_class = _null_get_app_class
-
-
-def _hildon_set_application_name(name):
-       gtk.set_application_name(name)
-
-
-def _null_set_application_name(name):
-       pass
-
-
-try:
-       gtk.set_application_name
-       set_application_name = _hildon_set_application_name
-except AttributeError:
-       set_application_name = _null_set_application_name
-
-
-def _fremantle_hildonize_window(app, window):
-       oldWindow = window
-       newWindow = hildon.StackableWindow()
-       if oldWindow.get_child() is not None:
-               oldWindow.get_child().reparent(newWindow)
-       app.add_window(newWindow)
-       return newWindow
-
-
-def _hildon_hildonize_window(app, window):
-       oldWindow = window
-       newWindow = hildon.Window()
-       if oldWindow.get_child() is not None:
-               oldWindow.get_child().reparent(newWindow)
-       app.add_window(newWindow)
-       return newWindow
-
-
-def _null_hildonize_window(app, window):
-       return window
-
-
-try:
-       hildon.StackableWindow
-       hildonize_window = _fremantle_hildonize_window
-except AttributeError:
-       try:
-               hildon.Window
-               hildonize_window = _hildon_hildonize_window
-       except AttributeError:
-               hildonize_window = _null_hildonize_window
-
-
-def _fremantle_hildonize_menu(window, gtkMenu):
-       appMenu = hildon.AppMenu()
-       window.set_app_menu(appMenu)
-       gtkMenu.get_parent().remove(gtkMenu)
-       return appMenu
-
-
-def _hildon_hildonize_menu(window, gtkMenu):
-       hildonMenu = gtk.Menu()
-       for child in gtkMenu.get_children():
-               child.reparent(hildonMenu)
-       window.set_menu(hildonMenu)
-       gtkMenu.destroy()
-       return hildonMenu
-
-
-def _null_hildonize_menu(window, gtkMenu):
-       return gtkMenu
-
-
-try:
-       hildon.AppMenu
-       GTK_MENU_USED = False
-       IS_FREMANTLE_SUPPORTED = True
-       hildonize_menu = _fremantle_hildonize_menu
-except AttributeError:
-       GTK_MENU_USED = True
-       IS_FREMANTLE_SUPPORTED = False
-       if IS_HILDON_SUPPORTED:
-               hildonize_menu = _hildon_hildonize_menu
-       else:
-               hildonize_menu = _null_hildonize_menu
-
-
-def _hildon_set_button_auto_selectable(button):
-       button.set_theme_size(hildon.HILDON_SIZE_AUTO_HEIGHT)
-
-
-def _null_set_button_auto_selectable(button):
-       pass
-
-
-try:
-       hildon.HILDON_SIZE_AUTO_HEIGHT
-       gtk.Button.set_theme_size
-       set_button_auto_selectable = _hildon_set_button_auto_selectable
-except AttributeError:
-       set_button_auto_selectable = _null_set_button_auto_selectable
-
-
-def _hildon_set_button_finger_selectable(button):
-       button.set_theme_size(hildon.HILDON_SIZE_FINGER_HEIGHT)
-
-
-def _null_set_button_finger_selectable(button):
-       pass
-
-
-try:
-       hildon.HILDON_SIZE_FINGER_HEIGHT
-       gtk.Button.set_theme_size
-       set_button_finger_selectable = _hildon_set_button_finger_selectable
-except AttributeError:
-       set_button_finger_selectable = _null_set_button_finger_selectable
-
-
-def _hildon_set_button_thumb_selectable(button):
-       button.set_theme_size(hildon.HILDON_SIZE_THUMB_HEIGHT)
-
-
-def _null_set_button_thumb_selectable(button):
-       pass
-
-
-try:
-       hildon.HILDON_SIZE_THUMB_HEIGHT
-       gtk.Button.set_theme_size
-       set_button_thumb_selectable = _hildon_set_button_thumb_selectable
-except AttributeError:
-       set_button_thumb_selectable = _null_set_button_thumb_selectable
-
-
-def _hildon_set_cell_thumb_selectable(renderer):
-       renderer.set_property("scale", 1.5)
-
-
-def _null_set_cell_thumb_selectable(renderer):
-       pass
-
-
-if IS_HILDON_SUPPORTED:
-       set_cell_thumb_selectable = _hildon_set_cell_thumb_selectable
-else:
-       set_cell_thumb_selectable = _null_set_cell_thumb_selectable
-
-
-def _hildon_set_pix_cell_thumb_selectable(renderer):
-       renderer.set_property("stock-size", 48)
-
-
-def _null_set_pix_cell_thumb_selectable(renderer):
-       pass
-
-
-if IS_HILDON_SUPPORTED:
-       set_pix_cell_thumb_selectable = _hildon_set_pix_cell_thumb_selectable
-else:
-       set_pix_cell_thumb_selectable = _null_set_pix_cell_thumb_selectable
-
-
-def _fremantle_show_information_banner(parent, message):
-       hildon.hildon_banner_show_information(parent, "", message)
-
-
-def _hildon_show_information_banner(parent, message):
-       hildon.hildon_banner_show_information(parent, None, message)
-
-
-def _null_show_information_banner(parent, message):
-       pass
-
-
-if IS_FREMANTLE_SUPPORTED:
-       show_information_banner = _fremantle_show_information_banner
-else:
-       try:
-               hildon.hildon_banner_show_information
-               show_information_banner = _hildon_show_information_banner
-       except AttributeError:
-               show_information_banner = _null_show_information_banner
-
-
-def _fremantle_show_busy_banner_start(parent, message):
-       hildon.hildon_gtk_window_set_progress_indicator(parent, True)
-       return parent
-
-
-def _fremantle_show_busy_banner_end(banner):
-       hildon.hildon_gtk_window_set_progress_indicator(banner, False)
-
-
-def _hildon_show_busy_banner_start(parent, message):
-       return hildon.hildon_banner_show_animation(parent, None, message)
-
-
-def _hildon_show_busy_banner_end(banner):
-       banner.destroy()
-
-
-def _null_show_busy_banner_start(parent, message):
-       return None
-
-
-def _null_show_busy_banner_end(banner):
-       assert banner is None
-
-
-try:
-       hildon.hildon_gtk_window_set_progress_indicator
-       show_busy_banner_start = _fremantle_show_busy_banner_start
-       show_busy_banner_end = _fremantle_show_busy_banner_end
-except AttributeError:
-       try:
-               hildon.hildon_banner_show_animation
-               show_busy_banner_start = _hildon_show_busy_banner_start
-               show_busy_banner_end = _hildon_show_busy_banner_end
-       except AttributeError:
-               show_busy_banner_start = _null_show_busy_banner_start
-               show_busy_banner_end = _null_show_busy_banner_end
-
-
-def _hildon_hildonize_text_entry(textEntry):
-       textEntry.set_property('hildon-input-mode', 7)
-
-
-def _null_hildonize_text_entry(textEntry):
-       pass
-
-
-if IS_HILDON_SUPPORTED:
-       hildonize_text_entry = _hildon_hildonize_text_entry
-else:
-       hildonize_text_entry = _null_hildonize_text_entry
-
-
-def _hildon_window_to_portrait(window):
-       # gtk documentation is unclear whether this does a "=" or a "|="
-       flags = hildon.PORTRAIT_MODE_SUPPORT | hildon.PORTRAIT_MODE_REQUEST
-       hildon.hildon_gtk_window_set_portrait_flags(window, flags)
-
-
-def _hildon_window_to_landscape(window):
-       # gtk documentation is unclear whether this does a "=" or a "&= ~"
-       flags = hildon.PORTRAIT_MODE_SUPPORT
-       hildon.hildon_gtk_window_set_portrait_flags(window, flags)
-
-
-def _null_window_to_portrait(window):
-       pass
-
-
-def _null_window_to_landscape(window):
-       pass
-
-
-try:
-       hildon.PORTRAIT_MODE_SUPPORT
-       hildon.PORTRAIT_MODE_REQUEST
-       hildon.hildon_gtk_window_set_portrait_flags
-
-       window_to_portrait = _hildon_window_to_portrait
-       window_to_landscape = _hildon_window_to_landscape
-except AttributeError:
-       window_to_portrait = _null_window_to_portrait
-       window_to_landscape = _null_window_to_landscape
-
-
-def get_device_orientation():
-       bus = dbus.SystemBus()
-       try:
-               rawMceRequest = bus.get_object("com.nokia.mce", "/com/nokia/mce/request")
-               mceRequest = dbus.Interface(rawMceRequest, dbus_interface="com.nokia.mce.request")
-               orientation, standState, faceState, xAxis, yAxis, zAxis = mceRequest.get_device_orientation()
-       except dbus.exception.DBusException:
-               # catching for documentation purposes that when a system doesn't
-               # support this, this is what to expect
-               raise
-
-       if orientation == "":
-               return gtk.ORIENTATION_HORIZONTAL
-       elif orientation == "":
-               return gtk.ORIENTATION_VERTICAL
-       else:
-               raise RuntimeError("Unknown orientation: %s" % orientation)
-
-
-def _hildon_hildonize_password_entry(textEntry):
-       textEntry.set_property('hildon-input-mode', 7 | (1 << 29))
-
-
-def _null_hildonize_password_entry(textEntry):
-       pass
-
-
-if IS_HILDON_SUPPORTED:
-       hildonize_password_entry = _hildon_hildonize_password_entry
-else:
-       hildonize_password_entry = _null_hildonize_password_entry
-
-
-def _hildon_hildonize_combo_entry(comboEntry):
-       comboEntry.set_property('hildon-input-mode', 1 << 4)
-
-
-def _null_hildonize_combo_entry(textEntry):
-       pass
-
-
-if IS_HILDON_SUPPORTED:
-       hildonize_combo_entry = _hildon_hildonize_combo_entry
-else:
-       hildonize_combo_entry = _null_hildonize_combo_entry
-
-
-def _null_create_seekbar():
-       adjustment = gtk.Adjustment(0, 0, 101, 1, 5, 1)
-       seek = gtk.HScale(adjustment)
-       seek.set_draw_value(False)
-       return seek
-
-
-def _fremantle_create_seekbar():
-       seek = hildon.Seekbar()
-       seek.set_range(0.0, 100)
-       seek.set_draw_value(False)
-       seek.set_update_policy(gtk.UPDATE_DISCONTINUOUS)
-       return seek
-
-
-try:
-       hildon.Seekbar
-       create_seekbar = _fremantle_create_seekbar
-except AttributeError:
-       create_seekbar = _null_create_seekbar
-
-
-def _fremantle_hildonize_scrollwindow(scrolledWindow):
-       pannableWindow = hildon.PannableArea()
-
-       child = scrolledWindow.get_child()
-       scrolledWindow.remove(child)
-       pannableWindow.add(child)
-
-       parent = scrolledWindow.get_parent()
-       if parent is not None:
-               parent.remove(scrolledWindow)
-               parent.add(pannableWindow)
-
-       return pannableWindow
-
-
-def _hildon_hildonize_scrollwindow(scrolledWindow):
-       hildon.hildon_helper_set_thumb_scrollbar(scrolledWindow, True)
-       return scrolledWindow
-
-
-def _null_hildonize_scrollwindow(scrolledWindow):
-       return scrolledWindow
-
-
-try:
-       hildon.PannableArea
-       hildonize_scrollwindow = _fremantle_hildonize_scrollwindow
-       hildonize_scrollwindow_with_viewport = _hildon_hildonize_scrollwindow
-except AttributeError:
-       try:
-               hildon.hildon_helper_set_thumb_scrollbar
-               hildonize_scrollwindow = _hildon_hildonize_scrollwindow
-               hildonize_scrollwindow_with_viewport = _hildon_hildonize_scrollwindow
-       except AttributeError:
-               hildonize_scrollwindow = _null_hildonize_scrollwindow
-               hildonize_scrollwindow_with_viewport = _null_hildonize_scrollwindow
-
-
-def _hildon_request_number(parent, title, range, default):
-       spinner = hildon.NumberEditor(*range)
-       spinner.set_value(default)
-
-       dialog = gtk.Dialog(
-               title,
-               parent,
-               gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
-               (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
-       )
-       dialog.set_default_response(gtk.RESPONSE_CANCEL)
-       dialog.get_child().add(spinner)
-
-       try:
-               dialog.show_all()
-               response = dialog.run()
-
-               if response == gtk.RESPONSE_OK:
-                       return spinner.get_value()
-               elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
-                       raise RuntimeError("User cancelled request")
-               else:
-                       raise RuntimeError("Unrecognized response %r", response)
-       finally:
-               dialog.hide()
-               dialog.destroy()
-
-
-def _null_request_number(parent, title, range, default):
-       adjustment = gtk.Adjustment(default, range[0], range[1], 1, 5, 0)
-       spinner = gtk.SpinButton(adjustment, 0, 0)
-       spinner.set_wrap(False)
-
-       dialog = gtk.Dialog(
-               title,
-               parent,
-               gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
-               (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
-       )
-       dialog.set_default_response(gtk.RESPONSE_CANCEL)
-       dialog.get_child().add(spinner)
-
-       try:
-               dialog.show_all()
-               response = dialog.run()
-
-               if response == gtk.RESPONSE_OK:
-                       return spinner.get_value_as_int()
-               elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
-                       raise RuntimeError("User cancelled request")
-               else:
-                       raise RuntimeError("Unrecognized response %r", response)
-       finally:
-               dialog.hide()
-               dialog.destroy()
-
-
-try:
-       hildon.NumberEditor # TODO deprecated in fremantle
-       request_number = _hildon_request_number
-except AttributeError:
-       request_number = _null_request_number
-
-
-def _hildon_touch_selector(parent, title, items, defaultIndex):
-       model = gtk.ListStore(gobject.TYPE_STRING)
-       for item in items:
-               model.append((item, ))
-
-       selector = hildon.TouchSelector()
-       selector.append_text_column(model, True)
-       selector.set_column_selection_mode(hildon.TOUCH_SELECTOR_SELECTION_MODE_SINGLE)
-       selector.set_active(0, defaultIndex)
-
-       dialog = hildon.PickerDialog(parent)
-       dialog.set_selector(selector)
-
-       try:
-               dialog.show_all()
-               response = dialog.run()
-
-               if response == gtk.RESPONSE_OK:
-                       return selector.get_active(0)
-               elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
-                       raise RuntimeError("User cancelled request")
-               else:
-                       raise RuntimeError("Unrecognized response %r", response)
-       finally:
-               dialog.hide()
-               dialog.destroy()
-
-
-def _on_null_touch_selector_activated(treeView, path, column, dialog, pathData):
-       dialog.response(gtk.RESPONSE_OK)
-       pathData[0] = path
-
-
-def _null_touch_selector(parent, title, items, defaultIndex = -1):
-       parentSize = parent.get_size()
-
-       model = gtk.ListStore(gobject.TYPE_STRING)
-       for item in items:
-               model.append((item, ))
-
-       cell = gtk.CellRendererText()
-       set_cell_thumb_selectable(cell)
-       column = gtk.TreeViewColumn(title)
-       column.pack_start(cell, expand=True)
-       column.add_attribute(cell, "text", 0)
-
-       treeView = gtk.TreeView()
-       treeView.set_model(model)
-       treeView.append_column(column)
-       selection = treeView.get_selection()
-       selection.set_mode(gtk.SELECTION_SINGLE)
-       if 0 < defaultIndex:
-               selection.select_path((defaultIndex, ))
-
-       scrolledWin = gtk.ScrolledWindow()
-       scrolledWin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-       scrolledWin.add(treeView)
-
-       dialog = gtk.Dialog(
-               title,
-               parent,
-               gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
-               (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
-       )
-       dialog.set_default_response(gtk.RESPONSE_CANCEL)
-       dialog.get_child().add(scrolledWin)
-       dialog.resize(parentSize[0], max(parentSize[1]-100, 100))
-
-       scrolledWin = hildonize_scrollwindow(scrolledWin)
-       pathData = [None]
-       treeView.connect("row-activated", _on_null_touch_selector_activated, dialog, pathData)
-
-       try:
-               dialog.show_all()
-               response = dialog.run()
-
-               if response == gtk.RESPONSE_OK:
-                       if pathData[0] is None:
-                               raise RuntimeError("No selection made")
-                       return pathData[0][0]
-               elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
-                       raise RuntimeError("User cancelled request")
-               else:
-                       raise RuntimeError("Unrecognized response %r", response)
-       finally:
-               dialog.hide()
-               dialog.destroy()
-
-
-try:
-       hildon.PickerDialog
-       hildon.TouchSelector
-       touch_selector = _hildon_touch_selector
-except AttributeError:
-       touch_selector = _null_touch_selector
-
-
-def _hildon_touch_selector_entry(parent, title, items, defaultItem):
-       # Got a segfault when using append_text_column with TouchSelectorEntry, so using this way
-       try:
-               selector = hildon.TouchSelectorEntry(text=True)
-       except TypeError:
-               selector = hildon.hildon_touch_selector_entry_new_text()
-       defaultIndex = -1
-       for i, item in enumerate(items):
-               selector.append_text(item)
-               if item == defaultItem:
-                       defaultIndex = i
-
-       dialog = hildon.PickerDialog(parent)
-       dialog.set_selector(selector)
-
-       if 0 < defaultIndex:
-               selector.set_active(0, defaultIndex)
-       else:
-               selector.get_entry().set_text(defaultItem)
-
-       try:
-               dialog.show_all()
-               response = dialog.run()
-       finally:
-               dialog.hide()
-
-       if response == gtk.RESPONSE_OK:
-               return selector.get_entry().get_text()
-       elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
-               raise RuntimeError("User cancelled request")
-       else:
-               raise RuntimeError("Unrecognized response %r", response)
-
-
-def _on_null_touch_selector_entry_entry_changed(entry, result, selection, defaultIndex):
-       custom = entry.get_text().strip()
-       if custom:
-               result[0] = custom
-               selection.unselect_all()
-       else:
-               result[0] = None
-               selection.select_path((defaultIndex, ))
-
-
-def _on_null_touch_selector_entry_entry_activated(customEntry, dialog, result):
-       dialog.response(gtk.RESPONSE_OK)
-       result[0] = customEntry.get_text()
-
-
-def _on_null_touch_selector_entry_tree_activated(treeView, path, column, dialog, result):
-       dialog.response(gtk.RESPONSE_OK)
-       model = treeView.get_model()
-       itr = model.get_iter(path)
-       if itr is not None:
-               result[0] = model.get_value(itr, 0)
-
-
-def _null_touch_selector_entry(parent, title, items, defaultItem):
-       parentSize = parent.get_size()
-
-       model = gtk.ListStore(gobject.TYPE_STRING)
-       defaultIndex = -1
-       for i, item in enumerate(items):
-               model.append((item, ))
-               if item == defaultItem:
-                       defaultIndex = i
-
-       cell = gtk.CellRendererText()
-       set_cell_thumb_selectable(cell)
-       column = gtk.TreeViewColumn(title)
-       column.pack_start(cell, expand=True)
-       column.add_attribute(cell, "text", 0)
-
-       treeView = gtk.TreeView()
-       treeView.set_model(model)
-       treeView.append_column(column)
-       selection = treeView.get_selection()
-       selection.set_mode(gtk.SELECTION_SINGLE)
-
-       scrolledWin = gtk.ScrolledWindow()
-       scrolledWin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-       scrolledWin.add(treeView)
-
-       customEntry = gtk.Entry()
-
-       layout = gtk.VBox()
-       layout.pack_start(customEntry, expand=False)
-       layout.pack_start(scrolledWin)
-
-       dialog = gtk.Dialog(
-               title,
-               parent,
-               gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
-               (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
-       )
-       dialog.set_default_response(gtk.RESPONSE_CANCEL)
-       dialog.get_child().add(layout)
-       dialog.resize(parentSize[0], max(parentSize[1]-100, 100))
-
-       scrolledWin = hildonize_scrollwindow(scrolledWin)
-
-       result = [None]
-       if 0 < defaultIndex:
-               selection.select_path((defaultIndex, ))
-               result[0] = defaultItem
-       else:
-               customEntry.set_text(defaultItem)
-
-       customEntry.connect("activate", _on_null_touch_selector_entry_entry_activated, dialog, result)
-       customEntry.connect("changed", _on_null_touch_selector_entry_entry_changed, result, selection, defaultIndex)
-       treeView.connect("row-activated", _on_null_touch_selector_entry_tree_activated, dialog, result)
-
-       try:
-               dialog.show_all()
-               response = dialog.run()
-
-               if response == gtk.RESPONSE_OK:
-                       _, itr = selection.get_selected()
-                       if itr is not None:
-                               return model.get_value(itr, 0)
-                       else:
-                               enteredText = customEntry.get_text().strip()
-                               if enteredText:
-                                       return enteredText
-                               elif result[0] is not None:
-                                       return result[0]
-                               else:
-                                       raise RuntimeError("No selection made")
-               elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
-                       raise RuntimeError("User cancelled request")
-               else:
-                       raise RuntimeError("Unrecognized response %r", response)
-       finally:
-               dialog.hide()
-               dialog.destroy()
-
-
-try:
-       hildon.PickerDialog
-       hildon.TouchSelectorEntry
-       touch_selector_entry = _hildon_touch_selector_entry
-except AttributeError:
-       touch_selector_entry = _null_touch_selector_entry
-
-
-if __name__ == "__main__":
-       app = get_app_class()()
-
-       label = gtk.Label("Hello World from a Label!")
-
-       win = gtk.Window()
-       win.add(label)
-       win = hildonize_window(app, win)
-       if False and IS_FREMANTLE_SUPPORTED:
-               appMenu = hildon.AppMenu()
-               for i in xrange(5):
-                       b = gtk.Button(str(i))
-                       appMenu.append(b)
-               win.set_app_menu(appMenu)
-               win.show_all()
-               appMenu.show_all()
-               gtk.main()
-       elif False:
-               print touch_selector(win, "Test", ["A", "B", "C", "D"], 2)
-       elif False:
-               print touch_selector_entry(win, "Test", ["A", "B", "C", "D"], "C")
-               print touch_selector_entry(win, "Test", ["A", "B", "C", "D"], "Blah")
-       elif False:
-               import pprint
-               name, value = "", ""
-               goodLocals = [
-                       (name, value) for (name, value) in locals().iteritems()
-                       if not name.startswith("_")
-               ]
-               pprint.pprint(goodLocals)
-       elif False:
-               import time
-               show_information_banner(win, "Hello World")
-               time.sleep(5)
-       elif False:
-               import time
-               banner = show_busy_banner_start(win, "Hello World")
-               time.sleep(5)
-               show_busy_banner_end(banner)
diff --git a/src/libraries/gtkpie.py b/src/libraries/gtkpie.py
deleted file mode 100755 (executable)
index 80e3d52..0000000
+++ /dev/null
@@ -1,794 +0,0 @@
-#!/usr/bin/env python
-
-"""
-@todo Handle sizing in a better manner http://www.gtkmm.org/docs/gtkmm-2.4/docs/tutorial/html/sec-custom-widgets.html
-"""
-
-
-from __future__ import division
-
-import os
-import weakref
-import math
-import copy
-import warnings
-
-import gobject
-import gtk
-import cairo
-import pango
-
-try:
-       import rsvg
-except ImportError:
-       rsvg = None
-
-
-def deg_to_rad(deg):
-       return (2 * math.pi * deg) / 360.0
-
-
-def rad_to_deg(rad):
-       return (360.0 * rad) / (2 * math.pi)
-
-
-def normalize_radian_angle(radAng):
-       """
-       Restricts @param radAng to the range [0..2pi)
-       """
-       twoPi = 2 * math.pi
-
-       while radAng < 0:
-               radAng += twoPi
-       while twoPi <= radAng:
-               radAng -= twoPi
-
-       return radAng
-
-
-def delta_to_rtheta(dx, dy):
-       distance = math.sqrt(dx**2 + dy**2)
-
-       angleInRads = math.atan2(-dy, dx)
-       if angleInRads < 0:
-               angleInRads = 2*math.pi + angleInRads
-       return distance, angleInRads
-
-
-class FontCache(object):
-
-       def __init__(self):
-               self.__fontCache = {}
-
-       def get_font(self, s):
-               if s in self.__fontCache:
-                       return self.__fontCache[s]
-
-               descr = pango.FontDescription(s)
-               self.__fontCache[s] = descr
-
-               return descr
-
-
-FONTS = FontCache()
-
-
-class ImageCache(object):
-
-       def __init__(self):
-               self.__imageCache = {}
-               self.__imagePaths = [
-                       os.path.join(os.path.dirname(__file__), "images"),
-               ]
-
-       def add_path(self, path):
-               self.__imagePaths.append(path)
-
-       def get_image(self, s):
-               if s in self.__imageCache:
-                       return self.__imageCache[s]
-
-               image = None
-
-               if s.lower().endswith(".png"):
-                       for path in self.__imagePaths:
-                               imagePath = os.path.join(path, s)
-                               try:
-                                       image = cairo.ImageSurface.create_from_png(imagePath)
-                                       break
-                               except:
-                                       warnings.warn("Unable to load image %s" % imagePath)
-               elif s.lower().endswith(".svg") and rsvg is not None:
-                       for path in self.__imagePaths:
-                               imagePath = os.path.join(path, s)
-                               try:
-                                       image = rsvg.Handle(file=imagePath)
-                               except:
-                                       warnings.warn("Unable to load image %s" % imagePath)
-               else:
-                       print "Don't know how to load image file type:", s
-
-               if image is not None:
-                       self.__imageCache[s] = image
-
-               return image
-
-
-IMAGES = ImageCache()
-
-
-def convert_color(gtkColor):
-       r = gtkColor.red / 65535
-       g = gtkColor.green / 65535
-       b = gtkColor.blue / 65535
-       return r, g, b
-
-
-def generate_pie_style(widget):
-       # GTK states:
-       # * gtk.STATE_NORMAL - The state of a sensitive widget that is not active and does not have the focus
-       # * gtk.STATE_ACTIVE - The state of a sensitive widget when it is active e.g. a button that is pressed but not yet released
-       # * gtk.STATE_PRELIGHT - The state of a sensitive widget that has the focus e.g. a button that has the mouse pointer over it.
-       # * gtk.STATE_SELECTED - The state of a widget that is selected e.g. selected text in a gtk.Entry widget
-       # * gtk.STATE_INSENSITIVE - The state of a widget that is insensitive and will not respond to any events e.g. cannot be activated, selected or prelit.
-
-       widget.ensure_style()
-       gtkStyle = widget.get_style()
-       sliceStyle = dict(
-               (gtkStyleState, {
-                       "text": convert_color(gtkStyle.text[gtkStyleState]),
-                       "fill": convert_color(gtkStyle.bg[gtkStyleState]),
-                       "stroke": None,
-               })
-               for gtkStyleState in (
-                       gtk.STATE_NORMAL, gtk.STATE_ACTIVE, gtk.STATE_PRELIGHT, gtk.STATE_SELECTED, gtk.STATE_INSENSITIVE
-               )
-       )
-
-       return sliceStyle
-
-
-class PieSlice(object):
-
-       SLICE_CENTER = 0
-       SLICE_EAST = 1
-       SLICE_SOUTH_EAST = 2
-       SLICE_SOUTH = 3
-       SLICE_SOUTH_WEST = 4
-       SLICE_WEST = 5
-       SLICE_NORTH_WEST = 6
-       SLICE_NORTH = 7
-       SLICE_NORTH_EAST = 8
-
-       MAX_ANGULAR_SLICES = 8
-
-       SLICE_DIRECTIONS = [
-               SLICE_CENTER,
-               SLICE_EAST,
-               SLICE_SOUTH_EAST,
-               SLICE_SOUTH,
-               SLICE_SOUTH_WEST,
-               SLICE_WEST,
-               SLICE_NORTH_WEST,
-               SLICE_NORTH,
-               SLICE_NORTH_EAST,
-       ]
-
-       SLICE_DIRECTION_NAMES = [
-               "CENTER",
-               "EAST",
-               "SOUTH_EAST",
-               "SOUTH",
-               "SOUTH_WEST",
-               "WEST",
-               "NORTH_WEST",
-               "NORTH",
-               "NORTH_EAST",
-       ]
-
-       def __init__(self, handler = (lambda p, s, d: None)):
-               self._direction = self.SLICE_CENTER
-               self._pie = None
-               self._style = None
-               self._handler = handler
-
-       def menu_init(self, pie, direction):
-               self._direction = direction
-               self._pie = weakref.ref(pie)
-               self._style = pie.sliceStyle
-
-       def calculate_minimum_radius(self, context, textLayout):
-               return 0
-
-       def draw_fg(self, styleState, isSelected, context, textLayout):
-               if isSelected:
-                       styleState = gtk.STATE_ACTIVE
-               self._draw_fg(styleState, context, textLayout)
-
-       def draw_bg(self, styleState, isSelected, context, textLayout):
-               if isSelected:
-                       styleState = gtk.STATE_ACTIVE
-               self._draw_bg(styleState, context, textLayout)
-
-       def _draw_fg(self, styleState, context, textLayout):
-               pass
-
-       def _draw_bg(self, styleState, context, textLayout):
-               centerPosition = self._pie().centerPosition
-               radius = max(self._pie().radius, self.calculate_minimum_radius(context, textLayout))
-               outerRadius = self._pie().outerRadius
-
-               fillColor = self._style[styleState]["fill"]
-               if not fillColor:
-                       return
-
-               if self._direction == self.SLICE_CENTER:
-                       context.arc(
-                               centerPosition[0],
-                               centerPosition[1],
-                               radius,
-                               0,
-                               2 * math.pi
-                       )
-
-                       context.set_source_rgb(*fillColor)
-                       context.fill()
-               else:
-                       sliceCenterAngle = self.quadrant_to_theta(self._direction)
-                       sliceArcWidth = 2*math.pi / self.MAX_ANGULAR_SLICES
-                       sliceStartAngle = sliceCenterAngle - sliceArcWidth/2
-                       sliceEndAngle = sliceCenterAngle + sliceArcWidth/2
-
-                       context.arc(
-                               centerPosition[0],
-                               centerPosition[1],
-                               radius,
-                               sliceStartAngle,
-                               sliceEndAngle,
-                       )
-                       context.arc_negative(
-                               centerPosition[0],
-                               centerPosition[1],
-                               outerRadius,
-                               sliceEndAngle,
-                               sliceStartAngle,
-                       )
-                       context.close_path()
-
-                       context.set_source_rgb(*fillColor)
-                       context.fill()
-
-       def activate(self):
-               self._handler(self._pie(), self, self._direction)
-
-       @classmethod
-       def rtheta_to_quadrant(cls, distance, angleInRads, innerRadius):
-               if distance < innerRadius:
-                       quadrant = 0
-               else:
-                       gradians = angleInRads / (2*math.pi)
-                       preciseQuadrant = gradians * cls.MAX_ANGULAR_SLICES + cls.MAX_ANGULAR_SLICES / (2 * 2*math.pi)
-                       quadrantWithWrap = int(preciseQuadrant)
-                       quadrant = quadrantWithWrap % cls.MAX_ANGULAR_SLICES
-                       quadrant += 1
-
-               return quadrant
-
-       @classmethod
-       def quadrant_to_theta(cls, quadrant):
-               assert quadrant != 0
-               quadrant -= 1
-
-               gradians = quadrant / cls.MAX_ANGULAR_SLICES
-               radians = gradians * 2*math.pi
-
-               return radians
-
-
-class NullPieSlice(PieSlice):
-
-       def draw_bg(self, styleState, isSelected, context, textLayout):
-               super(NullPieSlice, self).draw_bg(styleState, False, context, textLayout)
-
-
-class LabelPieSlice(PieSlice):
-
-       def _align_label(self, labelWidth, labelHeight):
-               centerPosition = self._pie().centerPosition
-               if self._direction == PieSlice.SLICE_CENTER:
-                       labelX = centerPosition[0] - labelWidth/2
-                       labelY = centerPosition[1] - labelHeight/2
-               else:
-                       if self._direction in (PieSlice.SLICE_NORTH_WEST, PieSlice.SLICE_WEST, PieSlice.SLICE_SOUTH_WEST):
-                               outerX = 0
-                               labelX = outerX
-                       elif self._direction in (PieSlice.SLICE_SOUTH, PieSlice.SLICE_NORTH):
-                               outerX = centerPosition[0]
-                               labelX = outerX - labelWidth/2
-                       elif self._direction in (PieSlice.SLICE_NORTH_EAST, PieSlice.SLICE_EAST, PieSlice.SLICE_SOUTH_EAST):
-                               outerX = centerPosition[0] * 2
-                               labelX = outerX - labelWidth
-                       else:
-                               assert False, "Direction %d is incorrect" % self._direction
-
-                       if self._direction in (PieSlice.SLICE_NORTH_EAST, PieSlice.SLICE_NORTH, PieSlice.SLICE_NORTH_WEST):
-                               outerY = 0
-                               labelY = outerY
-                       elif self._direction in (PieSlice.SLICE_EAST, PieSlice.SLICE_WEST):
-                               outerY = centerPosition[1]
-                               labelY = outerY - labelHeight/2
-                       elif self._direction in (PieSlice.SLICE_SOUTH_EAST, PieSlice.SLICE_SOUTH, PieSlice.SLICE_SOUTH_WEST):
-                               outerY = centerPosition[1] * 2
-                               labelY = outerY - labelHeight
-                       else:
-                               assert False, "Direction %d is incorrect" % self._direction
-
-               return int(labelX), int(labelY)
-
-
-class TextLabelPieSlice(LabelPieSlice):
-
-       def __init__(self, text, fontName = 'Helvetica 12', handler = (lambda p, s, d: None)):
-               super(TextLabelPieSlice, self).__init__(handler = handler)
-               self.__text = text
-               self.__fontName = fontName
-
-       def calculate_minimum_radius(self, context, textLayout):
-               font = FONTS.get_font(self.__fontName)
-               textLayout.set_font_description(font)
-               textLayout.set_markup(self.__text)
-
-               labelWidth, labelHeight = textLayout.get_pixel_size()
-               return min(labelWidth, labelHeight) / 2
-
-       def _draw_fg(self, styleState, context, textLayout):
-               super(TextLabelPieSlice, self)._draw_fg(styleState, context, textLayout)
-
-               textColor = self._style[styleState]["text"]
-               font = FONTS.get_font(self.__fontName)
-
-               context.set_source_rgb(*textColor)
-               textLayout.set_font_description(font)
-               textLayout.set_markup(self.__text)
-               labelWidth, labelHeight = textLayout.get_pixel_size()
-               labelX, labelY = self._align_label(labelWidth, labelHeight)
-
-               context.move_to(
-                       labelX,
-                       labelY,
-               )
-
-               context.show_layout(textLayout)
-
-
-class ImageLabelPieSlice(LabelPieSlice):
-
-       def __init__(self, imagePath, handler = (lambda p, s, d: None)):
-               super(ImageLabelPieSlice, self).__init__(handler = handler)
-               self.__imagePath = imagePath
-
-       def calculate_minimum_radius(self, context, textLayout):
-               image = IMAGES.get_image(self.__imagePath)
-               if image is None:
-                       return
-               labelWidth, labelHeight = image.get_width(), image.get_height()
-               return min(labelWidth, labelHeight) / 2
-
-       def _draw_fg(self, styleState, context, textLayout):
-               super(ImageLabelPieSlice, self)._draw_fg(styleState, context, textLayout)
-
-               image = IMAGES.get_image(self.__imagePath)
-               if image is None:
-                       return
-
-               labelWidth, labelHeight = image.get_width(), image.get_height()
-               labelX, labelY = self._align_label(labelWidth, labelHeight)
-
-               context.set_source_surface(
-                       image,
-                       labelX,
-                       labelY,
-               )
-
-               context.paint()
-
-
-class PieMenu(gtk.DrawingArea):
-
-       def __init__(self, style = None, **kwds):
-               super(PieMenu, self).__init__()
-
-               self.sliceStyle = style
-               self.centerPosition = 0, 0
-               self.radius = 20
-               self.outerRadius = self.radius * 2
-
-               self.connect("expose_event", self._on_expose)
-               self.connect("motion_notify_event", self._on_motion_notify)
-               self.connect("leave_notify_event", self._on_leave_notify)
-               self.connect("proximity_in_event", self._on_motion_notify)
-               self.connect("proximity_out_event", self._on_leave_notify)
-               self.connect("button_press_event", self._on_button_press)
-               self.connect("button_release_event", self._on_button_release)
-
-               self.set_events(
-                       gtk.gdk.EXPOSURE_MASK |
-                       gtk.gdk.POINTER_MOTION_MASK |
-                       gtk.gdk.POINTER_MOTION_HINT_MASK |
-                       gtk.gdk.BUTTON_MOTION_MASK |
-                       gtk.gdk.BUTTON_PRESS_MASK |
-                       gtk.gdk.BUTTON_RELEASE_MASK |
-                       gtk.gdk.PROXIMITY_IN_MASK |
-                       gtk.gdk.PROXIMITY_OUT_MASK |
-                       gtk.gdk.LEAVE_NOTIFY_MASK
-               )
-
-               self.__activeSlice = None
-               self.__slices = {}
-               for direction in PieSlice.SLICE_DIRECTIONS:
-                       self.add_slice(NullPieSlice(), direction)
-
-               self.__clickPosition = 0, 0
-               self.__styleState = gtk.STATE_NORMAL
-
-       def add_slice(self, slice, direction):
-               assert direction in PieSlice.SLICE_DIRECTIONS
-
-               slice.menu_init(self, direction)
-               self.__slices[direction] = slice
-
-               if direction == PieSlice.SLICE_CENTER:
-                       self.__activeSlice = self.__slices[PieSlice.SLICE_CENTER]
-
-       def __update_state(self, mousePosition):
-               rect = self.get_allocation()
-               newStyleState = self.__styleState
-
-               if (
-                       0 <= mousePosition[0] and mousePosition[1] < rect.width and
-                       0 <= mousePosition[1] and mousePosition[1] < rect.height
-               ):
-                       if self.__clickPosition == (0, 0):
-                               newStyleState = gtk.STATE_PRELIGHT
-               else:
-                       if self.__clickPosition != (0, 0):
-                               newStyleState = gtk.STATE_PRELIGHT
-
-               if newStyleState != self.__styleState:
-                       self.__generate_draw_event()
-                       self.__styleState = newStyleState
-
-       def __process_mouse_position(self, mousePosition):
-               self.__update_state(mousePosition)
-               if self.__clickPosition == (0, 0):
-                       return
-
-               delta = (
-                       mousePosition[0] - self.centerPosition[0],
-                       - (mousePosition[1] - self.centerPosition[1])
-               )
-               distance, angleInRads = delta_to_rtheta(delta[0], delta[1])
-               quadrant = PieSlice.rtheta_to_quadrant(distance, angleInRads, self.radius)
-               self.__select_slice(self.__slices[quadrant])
-
-       def __select_slice(self, newSlice):
-               if newSlice is self.__activeSlice:
-                       return
-
-               oldSlice = self.__activeSlice
-               self.__activeSlice = newSlice
-               self.__generate_draw_event()
-
-       def __generate_draw_event(self):
-               if self.window is None:
-                       return
-               self.queue_draw()
-
-       def _on_expose(self, widget, event):
-               cairoContext = self.window.cairo_create()
-               pangoContext = self.create_pango_context()
-               textLayout = pango.Layout(pangoContext)
-
-               rect = self.get_allocation()
-               position = 0, 0
-               dimensions = rect.width, rect.height
-
-               self.centerPosition = position[0] + dimensions[0] / 2, position[1] + dimensions[1] / 2
-               self.outerRadius = max(*dimensions) # be larger than the view
-               self.radius = self.outerRadius / (3*2) # fit inside the middle cell
-
-               # Draw Background
-               cairoContext.rectangle(
-                       position[0],
-                       position[1],
-                       dimensions[0],
-                       dimensions[1],
-               )
-               cairoContext.set_source_rgb(*self.sliceStyle[self.__styleState]["fill"])
-               cairoContext.fill()
-
-               isSelected = self.__clickPosition != (0, 0)
-               self.__activeSlice.draw_bg(self.__styleState, isSelected, cairoContext, textLayout)
-
-               # Draw Foreground
-               for slice in self.__slices.itervalues():
-                       isSelected = (slice is self.__activeSlice)
-                       if not isSelected:
-                               slice.draw_fg(self.__styleState, isSelected, cairoContext, textLayout)
-
-               isSelected = self.__clickPosition != (0, 0)
-               self.__activeSlice.draw_fg(self.__styleState, isSelected, cairoContext, textLayout)
-
-       def _on_leave_notify(self, widget, event):
-               newStyleState = gtk.STATE_NORMAL
-               if newStyleState != self.__styleState:
-                       self.__generate_draw_event()
-                       self.__styleState = newStyleState
-
-               mousePosition = event.get_coords()
-               self.__process_mouse_position(mousePosition)
-
-       def _on_motion_notify(self, widget, event):
-               mousePosition = event.get_coords()
-               self.__process_mouse_position(mousePosition)
-
-       def _on_button_press(self, widget, event):
-               self.__clickPosition = event.get_coords()
-
-               self._on_motion_notify(widget, event)
-               self.__generate_draw_event()
-
-       def _on_button_release(self, widget, event):
-               self._on_motion_notify(widget, event)
-
-               self.__activeSlice.activate()
-               self.__activeSlice = self.__slices[PieSlice.SLICE_CENTER]
-               self.__clickPosition = 0, 0
-
-               self.__generate_draw_event()
-
-
-gobject.type_register(PieMenu)
-
-
-class FakeEvent(object):
-
-       def __init__(self, x, y, isHint):
-               self.x = x
-               self.y = y
-               self.is_hint = isHint
-
-       def get_coords(self):
-               return self.x, self.y
-
-
-class PiePopup(gtk.DrawingArea):
-
-       def __init__(self, style = None, **kwds):
-               super(PiePopup, self).__init__()
-
-               self.showAllSlices = True
-               self.sliceStyle = style
-               self.centerPosition = 0, 0
-               self.radius = 20
-               self.outerRadius = self.radius * 2
-
-               self.connect("expose_event", self._on_expose)
-               self.connect("motion_notify_event", self._on_motion_notify)
-               self.connect("proximity_in_event", self._on_motion_notify)
-               self.connect("proximity_out_event", self._on_leave_notify)
-               self.connect("leave_notify_event", self._on_leave_notify)
-               self.connect("button_press_event", self._on_button_press)
-               self.connect("button_release_event", self._on_button_release)
-
-               self.set_events(
-                       gtk.gdk.EXPOSURE_MASK |
-                       gtk.gdk.POINTER_MOTION_MASK |
-                       gtk.gdk.POINTER_MOTION_HINT_MASK |
-                       gtk.gdk.BUTTON_MOTION_MASK |
-                       gtk.gdk.BUTTON_PRESS_MASK |
-                       gtk.gdk.BUTTON_RELEASE_MASK |
-                       gtk.gdk.PROXIMITY_IN_MASK |
-                       gtk.gdk.PROXIMITY_OUT_MASK |
-                       gtk.gdk.LEAVE_NOTIFY_MASK
-               )
-
-               self.__popped = False
-               self.__styleState = gtk.STATE_NORMAL
-               self.__activeSlice = None
-               self.__slices = {}
-               self.__localSlices = {}
-
-               self.__clickPosition = 0, 0
-               self.__popupTimeDelay = None
-
-               self.__pie = None
-               self.__pie = PieMenu(self.sliceStyle)
-               self.__pie.connect("button_release_event", self._on_button_release)
-               self.__pie.show()
-
-               self.__popupWindow = gtk.Window(type = gtk.WINDOW_POPUP)
-               self.__popupWindow.set_title("")
-               self.__popupWindow.add(self.__pie)
-
-               self.add_slice(NullPieSlice(), PieSlice.SLICE_CENTER)
-
-       def add_slice(self, slice, direction):
-               assert direction in PieSlice.SLICE_DIRECTIONS
-
-               self.__pie.add_slice(copy.copy(slice), direction)
-
-               if self.showAllSlices or direction == PieSlice.SLICE_CENTER:
-                       self.__localSlices[direction] = slice
-                       self.__localSlices[direction].menu_init(self, direction)
-               if direction == PieSlice.SLICE_CENTER:
-                       self.__activeSlice = self.__localSlices[PieSlice.SLICE_CENTER]
-
-       def __update_state(self, mousePosition):
-               rect = self.get_allocation()
-               newStyleState = self.__styleState
-
-               if (
-                       0 <= mousePosition[0] and mousePosition[0] < rect.width and
-                       0 <= mousePosition[1] and mousePosition[1] < rect.height
-               ):
-                       if self.__clickPosition == (0, 0):
-                               newStyleState = gtk.STATE_PRELIGHT
-               else:
-                       if self.__clickPosition != (0, 0):
-                               newStyleState = gtk.STATE_PRELIGHT
-
-               if newStyleState != self.__styleState:
-                       self.__styleState = newStyleState
-                       self.__generate_draw_event()
-
-       def __generate_draw_event(self):
-               self.queue_draw()
-
-       def _on_expose(self, widget, event):
-               rect = self.get_allocation()
-               position = 0, 0
-               dimensions = rect.width, rect.height
-
-               # update sizing information
-               self.centerPosition = position[0] + dimensions[0] / 2, position[1] + dimensions[1] / 2
-               self.outerRadius = max(*dimensions) # be larger than the view
-               self.radius = self.outerRadius / (3*2) # fit inside the middle cell
-
-               # Draw Background
-               cairoContext = self.window.cairo_create()
-               cairoContext.rectangle(
-                       position[0],
-                       position[1],
-                       dimensions[0],
-                       dimensions[1],
-               )
-               cairoContext.set_source_rgb(*self.sliceStyle[self.__styleState]["fill"])
-               cairoContext.fill()
-
-               # Draw Foreground
-               pangoContext = self.create_pango_context()
-               textLayout = pango.Layout(pangoContext)
-               for slice in self.__localSlices.itervalues():
-                       isSelected = (slice is self.__activeSlice)
-                       if not isSelected:
-                               slice.draw_fg(self.__styleState, isSelected, cairoContext, textLayout)
-
-               isSelected = self.__clickPosition != (0, 0)
-               self.__activeSlice.draw_fg(self.__styleState, isSelected, cairoContext, textLayout)
-
-       def _on_leave_notify(self, widget, event):
-               newStyleState = gtk.STATE_NORMAL
-               if newStyleState != self.__styleState:
-                       self.__styleState = newStyleState
-                       self.__generate_draw_event()
-
-               self._on_motion_notify(widget, event)
-
-       def _on_motion_notify(self, widget, event):
-               self.__update_state(event.get_coords())
-               if not self.__popped:
-                       return
-
-               mousePosition = event.get_root_coords()
-               piePosition = self.__popupWindow.get_position()
-               event.x = mousePosition[0] - piePosition[0]
-               event.y = mousePosition[1] - piePosition[1]
-               self.__pie._on_motion_notify(self.__pie, event)
-
-       def _on_button_press(self, widget, event):
-               if len(self.__localSlices) == 0:
-                       return
-
-               if self.__popupTimeDelay is not None:
-                       # This press is for a double click for which we do not get a release
-                       # self._on_button_release(widget, event)
-                       return
-
-               self.__clickPosition = event.get_root_coords()
-               self.__generate_draw_event()
-               self.__popupTimeDelay = gobject.timeout_add(150, self._on_delayed_popup)
-
-       def _on_delayed_popup(self):
-               self.__popup(self.__clickPosition)
-               gobject.source_remove(self.__popupTimeDelay)
-               self.__popupTimeDelay = None
-               return False
-
-       def _on_button_release(self, widget, event):
-               if len(self.__localSlices) == 0:
-                       return
-
-               if self.__popupTimeDelay is None:
-                       mousePosition = event.get_root_coords()
-                       piePosition = self.__popupWindow.get_position()
-                       eventX = mousePosition[0] - piePosition[0]
-                       eventY = mousePosition[1] - piePosition[1]
-                       pieRelease = FakeEvent(eventX, eventY, False)
-                       self.__pie._on_button_release(self.__pie, pieRelease)
-
-                       self.__unpop()
-               else:
-                       gobject.source_remove(self.__popupTimeDelay)
-                       self.__popupTimeDelay = None
-                       self.__activeSlice.activate()
-
-               self.__clickPosition = 0, 0
-               self.__generate_draw_event()
-
-       def __popup(self, position):
-               assert not self.__popped
-               self.__popped = True
-
-               width, height = 256, 256
-               popupX, popupY = position[0] - width/2, position[1] - height/2
-
-               self.__popupWindow.move(int(popupX), int(popupY))
-               self.__popupWindow.resize(width, height)
-               pieClick = FakeEvent(width/2, height/2, False)
-               self.__pie._on_button_press(self.__pie, pieClick)
-               self.__pie.grab_focus()
-
-               self.__popupWindow.show()
-
-       def __unpop(self):
-               assert self.__popped
-               self.__popped = False
-
-               piePosition = self.__popupWindow.get_position()
-               self.grab_focus()
-
-               self.__popupWindow.hide()
-
-
-gobject.type_register(PiePopup)
-
-
-def pie_main(isPop):
-       win = gtk.Window()
-       win.set_title("Pie Menu Test")
-
-       sliceStyle = generate_pie_style(win)
-       if isPop:
-               target = PiePopup(sliceStyle)
-       else:
-               target = PieMenu(sliceStyle)
-
-       def handler(pie, slice, direction):
-               print pie, slice, direction
-       target.add_slice(TextLabelPieSlice("C", handler=handler), PieSlice.SLICE_CENTER)
-       target.add_slice(TextLabelPieSlice("N", handler=handler), PieSlice.SLICE_NORTH)
-       target.add_slice(TextLabelPieSlice("S", handler=handler), PieSlice.SLICE_SOUTH)
-       target.add_slice(TextLabelPieSlice("E", handler=handler), PieSlice.SLICE_EAST)
-       target.add_slice(TextLabelPieSlice("W", handler=handler), PieSlice.SLICE_WEST)
-
-       win.add(target)
-       win.resize(300, 300)
-       win.connect("destroy", lambda w: gtk.main_quit())
-       win.show_all()
-
-
-if __name__ == "__main__":
-       pie_main(False)
-       pie_main(True)
-       gtk.main()
diff --git a/src/libraries/gtkpieboard.py b/src/libraries/gtkpieboard.py
deleted file mode 100755 (executable)
index c2c7175..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-#!/usr/bin/env python
-
-
-from __future__ import division
-
-import copy
-import warnings
-
-import gobject
-import gtk
-
-import gtkpie
-
-
-class PieKeyboard(gtk.Table):
-
-       def __init__(self, style, rows, columns, alternateStyles=True):
-               super(PieKeyboard, self).__init__(rows, columns, homogeneous=True)
-
-               self.__cells = {}
-               for row in xrange(rows):
-                       for column in xrange(columns):
-                               popup = gtkpie.PiePopup(
-                                       self._alternate_style(row, column, style) if alternateStyles else style
-                               )
-                               self.attach(popup, column, column+1, row, row+1)
-                               self.__cells[(row, column)] = popup
-
-       def add_slice(self, row, column, slice, direction):
-               pie = self.__cells[(row, column)]
-               pie.add_slice(slice, direction)
-
-       def add_slices(self, row, column, slices):
-               pie = self.__cells[(row, column)]
-               for direction, slice in slices.iteritems():
-                       pie.add_slice(slice, direction)
-
-       def get_pie(self, row, column):
-               return self.__cells[(row, column)]
-
-       @classmethod
-       def _alternate_style(cls, row, column, style):
-               i = row + column
-               isEven = (i % 2) == 0
-
-               if not isEven:
-                       return style
-
-               altStyle = copy.copy(style)
-               selected = altStyle[True]
-               notSelected = altStyle[False]
-               altStyle[False] = selected
-               altStyle[True] = notSelected
-               return altStyle
-
-
-class KeyboardModifier(object):
-
-       def __init__(self, name):
-               self.name = name
-               self.lock = False
-               self.once = False
-
-       @property
-       def isActive(self):
-               return self.lock or self.once
-
-       def on_toggle_lock(self, *args, **kwds):
-               self.lock = not self.lock
-
-       def on_toggle_once(self, *args, **kwds):
-               self.once = not self.once
-
-       def reset_once(self):
-               self.once = False
-
-
-gobject.type_register(PieKeyboard)
-
-
-def parse_keyboard_data(text):
-       return eval(text)
-
-
-def load_keyboard(keyboardName, dataTree, keyboard, keyboardHandler):
-       for (row, column), pieData in dataTree.iteritems():
-               showAllSlices = pieData["showAllSlices"]
-               keyboard.get_pie(row, column).showAllSlices = showAllSlices
-               for direction, directionName in enumerate(gtkpie.PieSlice.SLICE_DIRECTION_NAMES):
-                       if directionName not in pieData:
-                               continue
-                       sliceName = "%s-(%d, %d)-%s" % (keyboardName, row, column, directionName)
-
-                       sliceData = pieData[directionName]
-                       sliceAction = sliceData["action"]
-                       sliceType = sliceData["type"]
-                       if sliceType == "text":
-                               text = sliceData["text"]
-                               # font = sliceData["font"] # @TODO
-                               slice = gtkpie.TextLabelPieSlice(text, handler=keyboardHandler)
-                       elif sliceType == "image":
-                               path = sliceData["path"]
-                               slice = gtkpie.ImageLabelPieSlice(path, handler=keyboardHandler)
-
-                       slice.name = sliceName
-                       keyboard.add_slice(row, column, slice, direction)
-                       keyboardHandler.map_slice_action(slice, sliceAction)
-
-
-class KeyboardHandler(object):
-
-       def __init__(self, keyhandler):
-               self.__keyhandler = keyhandler
-               self.__commandHandlers = {}
-               self.__modifiers = {}
-               self.__sliceActions = {}
-
-               self.register_modifier("Shift")
-               self.register_modifier("Super")
-               self.register_modifier("Control")
-               self.register_modifier("Alt")
-
-       def register_command_handler(self, command, handler):
-               #@todo Make this handle multiple handlers or switch to gobject events
-               self.__commandHandlers["[%s]" % command] = handler
-
-       def unregister_command_handler(self, command):
-               #@todo Make this handle multiple handlers or switch to gobject events
-               del self.__commandHandlers["[%s]" % command]
-
-       def register_modifier(self, modifierName):
-               mod = KeyboardModifier(modifierName)
-               self.register_command_handler(modifierName, mod.on_toggle_lock)
-               self.__modifiers["<%s>" % modifierName] = mod
-
-       def unregister_modifier(self, modifierName):
-               self.unregister_command_handler(modifierName)
-               del self.__modifiers["<%s>" % modifierName]
-
-       def map_slice_action(self, slice, action):
-               self.__sliceActions[slice.name] = action
-
-       def __call__(self, pie, slice, direction):
-               try:
-                       action = self.__sliceActions[slice.name]
-               except KeyError:
-                       return
-
-               activeModifiers = [
-                       mod.name
-                       for mod in self.__modifiers.itervalues()
-                               if mod.isActive
-               ]
-
-               needResetOnce = False
-               if action.startswith("[") and action.endswith("]"):
-                       commandName = action[1:-1]
-                       if action in self.__commandHandlers:
-                               self.__commandHandlers[action](commandName, activeModifiers)
-                               needResetOnce = True
-                       else:
-                               warnings.warn("Unknown command: [%s]" % commandName)
-               elif action.startswith("<") and action.endswith(">"):
-                       modName = action[1:-1]
-                       for mod in self.__modifiers.itervalues():
-                               if mod.name == modName:
-                                       mod.on_toggle_once()
-                                       break
-                       else:
-                               warnings.warn("Unknown modifier: <%s>" % modName)
-               else:
-                       self.__keyhandler(action, activeModifiers)
-                       needResetOnce = True
-
-               if needResetOnce:
-                       for mod in self.__modifiers.itervalues():
-                               mod.reset_once()
diff --git a/src/libraries/images/alt.png b/src/libraries/images/alt.png
deleted file mode 100644 (file)
index 8ccd110..0000000
Binary files a/src/libraries/images/alt.png and /dev/null differ
diff --git a/src/libraries/images/arrows.png b/src/libraries/images/arrows.png
deleted file mode 100644 (file)
index 6ab51c0..0000000
Binary files a/src/libraries/images/arrows.png and /dev/null differ
diff --git a/src/libraries/images/backspace.png b/src/libraries/images/backspace.png
deleted file mode 100644 (file)
index c8d5506..0000000
Binary files a/src/libraries/images/backspace.png and /dev/null differ
diff --git a/src/libraries/images/clear.png b/src/libraries/images/clear.png
deleted file mode 100644 (file)
index e18eed4..0000000
Binary files a/src/libraries/images/clear.png and /dev/null differ
diff --git a/src/libraries/images/control.png b/src/libraries/images/control.png
deleted file mode 100644 (file)
index f24980e..0000000
Binary files a/src/libraries/images/control.png and /dev/null differ
diff --git a/src/libraries/images/newline.png b/src/libraries/images/newline.png
deleted file mode 100644 (file)
index 8b242f2..0000000
Binary files a/src/libraries/images/newline.png and /dev/null differ
diff --git a/src/libraries/images/shift.png b/src/libraries/images/shift.png
deleted file mode 100644 (file)
index 789d7e3..0000000
Binary files a/src/libraries/images/shift.png and /dev/null differ
diff --git a/src/libraries/images/space.png b/src/libraries/images/space.png
deleted file mode 100644 (file)
index 71207c3..0000000
Binary files a/src/libraries/images/space.png and /dev/null differ
diff --git a/src/libraries/images/super.png b/src/libraries/images/super.png
deleted file mode 100644 (file)
index 6461770..0000000
Binary files a/src/libraries/images/super.png and /dev/null differ
diff --git a/src/libraries/images/symbols.dia b/src/libraries/images/symbols.dia
deleted file mode 100644 (file)
index a04fe5a..0000000
Binary files a/src/libraries/images/symbols.dia and /dev/null differ
diff --git a/src/libraries/images/tab.png b/src/libraries/images/tab.png
deleted file mode 100644 (file)
index 1040cac..0000000
Binary files a/src/libraries/images/tab.png and /dev/null differ
index 52239a0..e2ccd20 100755 (executable)
@@ -1,10 +1,26 @@
 #!/usr/bin/env python
 
 import math
+import logging
 
 from PyQt4 import QtGui
 from PyQt4 import QtCore
 
+try:
+       from util import misc as misc_utils
+except ImportError:
+       class misc_utils(object):
+
+               @staticmethod
+               def log_exception(logger):
+
+                       def wrapper(func):
+                               return func
+                       return wrapper
+
+
+_moduleLogger = logging.getLogger(__name__)
+
 
 _TWOPI = 2 * math.pi
 
@@ -428,17 +444,20 @@ class QPieDisplay(QtGui.QWidget):
        def sizeHint(self):
                return self._artist.pieSize()
 
+       @misc_utils.log_exception(_moduleLogger)
        def showEvent(self, showEvent):
                mask = self._artist.show(self.palette())
                self.setMask(mask)
 
                QtGui.QWidget.showEvent(self, showEvent)
 
+       @misc_utils.log_exception(_moduleLogger)
        def hideEvent(self, hideEvent):
                self._artist.hide()
                self._selectionIndex = PieFiling.SELECTION_NONE
                QtGui.QWidget.hideEvent(self, hideEvent)
 
+       @misc_utils.log_exception(_moduleLogger)
        def paintEvent(self, paintEvent):
                canvas = self._artist.paint(self._selectionIndex)
 
@@ -514,6 +533,7 @@ class QPieButton(QtGui.QWidget):
        def sizeHint(self):
                return self._buttonArtist.pieSize()
 
+       @misc_utils.log_exception(_moduleLogger)
        def mousePressEvent(self, mouseEvent):
                self._popup_child(mouseEvent.globalPos())
                lastSelection = self._selectionIndex
@@ -526,6 +546,7 @@ class QPieButton(QtGui.QWidget):
                        self.highlighted.emit(self._selectionIndex)
                        self._display.selectAt(self._selectionIndex)
 
+       @misc_utils.log_exception(_moduleLogger)
        def mouseMoveEvent(self, mouseEvent):
                lastSelection = self._selectionIndex
 
@@ -541,6 +562,7 @@ class QPieButton(QtGui.QWidget):
                        self.highlighted.emit(self._selectionIndex)
                        self._display.selectAt(self._selectionIndex)
 
+       @misc_utils.log_exception(_moduleLogger)
        def mouseReleaseEvent(self, mouseEvent):
                lastSelection = self._selectionIndex
 
@@ -556,6 +578,7 @@ class QPieButton(QtGui.QWidget):
                self._activate_at(self._selectionIndex)
                self._hide_child()
 
+       @misc_utils.log_exception(_moduleLogger)
        def keyPressEvent(self, keyEvent):
                if keyEvent.key() in [QtCore.Qt.Key_Right, QtCore.Qt.Key_Down, QtCore.Qt.Key_Tab]:
                        self._popup_child(QtGui.QCursor.pos())
@@ -586,17 +609,20 @@ class QPieButton(QtGui.QWidget):
                else:
                        QtGui.QWidget.keyPressEvent(self, keyEvent)
 
+       @misc_utils.log_exception(_moduleLogger)
        def showEvent(self, showEvent):
                self._buttonArtist.show(self.palette())
                self._cachedCenterPosition = self.rect().center()
 
                QtGui.QWidget.showEvent(self, showEvent)
 
+       @misc_utils.log_exception(_moduleLogger)
        def hideEvent(self, hideEvent):
                self._display.hide()
                self._select_at(PieFiling.SELECTION_NONE)
                QtGui.QWidget.hideEvent(self, hideEvent)
 
+       @misc_utils.log_exception(_moduleLogger)
        def paintEvent(self, paintEvent):
                if self._poppedUp:
                        canvas = self._buttonArtist.paint(PieFiling.SELECTION_CENTER)
@@ -608,6 +634,12 @@ class QPieButton(QtGui.QWidget):
 
                QtGui.QWidget.paintEvent(self, paintEvent)
 
+       def __iter__(self):
+               return iter(self._filing)
+
+       def __len__(self):
+               return len(self._filing)
+
        def _popup_child(self, position):
                self._poppedUp = True
                self.aboutToShow.emit()
@@ -714,6 +746,7 @@ class QPieMenu(QtGui.QWidget):
        def sizeHint(self):
                return self._artist.pieSize()
 
+       @misc_utils.log_exception(_moduleLogger)
        def mousePressEvent(self, mouseEvent):
                lastSelection = self._selectionIndex
 
@@ -725,6 +758,7 @@ class QPieMenu(QtGui.QWidget):
                        self.highlighted.emit(self._selectionIndex)
                        self.update()
 
+       @misc_utils.log_exception(_moduleLogger)
        def mouseMoveEvent(self, mouseEvent):
                lastSelection = self._selectionIndex
 
@@ -735,6 +769,7 @@ class QPieMenu(QtGui.QWidget):
                        self.highlighted.emit(self._selectionIndex)
                        self.update()
 
+       @misc_utils.log_exception(_moduleLogger)
        def mouseReleaseEvent(self, mouseEvent):
                lastSelection = self._selectionIndex
 
@@ -745,6 +780,7 @@ class QPieMenu(QtGui.QWidget):
                self._activate_at(self._selectionIndex)
                self.update()
 
+       @misc_utils.log_exception(_moduleLogger)
        def keyPressEvent(self, keyEvent):
                if keyEvent.key() in [QtCore.Qt.Key_Right, QtCore.Qt.Key_Down, QtCore.Qt.Key_Tab]:
                        if self._selectionIndex != len(self._filing) - 1:
@@ -767,6 +803,7 @@ class QPieMenu(QtGui.QWidget):
                else:
                        QtGui.QWidget.keyPressEvent(self, keyEvent)
 
+       @misc_utils.log_exception(_moduleLogger)
        def showEvent(self, showEvent):
                self.aboutToShow.emit()
                self._cachedCenterPosition = self.rect().center()
@@ -779,11 +816,13 @@ class QPieMenu(QtGui.QWidget):
 
                QtGui.QWidget.showEvent(self, showEvent)
 
+       @misc_utils.log_exception(_moduleLogger)
        def hideEvent(self, hideEvent):
                self._artist.hide()
                self._selectionIndex = PieFiling.SELECTION_NONE
                QtGui.QWidget.hideEvent(self, hideEvent)
 
+       @misc_utils.log_exception(_moduleLogger)
        def paintEvent(self, paintEvent):
                canvas = self._artist.paint(self._selectionIndex)
 
@@ -792,6 +831,12 @@ class QPieMenu(QtGui.QWidget):
 
                QtGui.QWidget.paintEvent(self, paintEvent)
 
+       def __iter__(self):
+               return iter(self._filing)
+
+       def __len__(self):
+               return len(self._filing)
+
        def _select_at(self, index):
                self._selectionIndex = index
 
@@ -824,6 +869,10 @@ class QPieMenu(QtGui.QWidget):
                self.hide()
 
 
+def init_pies():
+       PieFiling.NULL_CENTER.setEnabled(False)
+
+
 def _print(msg):
        print msg
 
@@ -834,7 +883,7 @@ def _on_about_to_hide(app):
 
 if __name__ == "__main__":
        app = QtGui.QApplication([])
-       PieFiling.NULL_CENTER.setEnabled(False)
+       init_pies()
 
        if False:
                pie = QPieMenu()
diff --git a/src/libraries/qtpieboard.py b/src/libraries/qtpieboard.py
new file mode 100755 (executable)
index 0000000..699ddfd
--- /dev/null
@@ -0,0 +1,205 @@
+#!/usr/bin/env python
+
+
+from __future__ import division
+
+import os
+import warnings
+
+from PyQt4 import QtGui
+from PyQt4 import QtCore
+
+import qtpie
+
+
+class PieKeyboard(object):
+
+       SLICE_CENTER = -1
+       SLICE_NORTH = 0
+       SLICE_NORTH_WEST = 1
+       SLICE_WEST = 2
+       SLICE_SOUTH_WEST = 3
+       SLICE_SOUTH = 4
+       SLICE_SOUTH_EAST = 5
+       SLICE_EAST = 6
+       SLICE_NORTH_EAST = 7
+
+       MAX_ANGULAR_SLICES = 8
+
+       SLICE_DIRECTIONS = [
+               SLICE_CENTER,
+               SLICE_NORTH,
+               SLICE_NORTH_WEST,
+               SLICE_WEST,
+               SLICE_SOUTH_WEST,
+               SLICE_SOUTH,
+               SLICE_SOUTH_EAST,
+               SLICE_EAST,
+               SLICE_NORTH_EAST,
+       ]
+
+       SLICE_DIRECTION_NAMES = [
+               "CENTER",
+               "NORTH",
+               "NORTH_WEST",
+               "WEST",
+               "SOUTH_WEST",
+               "SOUTH",
+               "SOUTH_EAST",
+               "EAST",
+               "NORTH_EAST",
+       ]
+
+       def __init__(self, rows, columns):
+               self._layout = QtGui.QGridLayout()
+
+               self.__cells = {}
+
+       @property
+       def toplevel(self):
+               return self._layout
+
+       def add_pie(self, row, column, pieButton):
+               assert len(pieButton) == 8
+               self._layout.addWidget(pieButton, row, column)
+               self.__cells[(row, column)] = pieButton
+
+       def get_pie(self, row, column):
+               return self.__cells[(row, column)]
+
+
+class KeyboardModifier(object):
+
+       def __init__(self, name):
+               self.name = name
+               self.lock = False
+               self.once = False
+
+       @property
+       def isActive(self):
+               return self.lock or self.once
+
+       def on_toggle_lock(self, *args, **kwds):
+               self.lock = not self.lock
+
+       def on_toggle_once(self, *args, **kwds):
+               self.once = not self.once
+
+       def reset_once(self):
+               self.once = False
+
+
+def parse_keyboard_data(text):
+       return eval(text)
+
+
+def _enumerate_pie_slices(pieData, iconPaths):
+       for direction, directionName in zip(
+               PieKeyboard.SLICE_DIRECTIONS, PieKeyboard.SLICE_DIRECTION_NAMES
+       ):
+               if directionName in pieData:
+                       sliceData = pieData[directionName]
+
+                       action = QtGui.QAction(None)
+                       try:
+                               action.setText(sliceData["text"])
+                       except KeyError:
+                               pass
+                       try:
+                               relativeIconPath = sliceData["path"]
+                       except KeyError:
+                               pass
+                       else:
+                               for iconPath in iconPaths:
+                                       absIconPath = os.path.join(iconPath, relativeIconPath)
+                                       if os.path.exists(absIconPath):
+                                               action.setIcon(QtGui.QIcon(absIconPath))
+                                               break
+                       pieItem = qtpie.QActionPieItem(action)
+               else:
+                       pieItem = qtpie.PieFiling.NULL_CENTER
+                       action = ""
+               yield direction, pieItem, action
+
+
+def load_keyboard(keyboardName, dataTree, keyboard, keyboardHandler, iconPaths):
+       for (row, column), pieData in dataTree.iteritems():
+               pieItems = list(_enumerate_pie_slices(pieData, iconPaths))
+               assert pieItems[0][0] == PieKeyboard.SLICE_CENTER, pieItems[0]
+               _, center, centerAction = pieItems.pop(0)
+
+               pieButton = qtpie.QPieButton(center)
+               pieButton.set_center(center)
+               for direction, pieItem, action in pieItems:
+                       pieButton.insertItem(pieItem)
+               keyboard.add_pie(row, column, pieButton)
+
+
+class KeyboardHandler(object):
+
+       def __init__(self, keyhandler):
+               self.__keyhandler = keyhandler
+               self.__commandHandlers = {}
+               self.__modifiers = {}
+               self.__sliceActions = {}
+
+               self.register_modifier("Shift")
+               self.register_modifier("Super")
+               self.register_modifier("Control")
+               self.register_modifier("Alt")
+
+       def register_command_handler(self, command, handler):
+               #@todo Make this handle multiple handlers or switch to gobject events
+               self.__commandHandlers["[%s]" % command] = handler
+
+       def unregister_command_handler(self, command):
+               #@todo Make this handle multiple handlers or switch to gobject events
+               del self.__commandHandlers["[%s]" % command]
+
+       def register_modifier(self, modifierName):
+               mod = KeyboardModifier(modifierName)
+               self.register_command_handler(modifierName, mod.on_toggle_lock)
+               self.__modifiers["<%s>" % modifierName] = mod
+
+       def unregister_modifier(self, modifierName):
+               self.unregister_command_handler(modifierName)
+               del self.__modifiers["<%s>" % modifierName]
+
+       def map_slice_action(self, slice, action):
+               self.__sliceActions[slice.name] = action
+
+       def __call__(self, pie, slice, direction):
+               try:
+                       action = self.__sliceActions[slice.name]
+               except KeyError:
+                       return
+
+               activeModifiers = [
+                       mod.name
+                       for mod in self.__modifiers.itervalues()
+                               if mod.isActive
+               ]
+
+               needResetOnce = False
+               if action.startswith("[") and action.endswith("]"):
+                       commandName = action[1:-1]
+                       if action in self.__commandHandlers:
+                               self.__commandHandlers[action](commandName, activeModifiers)
+                               needResetOnce = True
+                       else:
+                               warnings.warn("Unknown command: [%s]" % commandName)
+               elif action.startswith("<") and action.endswith(">"):
+                       modName = action[1:-1]
+                       for mod in self.__modifiers.itervalues():
+                               if mod.name == modName:
+                                       mod.on_toggle_once()
+                                       break
+                       else:
+                               warnings.warn("Unknown modifier: <%s>" % modName)
+               else:
+                       self.__keyhandler(action, activeModifiers)
+                       needResetOnce = True
+
+               if needResetOnce:
+                       for mod in self.__modifiers.itervalues():
+                               mod.reset_once()
index 4110e42..26d00f0 100644 (file)
@@ -9,7 +9,7 @@ import os
 import inspect
 import ConfigParser
 
-from libraries import gtkpieboard
+from libraries import qtpieboard
 from util import io
 import operation
 
@@ -33,18 +33,18 @@ class PieKeyboardPlugin(object):
                self.factory = factory
                self.__handler = None
 
-       def setup(self, calcStack, style, boardHandler):
+       def setup(self, calcStack, boardHandler):
                self.__handler = boardHandler
 
                with open(self.factory.mapFile, "r") as mapfile:
-                       boardTree = gtkpieboard.parse_keyboard_data("\n".join(mapfile.readlines()))
+                       boardTree = qtpieboard.parse_keyboard_data("\n".join(mapfile.readlines()))
 
                rows, columns = boardTree["dimensions"]
                keyboardName = boardTree["name"]
                keyTree = boardTree["keys"]
 
-               keyboard = gtkpieboard.PieKeyboard(style, rows, columns)
-               gtkpieboard.load_keyboard(keyboardName, keyTree, keyboard, self.__handler)
+               keyboard = qtpieboard.PieKeyboard(rows, columns)
+               qtpieboard.load_keyboard(keyboardName, keyTree, keyboard, self.__handler, self.factory.iconPaths)
 
                for commandName, operator in self.factory.commands.iteritems():
                        handler = CommandStackHandler(calcStack, commandName, operator)
@@ -68,6 +68,7 @@ class PieKeyboardPluginFactory(object):
                self.name = pluginName
                self.mapFile = keyboardMapFile
                self.commands = {}
+               self.iconPaths = [os.path.join(os.path.dirname(keyboardMapFile), "images")]
 
        def register_operation(self, commandName, operator):
                self.commands[commandName] = operator
diff --git a/src/plugins/images/alt.png b/src/plugins/images/alt.png
new file mode 100644 (file)
index 0000000..8ccd110
Binary files /dev/null and b/src/plugins/images/alt.png differ
diff --git a/src/plugins/images/arrows.png b/src/plugins/images/arrows.png
new file mode 100644 (file)
index 0000000..6ab51c0
Binary files /dev/null and b/src/plugins/images/arrows.png differ
diff --git a/src/plugins/images/backspace.png b/src/plugins/images/backspace.png
new file mode 100644 (file)
index 0000000..c8d5506
Binary files /dev/null and b/src/plugins/images/backspace.png differ
diff --git a/src/plugins/images/clear.png b/src/plugins/images/clear.png
new file mode 100644 (file)
index 0000000..e18eed4
Binary files /dev/null and b/src/plugins/images/clear.png differ
diff --git a/src/plugins/images/control.png b/src/plugins/images/control.png
new file mode 100644 (file)
index 0000000..f24980e
Binary files /dev/null and b/src/plugins/images/control.png differ
diff --git a/src/plugins/images/newline.png b/src/plugins/images/newline.png
new file mode 100644 (file)
index 0000000..8b242f2
Binary files /dev/null and b/src/plugins/images/newline.png differ
diff --git a/src/plugins/images/shift.png b/src/plugins/images/shift.png
new file mode 100644 (file)
index 0000000..789d7e3
Binary files /dev/null and b/src/plugins/images/shift.png differ
diff --git a/src/plugins/images/space.png b/src/plugins/images/space.png
new file mode 100644 (file)
index 0000000..71207c3
Binary files /dev/null and b/src/plugins/images/space.png differ
diff --git a/src/plugins/images/super.png b/src/plugins/images/super.png
new file mode 100644 (file)
index 0000000..6461770
Binary files /dev/null and b/src/plugins/images/super.png differ
diff --git a/src/plugins/images/symbols.dia b/src/plugins/images/symbols.dia
new file mode 100644 (file)
index 0000000..a04fe5a
Binary files /dev/null and b/src/plugins/images/symbols.dia differ
diff --git a/src/plugins/images/tab.png b/src/plugins/images/tab.png
new file mode 100644 (file)
index 0000000..1040cac
Binary files /dev/null and b/src/plugins/images/tab.png differ
index 74f085d..585bf1b 100644 (file)
@@ -211,13 +211,10 @@ class QCalcHistory(history.AbstractHistory):
 
        def push(self, node):
                simpleNode = node.simplify()
-               row = RowData(node, simpleNode)
+               row = RowData(self._prettyRenderer, node, simpleNode)
                self._historyStore.push(row)
 
-               selection = self._historyView.get_selection()
-               selectionPath = (len(self._historyStore)-1, )
-               selection.select_path(selectionPath)
-               self._historyView.scroll_to_cell(selectionPath)
+               # @todo Scroll to bottom
 
        def pop(self):
                if len(self._historyStore) == 0: