Add StatusIcon and engine menu.
authorHuang Peng <shawn.p.huang@gmail.com>
Thu, 12 Jun 2008 11:44:41 +0000 (19:44 +0800)
committerHuang Peng <shawn.p.huang@gmail.com>
Thu, 12 Jun 2008 11:44:41 +0000 (19:44 +0800)
engine/anthy/factory.py
ibus/gtk.py
ibus/interface/iibus.py
ibusdaemon/bus.py
ibusdaemon/factorymanager.py
panel/lang.py [new file with mode: 0644]
panel/main.py
panel/panel.py

index 62f697c..de2792e 100644 (file)
@@ -5,9 +5,9 @@ FACTORY_PATH = "/com/redhat/IBus/engines/Anthy/Factory"
 ENGINE_PATH = "/com/redhat/IBus/engines/Anthy/Engine/%d"
 
 class DemoEngineFactory (interface.IEngineFactory):
-       NAME = "AnthyEngine"
+       NAME = "Anthy"
        LANG = "ja"
-       ICON = ""
+       ICON = "ibus-anthy"
        AUTHORS = "Huang Peng <shawn.p.huang@gmail.com>"
        CREDITS = "GPLv2"
 
index 56a352f..340cd27 100644 (file)
@@ -14,10 +14,10 @@ class PangoAttrList (pango.AttrList):
                offsets.append (offset)
                for attr in attrs:
                        pango_attr = None
-                       start_index = attrs._start_index if attrs._start_index >= 0 else 0
-                       end_index = attrs._end_index if attrs._end_index >= 0 else 0
-                       start_index = offsets[_start_index] if attrstart_index < len (offsets) else offsets[-1]
-                       end_index = offsets[_end_index] if end_index < len (offsets) else offsets[-1]
+                       start_index = attr._start_index if attr._start_index >= 0 else 0
+                       end_index = attr._end_index if attr._end_index >= 0 else 0
+                       start_index = offsets[start_index] if start_index < len (offsets) else offsets[-1]
+                       end_index = offsets[end_index] if end_index < len (offsets) else offsets[-1]
                        if attr._type == ibus.ATTR_TYPE_FOREGROUND:
                                r = (attr._value & 0x00ff0000) >> 8
                                g = (attr._value & 0x0000ff00)
index 8611c4d..d6a2f7b 100644 (file)
@@ -52,5 +52,11 @@ class IIBus (dbus.service.Object):
        @method (out_signature = "b")
        def IsEnabled (self, dbusconn): pass
 
-       @method (out_signature = "v")
-       def GetFactoryInfo (self, dbusconn): pass
+       @method (out_signature = "av")
+       def GetFactories (self, dbusconn): pass
+
+       @method (in_signature = "o", out_signature = "av")
+       def GetFactoryInfo (self, factory_path, dbusconn): pass
+
+       @method (in_signature = "o")
+       def SetFactory (self, factory_path, dbusconn): pass
index 3584967..4b45659 100644 (file)
@@ -228,6 +228,22 @@ class IBus (ibus.Object):
                if panel == self._panel:
                        self._panel = DummyPanel ()
 
+       ##########################################################
+       # general methods
+       ##########################################################
+       def get_factories (self):
+               return self._factory_manager.get_factories ()
+
+       def get_factory_info (self, factory_path):
+               return self._factory_manager.get_factory_info (factory_path)
+
+       def set_factory (self, factory_path):
+               if self._focused_client == None:
+                       return
+               factory = self._factory_manager.get_factory (factory_path)
+               engine = factory.create_engine ()
+               self._focused_client.set_engine (engine)
+
 class IBusProxy (ibus.IIBus):
        SUPPORTS_MULTIPLE_CONNECTIONS = True
 
@@ -282,3 +298,11 @@ class IBusProxy (ibus.IIBus):
        def IsEnabled (self, dbusconn):
                return self._ibus.is_enabled (dbusconn)
 
+       def GetFactories (self, dbusconn):
+               return self._ibus.get_factories ()
+
+       def GetFactoryInfo (self, factory_path, dbusconn):
+               return self._ibus.get_factory_info (factory_path)
+
+       def SetFactory (self, factory_path, dbusconn):
+               return self._ibus.set_factory (factory_path)
index 3a1bb1e..bde9332 100644 (file)
@@ -21,7 +21,7 @@ class FactoryManager (ibus.Object):
        def register_factories (self, object_paths, ibusconn):
                if ibusconn in self._factories:
                        raise ibus.IBusException ("this conn has registered factories!")
-               
+
                self._ibusconn_factory_dict[ibusconn] = []
 
                for object_path in object_paths:
@@ -53,7 +53,18 @@ class FactoryManager (ibus.Object):
                        i = 0
 
                return factories[i]
