From 81c65ccac80691d3742e209ca6678ace0d419a09 Mon Sep 17 00:00:00 2001 From: Yann Leboulanger Date: Fri, 14 Sep 2007 20:18:06 +0000 Subject: [PATCH] [steve-e] Ability to select a jid in history window. fixes #3410, #3308, #1925 --- data/glade/history_window.glade | 663 +++++++++++++++----------------- data/glade/roster_window.glade | 17 + src/chat_control.py | 7 +- src/common/logger.py | 3 + src/gajim.py | 2 +- src/history_window.py | 147 +++++-- src/roster_window.py | 14 +- 7 files changed, 464 insertions(+), 389 deletions(-) diff --git a/data/glade/history_window.glade b/data/glade/history_window.glade index b475f03b4..23f2784c4 100644 --- a/data/glade/history_window.glade +++ b/data/glade/history_window.glade @@ -1,346 +1,321 @@ - - - + + + - - - Conversation History - GTK_WINDOW_TOPLEVEL - GTK_WIN_POS_NONE - False - 650 - 350 - True - False - history - True - False - False - GDK_WINDOW_TYPE_HINT_NORMAL - GDK_GRAVITY_NORTH_WEST - True - - - - - 6 - True - False - 6 - - - - True - True - 165 - - - - True - False - 6 - - - - True - True - GTK_CALENDAR_SHOW_HEADING|GTK_CALENDAR_SHOW_DAY_NAMES - - - - - 0 - False - True - - - - - True - False - - - - - - True - True - GTK_POLICY_AUTOMATIC - GTK_POLICY_AUTOMATIC - GTK_SHADOW_ETCHED_IN - GTK_CORNER_TOP_LEFT - - - - - - - True - True - - - - - 0 - True - True - - - - - - True - True - _Log conversation history - True - GTK_RELIEF_NORMAL - True - True - False - True - - - 0 - False - False - - - - - - True - True - False - 0 - - - - - True - False - 6 - - - - True - False - 6 - - - - True - True - True - True - 0 - - True - * - True - - - 0 - True - True - - - - - - True - True - True - True - GTK_RELIEF_NORMAL - True - - - - - True - 0.5 - 0.5 - 0 - 0 - 0 - 0 - 0 - 0 - - - - True - False - 2 - - - - True - gtk-find - 4 - 0.5 - 0.5 - 0 - 0 - - - 0 - False - False - - - - - - True - Search - True - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - 0 - False - False - - - - - - - - - 0 - False - False - - - - - - True - Build custom query - True - Query Builder... - True - GTK_RELIEF_NORMAL - True - - - - 0 - False - False - - - - - 0 - False - True - - - - - - True - True - GTK_POLICY_AUTOMATIC - GTK_POLICY_AUTOMATIC - GTK_SHADOW_IN - GTK_CORNER_TOP_LEFT - - - - True - True - True - True - False - True - False - False - False - - - - - - 0 - True - True - - - - - - - - True - _Search - True - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - PANGO_ELLIPSIZE_NONE - -1 - False - 0 - - - label_item - - - - - 0 - False - True - - - - - - True - GTK_BUTTONBOX_END - 6 - - - - True - True - True - gtk-close - True - GTK_RELIEF_NORMAL - True - - - - - - 0 - False - False - - - - - - + + Conversation History + history + 650 + 350 + + + + True + 6 + 6 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + GTK_SHADOW_NONE + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + Enter a contact jid or MUC jid here to view its history. +If a contact is connected you can even enter his nick name. + + True + + + False + False + 1 + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>JID Selection</b> + True + + + label_item + + + + + False + False + 8 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + GTK_SHADOW_NONE + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + True + 165 + + + True + 6 + + + True + True + + + + + False + + + + + False + False + + + + + True + True + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_SHADOW_ETCHED_IN + + + + + + True + False + + + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>History Viewer</b> + True + + + label_item + + + + + 1 + + + + + True + True + _Log conversation history + True + 0 + True + True + + + False + False + 2 + + + + + True + True + + + + True + 6 + + + True + 6 + + + True + True + True + + + + + True + True + True + True + 0 + + + + True + 0 + 0 + + + True + 2 + + + True + gtk-find + + + False + False + + + + + True + Search + True + + + False + False + 1 + + + + + + + + + False + False + 1 + + + + + True + True + Build custom query + Query Builder... + True + 0 + + + + False + False + 2 + + + + + False + + + + + True + True + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_SHADOW_IN + + + True + True + True + + + + + + 1 + + + + + + + True + _Search + True + + + label_item + + + + + False + 3 + + + + + True + 6 + GTK_BUTTONBOX_END + + + True + True + True + gtk-close + True + 0 + + + + + + False + False + 4 + + + + + diff --git a/data/glade/roster_window.glade b/data/glade/roster_window.glade index c8bcd52e1..095680965 100644 --- a/data/glade/roster_window.glade +++ b/data/glade/roster_window.glade @@ -243,6 +243,23 @@ + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + _History + True + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + gtk-justify-fill + 1 + + + + diff --git a/src/chat_control.py b/src/chat_control.py index 5898c30dc..06a17cac7 100644 --- a/src/chat_control.py +++ b/src/chat_control.py @@ -715,10 +715,11 @@ class ChatControlBase(MessageControl): if not jid: jid = self.contact.jid - if gajim.interface.instances['logs'].has_key(jid): - gajim.interface.instances['logs'][jid].window.present() + if gajim.interface.instances.has_key('logs'): + gajim.interface.instances['logs'].window.present() + gajim.interface.instances['logs'].open_history(jid, self.account) else: - gajim.interface.instances['logs'][jid] = \ + gajim.interface.instances['logs'] = \ history_window.HistoryWindow(jid, self.account) def on_minimize_menuitem_toggled(self, widget): diff --git a/src/common/logger.py b/src/common/logger.py index 1dd06e563..a82eb8776 100644 --- a/src/common/logger.py +++ b/src/common/logger.py @@ -137,6 +137,9 @@ class Logger: for row in rows: # row[0] is first item of row (the only result here, the jid) self.jids_already_in.append(row[0]) + + def get_jids_in_db(self): + return self.jids_already_in def jid_is_from_pm(self, jid): '''if jid is gajim@conf/nkour it's likely a pm one, how we know diff --git a/src/gajim.py b/src/gajim.py index b4f83cb73..e523ed2cb 100755 --- a/src/gajim.py +++ b/src/gajim.py @@ -2660,7 +2660,7 @@ class Interface: if gtk.pygtk_version >= (2, 10, 0) and gtk.gtk_version >= (2, 10, 0): gtk.link_button_set_uri_hook(self.on_launch_browser_mailer, 'url') - self.instances = {'logs': {}} + self.instances = {} for a in gajim.connections: self.instances[a] = {'infos': {}, 'disco': {}, 'gc_config': {}, diff --git a/src/history_window.py b/src/history_window.py index 19af94b73..0464fa06a 100644 --- a/src/history_window.py +++ b/src/history_window.py @@ -49,14 +49,19 @@ C_TIME class HistoryWindow: '''Class for browsing logs of conversations with contacts''' - def __init__(self, jid, account): - self.jid = jid + def __init__(self, jid = None, account = None): + if jid is None: + self.jid = 'Enter jid or contact name here' + else: + self.jid = jid self.account = account + self.mark_days_idle_call_id = None xml = gtkgui_helpers.get_glade('history_window.glade') self.window = xml.get_widget('history_window') + self.jid_entry = xml.get_widget('jid_entry') self.calendar = xml.get_widget('calendar') scrolledwindow = xml.get_widget('scrolledwindow') self.history_textview = conversation_textview.ConversationTextview( @@ -64,6 +69,8 @@ class HistoryWindow: scrolledwindow.add(self.history_textview.tv) self.history_buffer = self.history_textview.tv.get_buffer() self.history_buffer.create_tag('highlight', background = 'yellow') + self.checkbutton = xml.get_widget('log_history_checkbutton') + self.checkbutton.connect('toggled', self.on_log_history_checkbutton_toggled) self.query_entry = xml.get_widget('query_entry') self.search_button = xml.get_widget('search_button') query_builder_button = xml.get_widget('query_builder_button') @@ -72,6 +79,29 @@ class HistoryWindow: self.expander_vbox = xml.get_widget('expander_vbox') self.results_treeview = xml.get_widget('results_treeview') + + # create jid dict for auto completion + self.completion_dict = {} + liststore = gtkgui_helpers.get_completion_liststore(self.jid_entry) + + # Add all jids in the db + db_jids = gajim.logger.get_jids_in_db() + for jid in db_jids: + self.completion_dict[jid] = jid + + # Enhance contacts of online accounts with their names + for account in gajim.contacts.get_accounts(): + self.completion_dict.update(helpers.get_contact_dict_for_account(account)) + keys = self.completion_dict.keys() + keys.sort() + # Add icons + for jid in keys: + if gajim.logger.jid_is_room_jid(jid): + img = gajim.interface.roster.load_icon('muc_active') + else: + img = gajim.interface.roster.jabber_state_images['16']['online'] + liststore.append((img.get_pixbuf(), jid)) + # contact_name, date, message, time model = gtk.ListStore(str, str, str, str) self.results_treeview.set_model(model) @@ -98,43 +128,10 @@ class HistoryWindow: col.set_attributes(renderer, text = C_MESSAGE) col.set_resizable(True) - contact = gajim.contacts.get_first_contact_from_jid(account, jid) - if contact: - title = _('Conversation History with %s') % contact.get_shown_name() - else: - title = _('Conversation History with %s') % jid - self.window.set_title(title) + self.jid_entry.set_text(self.jid) xml.signal_autoconnect(self) - - # fake event so we start mark days procedure for selected month - # selected month is current month as calendar defaults to selecting - # current date - self.calendar.emit('month-changed') - - # select and show logs for last date we have logs with contact - # and if we don't have logs at all, default to today - result = gajim.logger.get_last_date_that_has_logs(self.jid, self.account) - if result is None: - date = time.localtime() - else: - tim = result - date = time.localtime(tim) - - y, m, d = date[0], date[1], date[2] - gtk_month = gtkgui_helpers.make_python_month_gtk_month(m) - self.calendar.select_month(gtk_month, y) - self.calendar.select_day(d) - self.add_lines_for_date(y, m, d) - - log = True - if self.jid in gajim.config.get_per('accounts', self.account, - 'no_log_for').split(' '): - log = False - checkbutton = xml.get_widget('log_history_checkbutton') - checkbutton.set_active(log) - checkbutton.connect('toggled', self.on_log_history_checkbutton_toggled) - + self.jid_entry.emit('activate') self.window.show_all() def on_history_window_destroy(self, widget): @@ -143,11 +140,80 @@ class HistoryWindow: # stop him! gobject.source_remove(self.mark_days_idle_call_id) self.history_textview.del_handlers() - del gajim.interface.instances['logs'][self.jid] + del gajim.interface.instances['logs'] + def on_close_button_clicked(self, widget): self.window.destroy() + def on_jid_entry_activate(self, widget): + self.jid = self.jid_entry.get_text() + + if self.completion_dict.has_key(self.jid): # a full qualified jid or contact name was entered + contact_name = self.completion_dict[self.jid] + if self.jid != contact_name: + self.jid = contact_name.jid # jid enhanced with contact + + accounts = gajim.contacts.get_accounts() + self.account = None + for account in accounts: + contact = gajim.contacts.get_first_contact_from_jid(account ,self.jid) + if contact: + self.account = account + break + if self.account is None: + # We do not know an account. This can only happen if the contact is offine, + # or if we browse a groupchat history. The account is not needed, a dummy can + # be set. + # FIXME: This may leed to wrong self nick in the displayed history + self.account = gajim.contacts.get_accounts()[0] + + # select logs for last date we have logs with contact + self.calendar.set_sensitive(True) + lastlog = gajim.logger.get_last_date_that_has_logs(self.jid, self.account) + + # Set the logging checkbutton + log = True + if self.jid in gajim.config.get_per('accounts', self.account, + 'no_log_for').split(' '): + log = False + self.checkbutton.set_active(log) + self.checkbutton.set_sensitive(True) + self.checkbutton.set_inconsistent(False) + + if contact: + title = _('Conversation History with %s') % contact.get_shown_name() + else: + title = _('Conversation History with %s') % self.jid + self.window.set_title(title) + + + else: # neither a valid jid, nor an existing contact name was entered + lastlog = None + + self.checkbutton.set_inconsistent(True) + self.checkbutton.set_sensitive(False) + + self.calendar.set_sensitive(False) + + title = _('Conversation History') + self.window.set_title(title) + + self.calendar.emit('month-changed') + + # Show logs for contact. If we don't have logs at all, default to today + if lastlog is None: + date = time.localtime() + else: + tim = lastlog + date = time.localtime(tim) + + y, m, d = date[0], date[1], date[2] + gtk_month = gtkgui_helpers.make_python_month_gtk_month(m) + self.calendar.select_month(gtk_month, y) + self.calendar.select_day(d) + self.add_lines_for_date(y, m, d) + def on_calendar_day_selected(self, widget): year, month, day = widget.get_date() # integers month = gtkgui_helpers.make_gtk_month_python_month(month) @@ -416,3 +482,8 @@ class HistoryWindow: gajim.config.set_per('accounts', self.account, 'no_log_for', ' '.join(no_log_for)) + def open_history(self, jid, account): + # Simulate that the jid was entered by hand + self.jid_entry.set_text(jid) + self.jid_entry.emit('activate') + diff --git a/src/roster_window.py b/src/roster_window.py index b812597b5..05ad866a9 100644 --- a/src/roster_window.py +++ b/src/roster_window.py @@ -1916,10 +1916,11 @@ class RosterWindow: def on_history(self, widget, contact, account): '''When history menuitem is activated: call log window''' - if gajim.interface.instances['logs'].has_key(contact.jid): - gajim.interface.instances['logs'][contact.jid].window.present() + if gajim.interface.instances.has_key('logs'): + gajim.interface.instances['logs'].window.present() + gajim.interface.instances['logs'].open_history(contact.jid, account) else: - gajim.interface.instances['logs'][contact.jid] = history_window.\ + gajim.interface.instances['logs'] = history_window.\ HistoryWindow(contact.jid, account) def on_disconnect(self, widget, jid, account): @@ -4008,6 +4009,13 @@ class RosterWindow: gajim.interface.instances['file_transfers'].window.present() else: gajim.interface.instances['file_transfers'].window.show_all() + + def on_history_menuitem_activate(self, widget): + if gajim.interface.instances.has_key('logs'): + gajim.interface.instances['logs'].window.present() + else: + gajim.interface.instances['logs'] = history_window.\ + HistoryWindow() def on_show_transports_menuitem_activate(self, widget): gajim.config.set('show_transports_group', widget.get_active())