[steve-e] Ability to select a jid in history window. fixes #3410, #3308, #1925

This commit is contained in:
Yann Leboulanger 2007-09-14 20:18:06 +00:00
parent b9712ab917
commit 81c65ccac8
7 changed files with 464 additions and 389 deletions

View File

@ -1,306 +1,67 @@
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> <!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--*- mode: xml -*-->
<glade-interface> <glade-interface>
<widget class="GtkWindow" id="history_window"> <widget class="GtkWindow" id="history_window">
<property name="title" translatable="yes">Conversation History</property> <property name="title" translatable="yes">Conversation History</property>
<property name="type">GTK_WINDOW_TOPLEVEL</property> <property name="role">history</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
<property name="default_width">650</property> <property name="default_width">650</property>
<property name="default_height">350</property> <property name="default_height">350</property>
<property name="resizable">True</property> <signal name="destroy" handler="on_history_window_destroy"/>
<property name="destroy_with_parent">False</property>
<property name="role">history</property>
<property name="decorated">True</property>
<property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
<signal name="destroy" handler="on_history_window_destroy" last_modification_time="Tue, 01 Mar 2005 16:30:31 GMT"/>
<child> <child>
<widget class="GtkVBox" id="vbox"> <widget class="GtkVBox" id="vbox">
<property name="visible">True</property>
<property name="border_width">6</property> <property name="border_width">6</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">6</property> <property name="spacing">6</property>
<child> <child>
<widget class="GtkHPaned" id="hpaned"> <widget class="GtkFrame" id="frame1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label_xalign">0</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<child>
<widget class="GtkAlignment" id="alignment1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="left_padding">12</property>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<widget class="GtkEntry" id="jid_entry">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="position">165</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<signal name="activate" handler="on_jid_entry_activate"/>
</widget>
</child>
<child> <child>
<widget class="GtkVBox" id="vbox"> <widget class="GtkLabel" id="label3">
<property name="visible">True</property> <property name="visible">True</property>
<property name="homogeneous">False</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="spacing">6</property> <property name="xalign">0</property>
<property name="label" translatable="yes">Enter a contact jid or MUC jid here to view its history.
<child> If a contact is connected you can even enter his nick name.
<widget class="GtkCalendar" id="calendar"> </property>
<property name="visible">True</property> <property name="wrap">True</property>
<property name="can_focus">True</property>
<property name="display_options">GTK_CALENDAR_SHOW_HEADING|GTK_CALENDAR_SHOW_DAY_NAMES</property>
<signal name="day_selected" handler="on_calendar_day_selected" last_modification_time="Sun, 20 Nov 2005 19:26:58 GMT"/>
<signal name="month_changed" handler="on_calendar_month_changed" last_modification_time="Thu, 24 Nov 2005 00:49:22 GMT"/>
</widget> </widget>
<packing> <packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="shrink">True</property>
<property name="resize">False</property>
</packing>
</child>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<placeholder/>
</child>
</widget>
<packing>
<property name="shrink">True</property>
<property name="resize">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="log_history_checkbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">_Log conversation history</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">True</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkExpander" id="search_expander">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="expanded">False</property>
<property name="spacing">0</property>
<signal name="activate" handler="on_search_expander_activate" last_modification_time="Tue, 29 Nov 2005 13:43:41 GMT"/>
<child>
<widget class="GtkVBox" id="expander_vbox">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">6</property>
<child>
<widget class="GtkHBox" id="query_hbox">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">6</property>
<child>
<widget class="GtkEntry" id="query_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char">*</property>
<property name="activates_default">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="search_button">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_search_button_clicked" last_modification_time="Tue, 29 Nov 2005 11:40:15 GMT"/>
<child>
<widget class="GtkAlignment" id="alignment99">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xscale">0</property>
<property name="yscale">0</property>
<property name="top_padding">0</property>
<property name="bottom_padding">0</property>
<property name="left_padding">0</property>
<property name="right_padding">0</property>
<child>
<widget class="GtkHBox" id="hbox3004">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">2</property>
<child>
<widget class="GtkImage" id="image1327">
<property name="visible">True</property>
<property name="stock">gtk-find</property>
<property name="icon_size">4</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label372">
<property name="visible">True</property>
<property name="label" translatable="yes">Search</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">False</property> <property name="fill">False</property>
<property name="position">1</property>
</packing> </packing>
</child> </child>
</widget> </widget>
</child> </child>
</widget> </widget>
</child> </child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child> <child>
<widget class="GtkButton" id="query_builder_button"> <widget class="GtkLabel" id="label1">
<property name="visible">True</property> <property name="visible">True</property>
<property name="tooltip" translatable="yes">Build custom query</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="can_focus">True</property> <property name="label" translatable="yes">&lt;b&gt;JID Selection&lt;/b&gt;</property>
<property name="label" translatable="yes">Query Builder...</property> <property name="use_markup">True</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_query_builder_button_clicked" last_modification_time="Tue, 29 Nov 2005 11:40:18 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkScrolledWindow" id="results_scrolledwindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<widget class="GtkTreeView" id="results_treeview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="headers_visible">True</property>
<property name="rules_hint">True</property>
<property name="reorderable">False</property>
<property name="enable_search">True</property>
<property name="fixed_height_mode">False</property>
<property name="hover_selection">False</property>
<property name="hover_expand">False</property>
<signal name="row_activated" handler="on_results_treeview_row_activated" last_modification_time="Tue, 29 Nov 2005 21:05:37 GMT"/>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label368">
<property name="visible">True</property>
<property name="label" translatable="yes">_Search</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget> </widget>
<packing> <packing>
<property name="type">label_item</property> <property name="type">label_item</property>
@ -308,39 +69,253 @@
</child> </child>
</widget> </widget>
<packing> <packing>
<property name="padding">0</property>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">True</property> <property name="fill">False</property>
<property name="padding">8</property>
</packing> </packing>
</child> </child>
<child> <child>
<widget class="GtkHButtonBox" id="hbuttonbox"> <widget class="GtkFrame" id="frame2">
<property name="visible">True</property> <property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property> <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="spacing">6</property> <property name="label_xalign">0</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<child> <child>
<widget class="GtkButton" id="close_button"> <widget class="GtkAlignment" id="alignment2">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="left_padding">12</property>
<child>
<widget class="GtkHPaned" id="hpaned">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="label">gtk-close</property> <property name="position">165</property>
<property name="use_stock">True</property> <child>
<property name="relief">GTK_RELIEF_NORMAL</property> <widget class="GtkVBox" id="vbox">
<property name="focus_on_click">True</property> <property name="visible">True</property>
<signal name="clicked" handler="on_close_button_clicked" last_modification_time="Tue, 01 Mar 2005 16:21:16 GMT"/> <property name="spacing">6</property>
<child>
<widget class="GtkCalendar" id="calendar">
<property name="visible">True</property>
<property name="can_focus">True</property>
<signal name="month_changed" handler="on_calendar_month_changed"/>
<signal name="day_selected" handler="on_calendar_day_selected"/>
</widget> </widget>
<packing>
<property name="expand">False</property>
</packing>
</child> </child>
</widget> </widget>
<packing> <packing>
<property name="padding">0</property> <property name="resize">False</property>
<property name="shrink">False</property>
</packing>
</child>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
<child>
<placeholder/>
</child>
</widget>
<packing>
<property name="resize">True</property>
<property name="shrink">False</property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">&lt;b&gt;History Viewer&lt;/b&gt;</property>
<property name="use_markup">True</property>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="log_history_checkbutton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">_Log conversation history</property>
<property name="use_underline">True</property>
<property name="response_id">0</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<widget class="GtkExpander" id="search_expander">
<property name="visible">True</property>
<property name="can_focus">True</property>
<signal name="activate" handler="on_search_expander_activate"/>
<child>
<widget class="GtkVBox" id="expander_vbox">
<property name="visible">True</property>
<property name="spacing">6</property>
<child>
<widget class="GtkHBox" id="query_hbox">
<property name="visible">True</property>
<property name="spacing">6</property>
<child>
<widget class="GtkEntry" id="query_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="activates_default">True</property>
</widget>
</child>
<child>
<widget class="GtkButton" id="search_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="response_id">0</property>
<signal name="clicked" handler="on_search_button_clicked"/>
<child>
<widget class="GtkAlignment" id="alignment99">
<property name="visible">True</property>
<property name="xscale">0</property>
<property name="yscale">0</property>
<child>
<widget class="GtkHBox" id="hbox3004">
<property name="visible">True</property>
<property name="spacing">2</property>
<child>
<widget class="GtkImage" id="image1327">
<property name="visible">True</property>
<property name="stock">gtk-find</property>
</widget>
<packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">False</property> <property name="fill">False</property>
</packing> </packing>
</child> </child>
<child>
<widget class="GtkLabel" id="label372">
<property name="visible">True</property>
<property name="label" translatable="yes">Search</property>
<property name="use_underline">True</property>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="query_builder_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip" translatable="yes">Build custom query</property>
<property name="label" translatable="yes">Query Builder...</property>
<property name="use_underline">True</property>
<property name="response_id">0</property>
<signal name="clicked" handler="on_query_builder_button_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
</packing>
</child>
<child>
<widget class="GtkScrolledWindow" id="results_scrolledwindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_IN</property>
<child>
<widget class="GtkTreeView" id="results_treeview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="rules_hint">True</property>
<signal name="row_activated" handler="on_results_treeview_row_activated"/>
</widget>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label368">
<property name="visible">True</property>
<property name="label" translatable="yes">_Search</property>
<property name="use_underline">True</property>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">3</property>
</packing>
</child>
<child>
<widget class="GtkHButtonBox" id="hbuttonbox">
<property name="visible">True</property>
<property name="spacing">6</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="close_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="label">gtk-close</property>
<property name="use_stock">True</property>
<property name="response_id">0</property>
<signal name="clicked" handler="on_close_button_clicked"/>
</widget>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">4</property>
</packing>
</child>
</widget> </widget>
</child> </child>
</widget> </widget>
</glade-interface> </glade-interface>

