diff --git a/src/common/connection.py b/src/common/connection.py index f9bd765f8..52217823c 100644 --- a/src/common/connection.py +++ b/src/common/connection.py @@ -118,7 +118,7 @@ class Connection: 'AGENT_INFO_INFO': [], 'QUIT': [], 'ACC_OK': [], 'MYVCARD': [], 'OS_INFO': [], 'VCARD': [], 'GC_MSG': [], 'GC_SUBJECT': [], 'GC_CONFIG': [], 'BAD_PASSPHRASE': [], 'ROSTER_INFO': [], - 'ERROR_ANSWER': [], 'JOIN_GC': [],} + 'ERROR_ANSWER': [], 'BOOKMARK': [],} self.name = name self.connected = 0 # offline self.connection = None # xmpppy instance @@ -567,13 +567,15 @@ class Connection: 'password':conf.getTagData('password'), 'nick':conf.getTagData('nick') } + self.dispatch("BOOKMARK", bm) + self.bookmarks.append(bm) + if bm['autojoin']=="1": jid = common.xmpp.protocol.JID(conf.getAttr("jid")) server = jid.getDomain() room = jid.getNode() gc = self.join_gc(bm['nick'], room, server, bm['password']) - self.dispatch("JOIN_GC", [jid.getStripped(), bm['nick']]) - self.bookmarks.append(bm) + elif ns=="gajim:prefs": #Preferences data #http://www.jabber.org/jeps/jep-0049.html diff --git a/src/config.py b/src/config.py index 67dbc01b6..488457406 100644 --- a/src/config.py +++ b/src/config.py @@ -2344,3 +2344,153 @@ class Remove_account_window: if self.plugin.windows.has_key('accounts'): self.plugin.windows['accounts'].init_accounts() self.window.destroy() + +#---------- ManageBookmarksWindow class -------------# +class ManageBookmarksWindow: + def __init__(self, plugin): + self.plugin = plugin + self.xml = gtk.glade.XML(GTKGUI_GLADE, 'manage_bookmarks_window', APP) + self.window = self.xml.get_widget('manage_bookmarks_window') + + #Account-JID, RoomName, Room-JID, Autojoin, Passowrd, Nick + self.treestore = gtk.TreeStore(str, str, str, str, str, str) + + #Store bookmarks in treeview. + for account in gajim.connections: + iter = self.treestore.append(None, [None, account,None, + None, None, None]) + + for bookmark in gajim.connections[account].bookmarks: + if bookmark['name']=="": + #No name was given for this bookmark. + #Use the first part of JID instead... + name = bookmark['jid'].split("@")[0] + bookmark['name'] = name + self.treestore.append( iter, [ + account, + bookmark['name'], + bookmark['jid'], + bookmark['autojoin'], + bookmark['password'], + bookmark['nick'] ]) + + + self.view = self.xml.get_widget('bookmarks_treeview') + self.view.set_model(self.treestore) + + renderer = gtk.CellRendererText() + column = gtk.TreeViewColumn("Bookmarks", renderer, text=1) + self.view.append_column(column) + + self.selection = self.view.get_selection() + self.selection.connect("changed", self.bookmark_selected) + + + #Prepare input fields + self.title_entry = self.xml.get_widget('title_entry') + self.nick_entry = self.xml.get_widget('nick_entry') + self.server_entry = self.xml.get_widget('server_entry') + self.room_entry = self.xml.get_widget('room_entry') + self.pass_entry = self.xml.get_widget('pass_entry') + self.autojoin_checkbutton = self.xml.get_widget('autojoin_checkbutton') + + + self.xml.signal_autoconnect(self) + self.window.show_all() + + def on_manage_bookmarks_window_destroy(self, widget): + del self.plugin.windows['manage_bookmarks'] + + def on_add_bookmark_button_clicked(self,widget): + """ + Add a new bookmark. + """ + #Get the account that is currently used + #(the parent of the currently selected item) + + (model, iter) = self.selection.get_selected() + if not iter: + #Nothing selected, do nothing + pass + #FIXME: ErrorDialog + + parent = model.iter_parent(iter) + + if not parent: + #No parent, so we got an account -> add to this. + add_to = iter + else: + #We got a bookmark selected, so we add_to the parent: + add_to = parent + + account = model.get_value(add_to,1) + self.treestore.append(add_to, [account,_('New Room'),'','','','']) + + + def on_remove_bookmark_button_clicked(self, widget): + """ + Remove selected bookmark. + """ + (model, iter) = self.selection.get_selected() + if not iter: + #Nothing selected + return + elif not model.iter_parent(iter): + #Don't remove account iters + return + + model.remove(iter) + self.clear_fields() + + def on_ok_button_clicked(self, widget): + """ + Parse the treestore data into our new bookmarks array, + then send the new bookmarks to the server. + """ + pass + + def on_cancel_button_clicked(self, widget): + """ Just close the window... """ + self.window.destroy() + + def bookmark_selected(self, selection): + """ + Fill in the bookmark's data into the fields. + """ + (model, iter) = selection.get_selected() + + if not iter: + #After removing the last bookmark for one account + #this will be None, so we will just: + return + + if not model.iter_parent(iter): + #Top-level has no data (it's the account fields) + self.clear_fields() + return + + #Fill in the data for childs + self.title_entry.set_text(model.get_value(iter, 1)) + room_jid = model.get_value(iter, 2) + try: + (room, server) = room_jid.split("@") + except ValueError: + #We just added this one + room = '' + server = '' + self.room_entry.set_text(room) + self.server_entry.set_text(server) + if model.get_value(iter,3): + self.autojoin_checkbutton.set_active(True) + else: + self.autojoin_checkbutton.set_active(False) + self.pass_entry.set_text(model.get_value(iter,4)) + self.nick_entry.set_text(model.get_value(iter,5)) + + def clear_fields(self): + self.title_entry.set_text('') + self.room_entry.set_text('') + self.server_entry.set_text('') + self.pass_entry.set_text('') + self.nick_entry.set_text('') + diff --git a/src/gajim.py b/src/gajim.py index 673c1035c..92db61133 100755 --- a/src/gajim.py +++ b/src/gajim.py @@ -506,6 +506,8 @@ class Interface: def handle_event_vcard(self, account, array): if self.windows[account]['infos'].has_key(array['jid']): self.windows[account]['infos'][array['jid']].set_values(array) + if self.windows[account]['chats'].has_key(array['jid']): + self.windows[account]['chats'][array['jid']].set_avatar(array) def handle_event_os_info(self, account, array): if self.windows[account]['infos'].has_key(array[0]): @@ -570,13 +572,19 @@ class Interface: user.groups = array[4] self.roster.draw_contact(jid, account) - def handle_event_join_gc(self, account, array): - #('JOIN_GC', account, (jid, nick)) - jid = array[0] - nickname = array[1] - self.roster.new_room(jid, nickname, account) - self.windows[account]['gc'][jid].set_active_tab(jid) - self.windows[account]['gc'][jid].window.present() + def handle_event_bookmark(self, account, bm): + #('BOOKMARK', account, {name,jid,autojoin,password,nick}) + #We received a bookmark item from the server (JEP48) + + #Open GC window if neccessary + if bm['autojoin'] == "1": + jid = bm['jid'] + self.roster.new_room(jid, bm['nick'], account) + self.windows[account]['gc'][jid].set_active_tab(jid) + self.windows[account]['gc'][jid].window.present() + + ##FIXME: Add a menuitem + def read_sleepy(self): '''Check if we are idle''' @@ -740,7 +748,7 @@ class Interface: conn.register_handler('GC_CONFIG', self.handle_event_gc_config) conn.register_handler('BAD_PASSPHRASE', self.handle_event_bad_passphrase) conn.register_handler('ROSTER_INFO', self.handle_event_roster_info) - conn.register_handler('JOIN_GC', self.handle_event_join_gc) + conn.register_handler('BOOKMARK', self.handle_event_bookmark) def process_connections(self): try: diff --git a/src/groupchat_window.py b/src/groupchat_window.py index 814698fc6..def2b7d58 100644 --- a/src/groupchat_window.py +++ b/src/groupchat_window.py @@ -316,8 +316,6 @@ class Groupchat_window(chat.Chat): gajim.connections[self.account].bookmarks.append(bm) gajim.connections[self.account].store_bookmarks() - #FIXME: add code to add to Bookmarks group (should be account-specific) - #FIXME: use join_gc_window [where user can put password] and change the #name of the boookmark [default: fill with room's 'name'] dialogs.Information_dialog( diff --git a/src/roster_window.py b/src/roster_window.py index c1c7cd143..80733cb00 100644 --- a/src/roster_window.py +++ b/src/roster_window.py @@ -243,6 +243,17 @@ class Roster_window: def make_menu(self): '''create the main_window's menus''' + + + #FIXME: do with glade (didn't want to touch it because of possible conflicts) + editmenu = self.xml.get_widget('edit_menu_menu') + newitem = gtk.MenuItem('Bookmarks') + editmenu.append(newitem) + editmenu.show_all() + newitem.connect('activate', self.on_bookmarks_menuitem_activate) + + + new_message_menuitem = self.xml.get_widget('new_message_menuitem') join_gc_menuitem = self.xml.get_widget('join_gc_menuitem') add_new_contact_menuitem = self.xml.get_widget('add_new_contact_menuitem') @@ -306,6 +317,10 @@ class Roster_window: our_jid = gajim.config.get_per('accounts', account, 'name') + '@' +\ gajim.config.get_per('accounts', account, 'hostname') lbl = gtk.Label() + lbl.set_markup('abc') + item = gtk.MenuItem() + item.add(lbl) + #item = gtk.MenuItem(_('as ') + our_jid) item = gtk.MenuItem(_('as ') + our_jid) sub_menu.append(item) item.connect('activate', self.on_join_gc_activate, account) @@ -1064,6 +1079,9 @@ class Roster_window: else: self.plugin.windows['accounts'] = config.Accounts_window(self.plugin) + def on_bookmarks_menuitem_activate(self, widget): + config.ManageBookmarksWindow(self.plugin) + def close_all(self, dic): '''close all the windows in the given dictionary''' for w in dic.values(): diff --git a/src/tabbed_chat_window.py b/src/tabbed_chat_window.py index 510c0c411..36c59d66c 100644 --- a/src/tabbed_chat_window.py +++ b/src/tabbed_chat_window.py @@ -22,6 +22,8 @@ import gtk.glade import pango import gobject import time +import urllib +import base64 import dialogs import history_window @@ -117,6 +119,31 @@ class Tabbed_chat_window(chat.Chat): banner_avatar_eventbox = self.xmls[jid].get_widget('banner_avatar_eventbox') banner_avatar_eventbox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(bgcolor)) + def set_avatar(self, vcard): + if not vcard.has_key('PHOTO'): + return + img_decoded = None + if vcard['PHOTO'].has_key('BINVAL'): + try: + img_decoded = base64.decodestring(vcard['PHOTO']['BINVAL']) + except: + pass + elif vcard[i].has_key('EXTVAL'): + url = vcard[i]['EXTVAL'] + try: + fd = urllib.urlopen(url) + img_decoded = fd.read() + except: + pass + if img_decoded: + pixbufloader = gtk.gdk.PixbufLoader() + pixbufloader.write(img_decoded) + pixbuf = pixbufloader.get_pixbuf() + pixbufloader.close() + scaled_buf = pixbuf.scale_simple(46, 46, gtk.gdk.INTERP_HYPER) + image = self.xmls[vcard['jid']].get_widget('avatar_image') + image.set_from_pixbuf(scaled_buf) + image.show_all() def set_state_image(self, jid): prio = 0 @@ -246,6 +273,8 @@ class Tabbed_chat_window(chat.Chat): if self.plugin.queues[self.account].has_key(user.jid): self.read_queue(user.jid) + gajim.connections[self.account].request_vcard(user.jid) + def on_message_textview_key_press_event(self, widget, event): """When a key is pressed: if enter is pressed without the shit key, message (if not empty) is sent