-       
+
+       def get_factories (self):
+               return self._factories.keys ()
+
+       def get_factory_info (self, factory_path):
+               factory = self._factories[factory_path]
+               return factory.get_info ()
+
+       def get_factory (self, factory_path):
+               factory = self._factories[factory_path]
+               return factory
+
        def _get_sorted_factories (self, resort = False):
                if not self._sorted_factories or resort:
                        factories = self._factories.values ()
diff --git a/panel/lang.py b/panel/lang.py
new file mode 100644 (file)
index 0000000..34678d5
--- /dev/null
@@ -0,0 +1,5 @@
+LANGUAGES = {
+       "zh" : "Chinese",
+       "en" : "English",
+       "ja" : "Japanese"
+}
index 6913215..6877c63 100644 (file)
@@ -11,9 +11,9 @@ class PanelApplication:
                                                        "Disconnected",
                                                        dbus_interface = dbus.LOCAL_IFACE)
 
-               self._panel = panel.PanelProxy (self._dbusconn, "/org/freedesktop/IBus/Panel")
-
                self._ibus = self._dbusconn.get_object (ibus.IBUS_NAME, ibus.IBUS_PATH)
+               self._panel = panel.PanelProxy (self._dbusconn, "/org/freedesktop/IBus/Panel", self._ibus)
+
                self._ibus.RegisterPanel (self._panel, True)
 
        def run (self):
index cdd421d..bac4c69 100644 (file)
@@ -3,23 +3,33 @@ import gtk
 import gtk.gdk as gdk
 import gobject
 import ibus
+from lang import LANGUAGES
 from ibus import interface
 from languagebar import LanguageBarWindow
 from candidatewindow import CandidateWindow
 
 class Panel (ibus.Object):
-       def __init__ (self, proxy):
+       def __init__ (self, proxy, _ibus):
                gobject.GObject.__init__ (self)
                self._proxy = proxy
+               self._ibus = _ibus
                self._language_bar = LanguageBarWindow ()
                self._language_bar.connect ("property-activate",
                                                lambda widget, prop_name: self._proxy.PropertyActivate (prop_name))
+
                self._candidate_panel = CandidateWindow ()
                self._candidate_panel.connect ("cursor-up",
                                                lambda widget: self._proxy.CursorUp ())
                self._candidate_panel.connect ("cursor-down",
                                                lambda widget: self._proxy.CursorDown ())
 
+               self._status_icon = gtk.StatusIcon ()
+               self._status_icon.connect ("popup-menu", self._status_icon_popup_menu_cb)
+               self._status_icon.connect ("activate", self._status_icon_activate_cb)
+               self._status_icon.set_from_icon_name ("engine-default")
+               self._status_icon.set_tooltip ("ibus - enabled")
+               self._status_icon.set_visible (True)
+
        def set_cursor_location (self, x, y, w, h):
                self._candidate_panel.move (x + w, y + h)
 
@@ -69,13 +79,43 @@ class Panel (ibus.Object):
        def do_destroy (self):
                gtk.main_quit ()
 
+       def _popup_factory_menu (self, button, active_time):
+               menu = gtk.Menu ()
+               factories = self._ibus.GetFactories ()
+               if not factories:
+                       item = gtk.MenuItem (label = "no im")
+                       item.set_sensitive (False)
+                       menu.add (item)
+               else:
+                       for factory in factories:
+                               name, lang, icon, authors, credits = self._ibus.GetFactoryInfo (factory)
+                               item = gtk.ImageMenuItem ("%s - %s" % (LANGUAGES.get (lang, lang), name))
+                               if not icon:
+                                       icon = "engine-default"
+                               item.set_image (gtk.image_new_from_icon_name (icon, gtk.ICON_SIZE_MENU))
+                               item.connect ("activate", self._menu_item_activate_cb, factory)
+                               menu.add (item)
+
+               menu.show_all ()
+               menu.set_take_focus (False)
+               menu.popup (None, None, gtk.status_icon_position_menu, button, active_time, self._status_icon)
+
+       def _status_icon_activate_cb (self, status_icon):
+               self._popup_factory_menu (0, gtk.get_current_event_time ())
+       def _status_icon_popup_menu_cb (self, status_icon, button, active_time):
+               self._popup_factory_menu (button, active_time)
+
+
+       def _menu_item_activate_cb (self, item, factory):
+               gobject.idle_add (self._ibus.SetFactory, factory, priority = gobject.PRIORITY_LOW)
+
 gobject.type_register (Panel, "IBusPanel")
 
 class PanelProxy (interface.IPanel):
-       def __init__ (self, dbusconn, object_path):
+       def __init__ (self, dbusconn, object_path, _ibus):
                interface.IPanel.__init__ (self, dbusconn, object_path)
                self._dbusconn = dbusconn
-               self._panel = Panel (self)
+               self._panel = Panel (self, _ibus)
 
        def SetCursorLocation (self, x, y, w, h):
                self._panel.set_cursor_location (x, y, w, h)