View File

@ -243,6 +243,23 @@
</child> </child>
</widget> </widget>
</child> </child>
<child>
<widget class="GtkImageMenuItem" id="history_menuitem">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="label" translatable="yes">_History</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_history_menuitem_activate"/>
<child internal-child="image">
<widget class="GtkImage" id="menu-item-image14">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="stock">gtk-justify-fill</property>
<property name="icon_size">1</property>
</widget>
</child>
</widget>
</child>
</widget> </widget>
</child> </child>
</widget> </widget>

View File

@ -715,10 +715,11 @@ class ChatControlBase(MessageControl):
if not jid: if not jid:
jid = self.contact.jid jid = self.contact.jid
if gajim.interface.instances['logs'].has_key(jid): if gajim.interface.instances.has_key('logs'):
gajim.interface.instances['logs'][jid].window.present() gajim.interface.instances['logs'].window.present()
gajim.interface.instances['logs'].open_history(jid, self.account)
else: else:
gajim.interface.instances['logs'][jid] = \ gajim.interface.instances['logs'] = \
history_window.HistoryWindow(jid, self.account) history_window.HistoryWindow(jid, self.account)
def on_minimize_menuitem_toggled(self, widget): def on_minimize_menuitem_toggled(self, widget):

View File

@ -138,6 +138,9 @@ class Logger:
# row[0] is first item of row (the only result here, the jid) # row[0] is first item of row (the only result here, the jid)
self.jids_already_in.append(row[0]) 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): def jid_is_from_pm(self, jid):
'''if jid is gajim@conf/nkour it's likely a pm one, how we know '''if jid is gajim@conf/nkour it's likely a pm one, how we know
gajim@conf is not a normal guy and nkour is not his resource? gajim@conf is not a normal guy and nkour is not his resource?

