diff --git a/chat/BuddyList.py b/chat/BuddyList.py
index 9bc63bad..7bf2e4ec 100644
--- a/chat/BuddyList.py
+++ b/chat/BuddyList.py
@@ -53,6 +53,8 @@ class BuddyList(object):
self._buddies = {}
self._pdiscovery = presence.PresenceDiscovery()
self._pdiscovery.add_service_listener(self._on_service_change)
+
+ def start(self):
self._pdiscovery.start()
def add_buddy_listener(self, listener):
diff --git a/chat/SimpleGladeApp.py b/chat/SimpleGladeApp.py
deleted file mode 100644
index 90c598cc..00000000
--- a/chat/SimpleGladeApp.py
+++ /dev/null
@@ -1,341 +0,0 @@
-"""
- SimpleGladeApp.py
- Module that provides an object oriented abstraction to pygtk and libglade.
- Copyright (C) 2004 Sandino Flores Moreno
-"""
-
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
-# USA
-
-import os
-import sys
-import re
-
-import tokenize
-import gtk
-import gtk.glade
-import weakref
-import inspect
-
-__version__ = "1.0"
-__author__ = 'Sandino "tigrux" Flores-Moreno'
-
-def bindtextdomain(app_name, locale_dir=None):
- """
- Bind the domain represented by app_name to the locale directory locale_dir.
- It has the effect of loading translations, enabling applications for different
- languages.
-
- app_name:
- a domain to look for translations, tipically the name of an application.
-
- locale_dir:
- a directory with locales like locale_dir/lang_isocode/LC_MESSAGES/app_name.mo
- If omitted or None, then the current binding for app_name is used.
- """
- try:
- import locale
- import gettext
- locale.setlocale(locale.LC_ALL, "")
- gtk.glade.bindtextdomain(app_name, locale_dir)
- gettext.install(app_name, locale_dir, unicode=1)
- except (IOError,locale.Error), e:
- print "Warning", app_name, e
- __builtins__.__dict__["_"] = lambda x : x
-
-
-class SimpleGladeApp:
-
- def __init__(self, path, root=None, domain=None, **kwargs):
- """
- Load a glade file specified by glade_filename, using root as
- root widget and domain as the domain for translations.
-
- If it receives extra named arguments (argname=value), then they are used
- as attributes of the instance.
-
- path:
- path to a glade filename.
- If glade_filename cannot be found, then it will be searched in the
- same directory of the program (sys.argv[0])
-
- root:
- the name of the widget that is the root of the user interface,
- usually a window or dialog (a top level widget).
- If None or ommited, the full user interface is loaded.
-
- domain:
- A domain to use for loading translations.
- If None or ommited, no translation is loaded.
-
- **kwargs:
- a dictionary representing the named extra arguments.
- It is useful to set attributes of new instances, for example:
- glade_app = SimpleGladeApp("ui.glade", foo="some value", bar="another value")
- sets two attributes (foo and bar) to glade_app.
- """
- if os.path.isfile(path):
- self.glade_path = path
- else:
- glade_dir = os.path.dirname( sys.argv[0] )
- self.glade_path = os.path.join(glade_dir, path)
- for key, value in kwargs.items():
- try:
- setattr(self, key, weakref.proxy(value) )
- except TypeError:
- setattr(self, key, value)
- self.glade = None
- self.install_custom_handler(self.custom_handler)
- self.glade = self.create_glade(self.glade_path, root, domain)
- if root:
- self.main_widget = self.get_widget(root)
- else:
- self.main_widget = None
- self.normalize_names()
- self.add_callbacks(self)
- self.new()
-
- def __repr__(self):
- class_name = self.__class__.__name__
- if self.main_widget:
- root = gtk.Widget.get_name(self.main_widget)
- repr = '%s(path="%s", root="%s")' % (class_name, self.glade_path, root)
- else:
- repr = '%s(path="%s")' % (class_name, self.glade_path)
- return repr
-
- def new(self):
- """
- Method called when the user interface is loaded and ready to be used.
- At this moment, the widgets are loaded and can be refered as self.widget_name
- """
- pass
-
- def add_callbacks(self, callbacks_proxy):
- """
- It uses the methods of callbacks_proxy as callbacks.
- The callbacks are specified by using:
- Properties window -> Signals tab
- in glade-2 (or any other gui designer like gazpacho).
-
- Methods of classes inheriting from SimpleGladeApp are used as
- callbacks automatically.
-
- callbacks_proxy:
- an instance with methods as code of callbacks.
- It means it has methods like on_button1_clicked, on_entry1_activate, etc.
- """
- self.glade.signal_autoconnect(callbacks_proxy)
-
- def normalize_names(self):
- """
- It is internally used to normalize the name of the widgets.
- It means a widget named foo:vbox-dialog in glade
- is refered self.vbox_dialog in the code.
-
- It also sets a data "prefixes" with the list of
- prefixes a widget has for each widget.
- """
- for widget in self.get_widgets():
- widget_name = gtk.Widget.get_name(widget)
- prefixes_name_l = widget_name.split(":")
- prefixes = prefixes_name_l[ : -1]
- widget_api_name = prefixes_name_l[-1]
- widget_api_name = "_".join( re.findall(tokenize.Name, widget_api_name) )
- gtk.Widget.set_name(widget, widget_api_name)
- if hasattr(self, widget_api_name):
- raise AttributeError("instance %s already has an attribute %s" % (self,widget_api_name))
- else:
- setattr(self, widget_api_name, widget)
- if prefixes:
- gtk.Widget.set_data(widget, "prefixes", prefixes)
-
- def add_prefix_actions(self, prefix_actions_proxy):
- """
- By using a gui designer (glade-2, gazpacho, etc)
- widgets can have a prefix in theirs names
- like foo:entry1 or foo:label3
- It means entry1 and label3 has a prefix action named foo.
-
- Then, prefix_actions_proxy must have a method named prefix_foo which
- is called everytime a widget with prefix foo is found, using the found widget
- as argument.
-
- prefix_actions_proxy:
- An instance with methods as prefix actions.
- It means it has methods like prefix_foo, prefix_bar, etc.
- """
- prefix_s = "prefix_"
- prefix_pos = len(prefix_s)
-
- is_method = lambda t : callable( t[1] )
- is_prefix_action = lambda t : t[0].startswith(prefix_s)
- drop_prefix = lambda (k,w): (k[prefix_pos:],w)
-
- members_t = inspect.getmembers(prefix_actions_proxy)
- methods_t = filter(is_method, members_t)
- prefix_actions_t = filter(is_prefix_action, methods_t)
- prefix_actions_d = dict( map(drop_prefix, prefix_actions_t) )
-
- for widget in self.get_widgets():
- prefixes = gtk.Widget.get_data(widget, "prefixes")
- if prefixes:
- for prefix in prefixes:
- if prefix in prefix_actions_d:
- prefix_action = prefix_actions_d[prefix]
- prefix_action(widget)
-
- def custom_handler(self,
- glade, function_name, widget_name,
- str1, str2, int1, int2):
- """
- Generic handler for creating custom widgets, internally used to
- enable custom widgets (custom widgets of glade).
-
- The custom widgets have a creation function specified in design time.
- Those creation functions are always called with str1,str2,int1,int2 as
- arguments, that are values specified in design time.
-
- Methods of classes inheriting from SimpleGladeApp are used as
- creation functions automatically.
-
- If a custom widget has create_foo as creation function, then the
- method named create_foo is called with str1,str2,int1,int2 as arguments.
- """
- try:
- handler = getattr(self, function_name)
- return handler(str1, str2, int1, int2)
- except AttributeError:
- return None
-
- def gtk_widget_show(self, widget, *args):
- """
- Predefined callback.
- The widget is showed.
- Equivalent to widget.show()
- """
- widget.show()
-
- def gtk_widget_hide(self, widget, *args):
- """
- Predefined callback.
- The widget is hidden.
- Equivalent to widget.hide()
- """
- widget.hide()
-
- def gtk_widget_grab_focus(self, widget, *args):
- """
- Predefined callback.
- The widget grabs the focus.
- Equivalent to widget.grab_focus()
- """
- widget.grab_focus()
-
- def gtk_widget_destroy(self, widget, *args):
- """
- Predefined callback.
- The widget is destroyed.
- Equivalent to widget.destroy()
- """
- widget.destroy()
-
- def gtk_window_activate_default(self, window, *args):
- """
- Predefined callback.
- The default widget of the window is activated.
- Equivalent to window.activate_default()
- """
- widget.activate_default()
-
- def gtk_true(self, *args):
- """
- Predefined callback.
- Equivalent to return True in a callback.
- Useful for stopping propagation of signals.
- """
- return True
-
- def gtk_false(self, *args):
- """
- Predefined callback.
- Equivalent to return False in a callback.
- """
- return False
-
- def gtk_main_quit(self, *args):
- """
- Predefined callback.
- Equivalent to self.quit()
- """
- self.quit()
-
- def main(self):
- """
- Starts the main loop of processing events.
- The default implementation calls gtk.main()
-
- Useful for applications that needs a non gtk main loop.
- For example, applications based on gstreamer needs to override
- this method with gst.main()
-
- Do not directly call this method in your programs.
- Use the method run() instead.
- """
- gtk.main()
-
- def quit(self):
- """
- Quit processing events.
- The default implementation calls gtk.main_quit()
-
- Useful for applications that needs a non gtk main loop.
- For example, applications based on gstreamer needs to override
- this method with gst.main_quit()
- """
- gtk.main_quit()
-
- def run(self):
- """
- Starts the main loop of processing events checking for Control-C.
-
- The default implementation checks wheter a Control-C is pressed,
- then calls on_keyboard_interrupt().
-
- Use this method for starting programs.
- """
- try:
- self.main()
- except KeyboardInterrupt:
- self.on_keyboard_interrupt()
-
- def on_keyboard_interrupt(self):
- """
- This method is called by the default implementation of run()
- after a program is finished by pressing Control-C.
- """
- pass
-
- def install_custom_handler(self, custom_handler):
- gtk.glade.set_custom_handler(custom_handler)
-
- def create_glade(self, glade_path, root, domain):
- return gtk.glade.XML(self.glade_path, root, domain)
-
- def get_widget(self, widget_name):
- return self.glade.get_widget(widget_name)
-
- def get_widgets(self):
- return self.glade.get_widget_prefix("")
diff --git a/chat/chat.glade b/chat/chat.glade
index 1058c232..eda4612b 100644
--- a/chat/chat.glade
+++ b/chat/chat.glade
@@ -22,7 +22,7 @@
False
-
+
True
2
2
diff --git a/chat/main.py b/chat/chat.py
similarity index 54%
rename from chat/main.py
rename to chat/chat.py
index e22a13af..b014ee26 100755
--- a/chat/main.py
+++ b/chat/chat.py
@@ -1,18 +1,27 @@
#!/usr/bin/python -t
# -*- tab-width: 4; indent-tabs-mode: t -*-
-import os, sys, pwd
-sys.path.append(os.getcwd())
+import dbus
+import dbus.service
+import dbus.glib
+
+import pygtk
+pygtk.require('2.0')
import gtk, gobject
+import gtk.glade
+
+import sys
+import os
+import pwd
+import gc
+
+sys.path.append(os.getcwd())
+sys.path.append('../shell/example-activity/')
+import activity
-from SimpleGladeApp import SimpleGladeApp
import presence
-import network
-import avahi
import BuddyList
-
-glade_dir = os.getcwd()
-
+import network
class Chat(object):
def __init__(self, view, label):
@@ -29,7 +38,6 @@ class Chat(object):
self._buffer.insert(aniter, buddy.nick() + ": " + msg + "\n")
-
class GroupChat(Chat):
def __init__(self, parent, view, label):
Chat.__init__(self, view, label)
@@ -50,18 +58,71 @@ class GroupChat(Chat):
if buddy:
self.recv_message(buddy, msg['data'])
-
-class ChatApp(SimpleGladeApp):
- def __init__(self, glade_file="chat.glade", root="mainWindow", domain=None, **kwargs):
+class ChatActivity(activity.Activity):
+ def __init__(self):
+ activity.Activity.__init__(self)
+ self._act_name = "Chat"
self._pannounce = presence.PresenceAnnounce()
self._buddy_list = BuddyList.BuddyList()
self._buddy_list.add_buddy_listener(self._on_buddy_presence_event)
(self._nick, self._realname) = self._get_name()
- path = os.path.join(glade_dir, glade_file)
- gtk.window_set_default_icon_name("config-users")
- SimpleGladeApp.__init__(self, path, root, domain, **kwargs)
+ self._glade = gtk.glade.XML("chat.glade", "mainTable", None)
+
+ def _ui_setup(self, plug):
+ self._buddy_list_model = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_PYOBJECT)
+ self._buddy_list_view = self._glade.get_widget("buddyListView")
+ self._buddy_list_view.set_model(self._buddy_list_model)
+ self._buddy_list_view.connect("cursor-changed", self._on_buddyList_buddy_selected)
+ self._buddy_list_view.connect("row-activated", self._on_buddyList_buddy_double_clicked)
+
+ self._entry = self._glade.get_widget("entry")
+ self._entry.connect("activate", self._send_chat_message)
+
+ renderer = gtk.CellRendererText()
+ column = gtk.TreeViewColumn("", renderer, text=0)
+ column.set_resizable(True)
+ column.set_sizing("GTK_TREE_VIEW_COLUMN_GROW_ONLY");
+ column.set_expand(True);
+ self._buddy_list_view.append_column(column)
+
+ self._chat_view = self._glade.get_widget("chatView")
+ self._chat_label = self._glade.get_widget("chatLabel")
+ self._group_chat = GroupChat(self, self._chat_view, self._chat_label)
+ aniter = self._buddy_list_model.append(None)
+ self._buddy_list_model.set(aniter, 0, "Group", 1, None)
+ self._group_chat.activate()
+ plug.add(self._glade.get_widget("mainTable"))
+
+ def _start(self):
+ self._buddy_list.start()
+ self._pannounce.register_service(self._realname, 6666, presence.OLPC_CHAT_SERVICE,
+ name = self._nick, realname = self._realname)
+
+ def activity_on_connected_to_shell(self):
+ print "act %d: in activity_on_connected_to_shell" % self.activity_get_id()
+ self.activity_set_tab_text(self._act_name)
+ self._plug = self.activity_get_gtk_plug()
+ self._ui_setup(self._plug)
+ self._plug.show_all()
+ self._start()
+
+ def activity_on_disconnected_from_shell(self):
+ print "act %d: in activity_on_disconnected_from_shell"%self.activity_get_id()
+ print "act %d: Shell disappeared..."%self.activity_get_id()
+
+ gc.collect()
+
+ def activity_on_close_from_user(self):
+ print "act %d: in activity_on_close_from_user"%self.activity_get_id()
+ self.activity_shutdown()
+
+ def activity_on_lost_focus(self):
+ print "act %d: in activity_on_lost_focus"%self.activity_get_id()
+
+ def activity_on_got_focus(self):
+ print "act %d: in activity_on_got_focus"%self.activity_get_id()
def _get_name(self):
ent = pwd.getpwuid(os.getuid())
@@ -75,14 +136,14 @@ class ChatApp(SimpleGladeApp):
def _on_buddyList_buddy_selected(self, widget, *args):
(model, aniter) = widget.get_selection().get_selected()
- name = self.treemodel.get(aniter,0)
+ name = self._buddy_list_model.get(aniter,0)
print "Selected %s" % name
def _on_buddyList_buddy_double_clicked(self, widget, *args):
""" Select the chat for this buddy or group """
(model, aniter) = widget.get_selection().get_selected()
chat = None
- buddy = self.treemodel.get_value(aniter, 1)
+ buddy = self._buddy_list_model.get_value(aniter, 1)
if not buddy:
chat = self._group_chat
else:
@@ -96,12 +157,12 @@ class ChatApp(SimpleGladeApp):
def _on_buddy_presence_event(self, action, buddy):
if action == BuddyList.ACTION_BUDDY_ADDED:
- aniter = self.treemodel.append(None)
- self.treemodel.set(aniter, 0, buddy.nick(), 1, buddy)
+ aniter = self._buddy_list_model.append(None)
+ self._buddy_list_model.set(aniter, 0, buddy.nick(), 1, buddy)
elif action == BuddyList.ACCTION_BUDDY_REMOVED:
- aniter = self.treemodel.get_iter(buddy.nick())
+ aniter = self._buddy_list_model.get_iter(buddy.nick())
if aniter:
- self.treemodel.remove(iter)
+ self._buddy_list_model.remove(iter)
def find_buddy_by_address(self, address):
return self._buddy_list.find_buddy_by_address(address)
@@ -110,7 +171,7 @@ class ChatApp(SimpleGladeApp):
self.quit()
def _get_current_chat(self):
- selection = self.buddyListView.get_selection()
+ selection = self._buddy_list_view.get_selection()
(model, aniter) = selection.get_selected()
buddy = model.get_value(aniter, 1)
if not buddy:
@@ -123,36 +184,13 @@ class ChatApp(SimpleGladeApp):
chat.send_message(text)
widget.set_text("")
- def new(self):
- self.treemodel = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_PYOBJECT)
- self.buddyListView.set_model(self.treemodel)
- self.buddyListView.connect("cursor-changed", self._on_buddyList_buddy_selected)
- self.buddyListView.connect("row-activated", self._on_buddyList_buddy_double_clicked)
- self.mainWindow.connect("delete-event", self._on_main_window_delete)
- self.entry.connect("activate", self._send_chat_message)
-
- renderer = gtk.CellRendererText()
- column = gtk.TreeViewColumn("", renderer, text=0)
- column.set_resizable(True)
- column.set_sizing("GTK_TREE_VIEW_COLUMN_GROW_ONLY");
- column.set_expand(True);
- self.buddyListView.append_column(column)
-
- self._group_chat = GroupChat(self, self.chatView, self.chatLabel)
- aniter = self.treemodel.append(None)
- self.treemodel.set(aniter, 0, "Group", 1, None)
- self._group_chat.activate()
-
- self._pannounce.register_service(self._realname, 6666, presence.OLPC_CHAT_SERVICE,
- name = self._nick, realname = self._realname)
-
- def cleanup(self):
- pass
+ def run(self):
+ gtk.main()
def main():
- app = ChatApp()
+ app = ChatActivity()
+ app.activity_connect_to_shell()
app.run()
- app.cleanup()
if __name__ == "__main__":
main()