From 73e7360bab924b141a904ef3ab04c39e6749d70a Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Fri, 21 Apr 2006 15:27:20 -0400 Subject: [PATCH] More work on the notebook widget. Ellipsize labels. --- browser/browser.py | 159 +++++++++++++++++++++++++++------------------ chat/BuddyList.py | 15 ----- chat/chat.glade | 89 +++++++------------------ chat/main.py | 94 ++++++--------------------- chat/network.py | 2 - chat/presence.py | 2 - shell/src/shell.py | 40 ++++++++---- 7 files changed, 169 insertions(+), 232 deletions(-) diff --git a/browser/browser.py b/browser/browser.py index 60054363..7e310579 100755 --- a/browser/browser.py +++ b/browser/browser.py @@ -15,99 +15,127 @@ import geckoembed class Activity(dbus.service.Object): - def __init__(self): - pass + def __init__(self): + pass - def name_owner_changed(self, service_name, old_service_name, new_service_name): - #print "in name_owner_changed: svc=%s oldsvc=%s newsvc=%s"%(service_name, old_service_name, new_service_name) - if service_name == "com.redhat.Sugar.Shell" and new_service_name == "": - self.activity_on_disconnected_from_shell() - #elif service_name == "com.redhat.Sugar.Shell" and old_service_name == "": - # self.activity_on_shell_reappeared() + def name_owner_changed(self, service_name, old_service_name, new_service_name): + #print "in name_owner_changed: svc=%s oldsvc=%s newsvc=%s"%(service_name, old_service_name, new_service_name) + if service_name == "com.redhat.Sugar.Shell" and new_service_name == "": + self.activity_on_disconnected_from_shell() + #elif service_name == "com.redhat.Sugar.Shell" and old_service_name == "": + # self.activity_on_shell_reappeared() - def activity_connect_to_shell(self): - self.__bus = dbus.SessionBus() + def activity_connect_to_shell(self): + self.__bus = dbus.SessionBus() - self.__bus.add_signal_receiver(self.name_owner_changed, dbus_interface = "org.freedesktop.DBus", signal_name = "NameOwnerChanged") + self.__bus.add_signal_receiver(self.name_owner_changed, dbus_interface = "org.freedesktop.DBus", signal_name = "NameOwnerChanged") - self.__activity_container_object = self.__bus.get_object("com.redhat.Sugar.Shell", \ - "/com/redhat/Sugar/Shell/ActivityContainer") - self.__activity_container = dbus.Interface(self.__activity_container_object, \ - "com.redhat.Sugar.Shell.ActivityContainer") + self.__activity_container_object = self.__bus.get_object("com.redhat.Sugar.Shell", \ + "/com/redhat/Sugar/Shell/ActivityContainer") + self.__activity_container = dbus.Interface(self.__activity_container_object, \ + "com.redhat.Sugar.Shell.ActivityContainer") - self.__activity_id = self.__activity_container.add_activity("") - self.__object_path = "/com/redhat/Sugar/Shell/Activities/%d"%self.__activity_id + self.__activity_id = self.__activity_container.add_activity("") + self.__object_path = "/com/redhat/Sugar/Shell/Activities/%d"%self.__activity_id - print "object_path = %s"%self.__object_path + print "object_path = %s"%self.__object_path - self.__activity_object = dbus.Interface(self.__bus.get_object("com.redhat.Sugar.Shell", self.__object_path), \ - "com.redhat.Sugar.Shell.ActivityHost") - self.__window_id = self.__activity_object.get_host_xembed_id() + self.__activity_object = dbus.Interface(self.__bus.get_object("com.redhat.Sugar.Shell", self.__object_path), \ + "com.redhat.Sugar.Shell.ActivityHost") + self.__window_id = self.__activity_object.get_host_xembed_id() - print "XEMBED window_id = %d"%self.__window_id + print "XEMBED window_id = %d"%self.__window_id - self.__plug = gtk.Plug(self.__window_id) + self.__plug = gtk.Plug(self.__window_id) - # Now let the Activity register a peer service so the Shell can poke it - self.__peer_service_name = "com.redhat.Sugar.Activity%d"%self.__activity_id - self.__peer_object_name = "/com/redhat/Sugar/Activity/%d"%self.__activity_id - self.__service = dbus.service.BusName(self.__peer_service_name, bus=self.__bus) - dbus.service.Object.__init__(self, self.__service, self.__peer_object_name) + # Now let the Activity register a peer service so the Shell can poke it + self.__peer_service_name = "com.redhat.Sugar.Activity%d"%self.__activity_id + self.__peer_object_name = "/com/redhat/Sugar/Activity/%d"%self.__activity_id + self.__service = dbus.service.BusName(self.__peer_service_name, bus=self.__bus) + dbus.service.Object.__init__(self, self.__service, self.__peer_object_name) - self.__activity_object.set_peer_service_name(self.__peer_service_name, self.__peer_object_name) + self.__activity_object.set_peer_service_name(self.__peer_service_name, self.__peer_object_name) - self.activity_on_connected_to_shell() + self.activity_on_connected_to_shell() - def activity_get_gtk_plug(self): - return self.__plug + def activity_get_gtk_plug(self): + return self.__plug - def activity_set_tab_text(self, text): - self.__activity_object.set_tab_text(text) + def activity_set_tab_text(self, text): + self.__activity_object.set_tab_text(text) - @dbus.service.method("com.redhat.Sugar.Activity", \ - in_signature="", \ - out_signature="") - def lost_focus(self): - self.activity_on_lost_focus() + @dbus.service.method("com.redhat.Sugar.Activity", \ + in_signature="", \ + out_signature="") + def lost_focus(self): + self.activity_on_lost_focus() - @dbus.service.method("com.redhat.Sugar.Activity", \ - in_signature="", \ - out_signature="") - def got_focus(self): - self.activity_on_got_focus() + @dbus.service.method("com.redhat.Sugar.Activity", \ + in_signature="", \ + out_signature="") + def got_focus(self): + self.activity_on_got_focus() - @dbus.service.method("com.redhat.Sugar.Activity", \ - in_signature="", \ - out_signature="") - def close_from_user(self): - self.activity_on_close_from_user() + @dbus.service.method("com.redhat.Sugar.Activity", \ + in_signature="", \ + out_signature="") + def close_from_user(self): + self.activity_on_close_from_user() - def activity_get_id(self): - return self.__activity_id + def activity_get_id(self): + return self.__activity_id - # pure virtual methods - def activity_on_connected_to_shell(self): - print "act %d: you need to override activity_on_connected_to_shell"%self.activity_get_id() + def __shutdown_reply_cb(self): + print "in __reply_cb" - def activity_on_disconnected_from_shell(self): - print "act %d: you need to override activity_on_disconnected_to_shell"%self.activity_get_id() + self.__plug.destroy() + self.__plug = None - def activity_on_close_from_user(self): - print "act %d: you need to override activity_on_close_from_user"%self.activity_get_id() + self.__bus = None + self.__activity_container_object = None + self.__activity_container = None + self.__activity_object = None + self.__service = None - def activity_on_lost_focus(self): - print "act %d: you need to override activity_on_lost_focus"%self.activity_get_id() + self.__bus.remove_signal_receiver(self.name_owner_changed, dbus_interface = "org.freedesktop.DBus", signal_name = "NameOwnerChanged") - def activity_on_got_focus(self): - print "act %d: you need to override activity_on_got_focus"%self.activity_get_id() + self.activity_on_disconnected_from_shell() + + + del self + + + + def __shutdown_error_cb(self, error): + print "in __error_cb" + + def activity_shutdown(self): + self.__activity_object.shutdown(reply_handler = self.__shutdown_reply_cb, error_handler = self.__shutdown_error_cb) + + # pure virtual methods + + def activity_on_connected_to_shell(self): + print "act %d: you need to override activity_on_connected_to_shell"%self.activity_get_id() + + def activity_on_disconnected_from_shell(self): + print "act %d: you need to override activity_on_disconnected_from_shell"%self.activity_get_id() + + def activity_on_close_from_user(self): + print "act %d: you need to override activity_on_close_from_user"%self.activity_get_id() + + def activity_on_lost_focus(self): + print "act %d: you need to override activity_on_lost_focus"%self.activity_get_id() + + def activity_on_got_focus(self): + print "act %d: you need to override activity_on_got_focus"%self.activity_get_id() def my_exit(): - sys.exit(0) + sys.exit(0) def deferred_exit(): - gobject.timeout_add(0, my_exit) + gobject.timeout_add(0, my_exit) ################################################################################ @@ -269,6 +297,9 @@ class BrowserActivity(Activity): def __title_cb(self, embed): self.activity_set_tab_text(embed.get_title()) + def activity_on_close_from_user(self): + self.activity_shutdown() + class WebActivity(Activity): def __init__(self): Activity.__init__(self) diff --git a/chat/BuddyList.py b/chat/BuddyList.py index 9bc63bad..e7cb7ca0 100644 --- a/chat/BuddyList.py +++ b/chat/BuddyList.py @@ -1,5 +1,3 @@ -# -*- tab-width: 4; indent-tabs-mode: t -*- - import presence import avahi @@ -16,13 +14,6 @@ class Buddy(object): self._host = host self._address = address self._port = port - self._chat = None - - def set_chat(self, chat): - self._chat = chat - - def chat(self): - return self._chat def nick(self): return self._nick @@ -75,12 +66,6 @@ class BuddyList(object): return buddy return None - def find_buddy_by_address(self, address): - for buddy in self._buddies.keys(): - if buddy.address() == address: - return buddy - return None - def _notify_listeners(self, action, buddy): for listener in self._listeners: listener(action, buddy) diff --git a/chat/chat.glade b/chat/chat.glade index 1058c232..f8195768 100644 --- a/chat/chat.glade +++ b/chat/chat.glade @@ -30,6 +30,31 @@ 0 0 + + + True + True + False + True + GTK_JUSTIFY_LEFT + GTK_WRAP_NONE + True + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 1 + 0 + 1 + + + True @@ -86,70 +111,6 @@ fill - - - - True - False - 0 - - - - True - - False - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - True - False - False - True - GTK_JUSTIFY_LEFT - GTK_WRAP_NONE - True - 0 - 0 - 0 - 0 - 0 - 0 - - - - 0 - True - True - - - - - 0 - 1 - 0 - 1 - fill - - diff --git a/chat/main.py b/chat/main.py index e22a13af..dff8cde7 100755 --- a/chat/main.py +++ b/chat/main.py @@ -1,5 +1,4 @@ #!/usr/bin/python -t -# -*- tab-width: 4; indent-tabs-mode: t -*- import os, sys, pwd sys.path.append(os.getcwd()) @@ -13,46 +12,9 @@ import BuddyList glade_dir = os.getcwd() - -class Chat(object): - def __init__(self, view, label): - self._buffer = gtk.TextBuffer() - self._view = view - self._label = label - - def activate(self, label): - self._view.set_buffer(self._buffer) - self._label.set_text(label) - - def recv_message(self, buddy, msg): - aniter = self._buffer.get_end_iter() - self._buffer.insert(aniter, buddy.nick() + ": " + msg + "\n") - - - -class GroupChat(Chat): - def __init__(self, parent, view, label): - Chat.__init__(self, view, label) - self._parent = parent - self._gc_controller = network.GroupChatController('224.0.0.221', 6666, self._recv_group_message) - self._gc_controller.start() - self._label_prefix = "Cha" - - def activate(self): - Chat.activate(self, "Group Chat") - - def send_message(self, text): - if len(text) > 0: - self._gc_controller.send_msg(text) - - def _recv_group_message(self, msg): - buddy = self._parent.find_buddy_by_address(msg['addr']) - if buddy: - self.recv_message(buddy, msg['data']) - - class ChatApp(SimpleGladeApp): def __init__(self, glade_file="chat.glade", root="mainWindow", domain=None, **kwargs): + self._pannounce = presence.PresenceAnnounce() self._buddy_list = BuddyList.BuddyList() self._buddy_list.add_buddy_listener(self._on_buddy_presence_event) @@ -79,57 +41,43 @@ class ChatApp(SimpleGladeApp): 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) - if not buddy: - chat = self._group_chat - else: - chat = buddy.chat() - - if chat: - chat.activate() - else: - # start a new chat with them - pass + name = self.treemodel.get(aniter,0) + print "Double-clicked %s" % name 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.treemodel.insert_after(None,None) + self.treemodel.set(aniter, 0, buddy.nick()) elif action == BuddyList.ACCTION_BUDDY_REMOVED: aniter = self.treemodel.get_iter(buddy.nick()) if aniter: self.treemodel.remove(iter) - def find_buddy_by_address(self, address): - return self._buddy_list.find_buddy_by_address(address) - def _on_main_window_delete(self, widget, *args): self.quit() - def _get_current_chat(self): - selection = self.buddyListView.get_selection() - (model, aniter) = selection.get_selected() - buddy = model.get_value(aniter, 1) - if not buddy: - return self._group_chat - return buddy.chat() + def _recv_group_message(self, msg): + aniter = self._group_chat_buffer.get_end_iter() + self._group_chat_buffer.insert(aniter, msg['data'] + "\n") +# print "Message: %s" % msg['data'] - def _send_chat_message(self, widget, *args): - chat = self._get_current_chat() + def _send_group_message(self, widget, *args): text = widget.get_text() - chat.send_message(text) + if len(text) > 0: + self._gc_controller.send_msg(text) widget.set_text("") def new(self): - self.treemodel = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_PYOBJECT) + self._group_chat_buffer = gtk.TextBuffer() + self.chatView.set_buffer(self._group_chat_buffer) + + self.treemodel = gtk.TreeStore(gobject.TYPE_STRING) 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) + self.entry.connect("activate", self._send_group_message) renderer = gtk.CellRendererText() column = gtk.TreeViewColumn("", renderer, text=0) @@ -138,14 +86,12 @@ class ChatApp(SimpleGladeApp): 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) + self._gc_controller = network.GroupChatController('224.0.0.221', 6666, self._recv_group_message) + self._gc_controller.start() + def cleanup(self): pass diff --git a/chat/network.py b/chat/network.py index 1f2c904a..a685a38a 100644 --- a/chat/network.py +++ b/chat/network.py @@ -1,5 +1,3 @@ -# -*- tab-width: 4; indent-tabs-mode: t -*- - import socket import threading import traceback diff --git a/chat/presence.py b/chat/presence.py index 8b88492f..45a31f96 100644 --- a/chat/presence.py +++ b/chat/presence.py @@ -1,5 +1,3 @@ -# -*- tab-width: 4; indent-tabs-mode: t -*- - import avahi, dbus, dbus.glib OLPC_CHAT_SERVICE = "_olpc_chat._udp" diff --git a/shell/src/shell.py b/shell/src/shell.py index f5f648d5..ffeceecb 100755 --- a/shell/src/shell.py +++ b/shell/src/shell.py @@ -10,7 +10,7 @@ import gobject import pygtk pygtk.require('2.0') import gtk - +import pango activity_counter = 0 @@ -34,31 +34,42 @@ class ActivityHost(dbus.service.Object): self.socket.set_data("sugar-activity", self) self.socket.show() - hbox = gtk.HBox(); + hbox = gtk.HBox(False, 4); + self.tab_activity_image = gtk.Image() self.tab_activity_image.set_from_stock(gtk.STOCK_CONVERT, gtk.ICON_SIZE_MENU) - self.tab_activity_image.show() + hbox.pack_start(self.tab_activity_image) + self.tab_activity_image.show() + label_hbox = gtk.HBox(False, 4); + label_hbox.connect("style-set", self.__tab_label_style_set_cb) + hbox.pack_start(label_hbox) + self.tab_label = gtk.Label(self.activity_name) + self.tab_label.set_ellipsize(pango.ELLIPSIZE_END) + self.tab_label.set_single_line_mode(True) + self.tab_label.set_alignment(0.0, 0.5) + self.tab_label.set_padding(0, 0) self.tab_label.show() - self.tab_close_button = gtk.Button() - settings = self.tab_close_button.get_settings() - [w, h] = gtk.icon_size_lookup_for_settings(settings, gtk.ICON_SIZE_MENU) - self.tab_close_button.set_size_request(w + 2, h + 2) close_image = gtk.Image() close_image.set_from_stock (gtk.STOCK_CLOSE, gtk.ICON_SIZE_MENU) close_image.show() + + self.tab_close_button = gtk.Button() + rcstyle = gtk.RcStyle(); + rcstyle.xthickness = rcstyle.ythickness = 0; + self.tab_close_button.modify_style (rcstyle); self.tab_close_button.add(close_image) self.tab_close_button.set_relief(gtk.RELIEF_NONE) self.tab_close_button.set_focus_on_click(gtk.FALSE) self.tab_close_button.show() self.tab_close_button.connect("clicked", self.tab_close_button_clicked) - hbox.set_spacing(4) - hbox.pack_start(self.tab_activity_image) - hbox.pack_start(self.tab_label) - hbox.pack_start(self.tab_close_button) + label_hbox.pack_start(self.tab_label) + label_hbox.pack_start(self.tab_close_button, False, False, 0) + label_hbox.show() + hbox.show() notebook = self.activity_container.notebook @@ -117,6 +128,13 @@ class ActivityHost(dbus.service.Object): def get_object_path(self): return self.dbus_object_name + def __tab_label_style_set_cb(self, widget, previous_style): + context = widget.get_pango_context() + metrics = context.get_metrics(widget.style.font_desc, context.get_language()) + char_width = metrics.get_approximate_digit_width() + [w, h] = gtk.icon_size_lookup_for_settings(widget.get_settings(), gtk.ICON_SIZE_MENU) + widget.set_size_request(15 * pango.PIXELS(char_width) + 2 * w, -1); + self.tab_close_button.set_size_request (w + 5, h + 2) class ActivityContainer(dbus.service.Object):