View File

@ -2660,7 +2660,7 @@ class Interface:
if gtk.pygtk_version >= (2, 10, 0) and gtk.gtk_version >= (2, 10, 0): 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') gtk.link_button_set_uri_hook(self.on_launch_browser_mailer, 'url')
self.instances = {'logs': {}} self.instances = {}
for a in gajim.connections: for a in gajim.connections:
self.instances[a] = {'infos': {}, 'disco': {}, 'gc_config': {}, self.instances[a] = {'infos': {}, 'disco': {}, 'gc_config': {},

View File

@ -49,14 +49,19 @@ C_TIME
class HistoryWindow: class HistoryWindow:
'''Class for browsing logs of conversations with contacts''' '''Class for browsing logs of conversations with contacts'''
def __init__(self, jid, account): def __init__(self, jid = None, account = None):
if jid is None:
self.jid = 'Enter jid or contact name here'
else:
self.jid = jid self.jid = jid
self.account = account self.account = account
self.mark_days_idle_call_id = None self.mark_days_idle_call_id = None
xml = gtkgui_helpers.get_glade('history_window.glade') xml = gtkgui_helpers.get_glade('history_window.glade')
self.window = xml.get_widget('history_window') self.window = xml.get_widget('history_window')
self.jid_entry = xml.get_widget('jid_entry')
self.calendar = xml.get_widget('calendar') self.calendar = xml.get_widget('calendar')
scrolledwindow = xml.get_widget('scrolledwindow') scrolledwindow = xml.get_widget('scrolledwindow')
self.history_textview = conversation_textview.ConversationTextview( self.history_textview = conversation_textview.ConversationTextview(
@ -64,6 +69,8 @@ class HistoryWindow:
scrolledwindow.add(self.history_textview.tv) scrolledwindow.add(self.history_textview.tv)
self.history_buffer = self.history_textview.tv.get_buffer() self.history_buffer = self.history_textview.tv.get_buffer()
self.history_buffer.create_tag('highlight', background = 'yellow') 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.query_entry = xml.get_widget('query_entry')
self.search_button = xml.get_widget('search_button') self.search_button = xml.get_widget('search_button')
query_builder_button = xml.get_widget('query_builder_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.expander_vbox = xml.get_widget('expander_vbox')
self.results_treeview = xml.get_widget('results_treeview') 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 # contact_name, date, message, time
model = gtk.ListStore(str, str, str, str) model = gtk.ListStore(str, str, str, str)
self.results_treeview.set_model(model) self.results_treeview.set_model(model)
@ -98,43 +128,10 @@ class HistoryWindow:
col.set_attributes(renderer, text = C_MESSAGE) col.set_attributes(renderer, text = C_MESSAGE)
col.set_resizable(True) col.set_resizable(True)
contact = gajim.contacts.get_first_contact_from_jid(account, jid) self.jid_entry.set_text(self.jid)
if contact:
title = _('Conversation History with %s') % contact.get_shown_name()
else:
title = _('Conversation History with %s') % jid
self.window.set_title(title)
xml.signal_autoconnect(self) xml.signal_autoconnect(self)
self.jid_entry.emit('activate')
# 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.window.show_all() self.window.show_all()
def on_history_window_destroy(self, widget): def on_history_window_destroy(self, widget):
@ -143,11 +140,80 @@ class HistoryWindow:
# stop him! # stop him!
gobject.source_remove(self.mark_days_idle_call_id) gobject.source_remove(self.mark_days_idle_call_id)
self.history_textview.del_handlers() self.history_textview.del_handlers()
del gajim.interface.instances['logs'][self.jid] del gajim.interface.instances['logs']
def on_close_button_clicked(self, widget): def on_close_button_clicked(self, widget):
self.window.destroy() 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): def on_calendar_day_selected(self, widget):
year, month, day = widget.get_date() # integers year, month, day = widget.get_date() # integers
month = gtkgui_helpers.make_gtk_month_python_month(month) 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', gajim.config.set_per('accounts', self.account, 'no_log_for',
' '.join(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')

View File

@ -1916,10 +1916,11 @@ class RosterWindow:
def on_history(self, widget, contact, account): def on_history(self, widget, contact, account):
'''When history menuitem is activated: call log window''' '''When history menuitem is activated: call log window'''
if gajim.interface.instances['logs'].has_key(contact.jid): if gajim.interface.instances.has_key('logs'):
gajim.interface.instances['logs'][contact.jid].window.present() gajim.interface.instances['logs'].window.present()
gajim.interface.instances['logs'].open_history(contact.jid, account)
else: else:
gajim.interface.instances['logs'][contact.jid] = history_window.\ gajim.interface.instances['logs'] = history_window.\
HistoryWindow(contact.jid, account) HistoryWindow(contact.jid, account)
def on_disconnect(self, widget, jid, account): def on_disconnect(self, widget, jid, account):
@ -4009,6 +4010,13 @@ class RosterWindow:
else: else:
gajim.interface.instances['file_transfers'].window.show_all() 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): def on_show_transports_menuitem_activate(self, widget):
gajim.config.set('show_transports_group', widget.get_active()) gajim.config.set('show_transports_group', widget.get_active())
self.draw_roster() self.draw_roster()