~jtaylor/ubuntu/oneiric/gajim/multiple-CVE

« back to all changes in this revision

Viewing changes to src/history_window.py

  • Committer: Bazaar Package Importer
  • Author(s): Nafallo Bjälevik
  • Date: 2008-11-16 00:26:27 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20081116002627-4olie99o2rqc7001
Tags: 0.12~beta1-0ubuntu1
* New upstream beta release:
  + Security improvements: End-to-End encryption, SSL certificat verification
  + Ability to minimize groupchats in roster
  + Chat to groupchat transformation
  + Block/Unblock contacts directly from roster
  + Single window mode
  + PEP support (User activity, mood and tune)
  + Security improvements: Kerberos (GSSAPI) SASL Authentication mechanism
  + Improve GUI of some windows
  + Fix handling of invalid XML
  + Fix freeze on connection
* Dropped all changes, patches and backports.
* src/common/passwords.py:
  - Change keyring to 'login', which is what gets unlocked at login.
* debian/copyright:
  - Updated for the GPL-3 change and for the amount of upstream authors.
* debian/control:
  - Update Standards-Version and drop XS for Vcs-Bzr.
  - Add Homepage and use ${shlibs:Depends}.
* debian/rules:
  - Update to not ignore errors from make clean.
  - Update with dh_shlibdeps.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
##      history_window.py
2
 
##
3
 
## Contributors for this file:
4
 
##      - Yann Le Boulanger <asterix@lagaule.org>
5
 
##      - Nikos Kouremenos <kourem@gmail.com>
6
 
##
7
 
## Copyright (C) 2003-2004 Yann Le Boulanger <asterix@lagaule.org>
8
 
##                         Vincent Hanquez <tab@snarc.org>
9
 
## Copyright (C) 2005 Yann Le Boulanger <asterix@lagaule.org>
10
 
##                    Vincent Hanquez <tab@snarc.org>
11
 
##                    Nikos Kouremenos <kourem@gmail.com>
12
 
##                    Dimitur Kirov <dkirov@gmail.com>
13
 
##                    Travis Shirk <travis@pobox.com>
14
 
##                    Norman Rasmussen <norman@rasmussen.co.za>
15
 
##
16
 
## This program is free software; you can redistribute it and/or modify
 
1
# -*- coding:utf-8 -*-
 
2
## src/history_window.py
 
3
##
 
4
## Copyright (C) 2003-2008 Yann Leboulanger <asterix AT lagaule.org>
 
5
## Copyright (C) 2005 Vincent Hanquez <tab AT snarc.org>
 
6
## Copyright (C) 2005-2006 Nikos Kouremenos <kourem AT gmail.com>
 
7
## Copyright (C) 2006 Dimitur Kirov <dkirov AT gmail.com>
 
8
##                    Travis Shirk <travis AT pobox.com>
 
9
## Copyright (C) 2006-2008 Jean-Marie Traissard <jim AT lapin.org>
 
10
## Copyright (C) 2007-2008 Stephan Erb <steve-e AT h3c.de>
 
11
## Copyright (C) 2008 Brendan Taylor <whateley AT gmail.com>
 
12
##
 
13
## This file is part of Gajim.
 
14
##
 
15
## Gajim is free software; you can redistribute it and/or modify
17
16
## it under the terms of the GNU General Public License as published
18
 
## by the Free Software Foundation; version 2 only.
 
17
## by the Free Software Foundation; version 3 only.
19
18
##
20
 
## This program is distributed in the hope that it will be useful,
 
19
## Gajim is distributed in the hope that it will be useful,
21
20
## but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
21
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
22
## GNU General Public License for more details.
24
23
##
 
24
## You should have received a copy of the GNU General Public License
 
25
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
 
26
##
25
27
 
26
28
import gtk
27
29
import gobject
33
35
 
34
36
from common import gajim
35
37
from common import helpers
 
38
from common import exceptions
36
39
 
37
40
from common.logger import Constants
38
41
 
39
42
constants = Constants()
40
43
 
 
44
# Completion dict
 
45
(
 
46
C_INFO_JID,
 
47
C_INFO_ACCOUNT,
 
48
C_INFO_NAME,
 
49
C_INFO_COMPLETION
 
50
) = range(4)
 
51
 
41
52
# contact_name, date, message, time
42
53
(
 
54
C_LOG_JID,
43
55
C_CONTACT_NAME,
44
56
C_UNIXTIME,
45
57
C_MESSAGE,
46
58
C_TIME
47
 
) = range(4)
 
59
) = range(5)
48
60
 
49
61
class HistoryWindow:
50
62
        '''Class for browsing logs of conversations with contacts'''
51
63
 
52
 
        def __init__(self, jid, account):
53
 
                self.jid = jid
54
 
                self.account = account
55
 
                self.mark_days_idle_call_id = None
56
 
                
 
64
        def __init__(self, jid = None, account = None):
57
65
                xml = gtkgui_helpers.get_glade('history_window.glade')
58
66
                self.window = xml.get_widget('history_window')
59
 
                
 
67
                self.jid_entry = xml.get_widget('jid_entry')
60
68
                self.calendar = xml.get_widget('calendar')
61
69
                scrolledwindow = xml.get_widget('scrolledwindow')
62
70
                self.history_textview = conversation_textview.ConversationTextview(
64
72
                scrolledwindow.add(self.history_textview.tv)
65
73
                self.history_buffer = self.history_textview.tv.get_buffer()
66
74
                self.history_buffer.create_tag('highlight', background = 'yellow')
 
75
                self.checkbutton = xml.get_widget('log_history_checkbutton')
 
76
                self.checkbutton.connect('toggled',
 
77
                        self.on_log_history_checkbutton_toggled)
67
78
                self.query_entry = xml.get_widget('query_entry')
68
 
                self.search_button = xml.get_widget('search_button')
69
 
                query_builder_button = xml.get_widget('query_builder_button')
70
 
                query_builder_button.hide()
71
 
                query_builder_button.set_no_show_all(True)
72
 
                self.expander_vbox = xml.get_widget('expander_vbox')
73
 
                
 
79
                self.query_combobox = xml.get_widget('query_combobox')
 
80
                self.query_combobox.set_active(0)
74
81
                self.results_treeview = xml.get_widget('results_treeview')
 
82
                self.results_window = xml.get_widget('results_scrolledwindow')
 
83
                
75
84
                # contact_name, date, message, time
76
 
                model = gtk.ListStore(str, str, str, str)
 
85
                model = gtk.ListStore(str, str, str, str, str)
77
86
                self.results_treeview.set_model(model)
78
87
                col = gtk.TreeViewColumn(_('Name'))
79
88
                self.results_treeview.append_column(col)
97
106
                col.pack_start(renderer)
98
107
                col.set_attributes(renderer, text = C_MESSAGE)
99
108
                col.set_resizable(True)
100
 
                
101
 
                contact = gajim.contacts.get_first_contact_from_jid(account, jid)
102
 
                if contact:
103
 
                        title = _('Conversation History with %s') % contact.get_shown_name()
104
 
                else:
105
 
                        title = _('Conversation History with %s') % jid
106
 
                self.window.set_title(title)
107
 
                
 
109
        
 
110
                self.jid = None # The history we are currently viewing
 
111
                self.account = None
 
112
                self.completion_dict = {}
 
113
                self.accounts_seen_online = [] # Update dict when new accounts connect
 
114
                self.jids_to_search = []
 
115
 
 
116
                # This will load history too
 
117
                gobject.idle_add(self._fill_completion_dict().next)
 
118
 
 
119
                if jid:
 
120
                        self.jid_entry.set_text(jid)    
 
121
 
108
122
                xml.signal_autoconnect(self)
109
 
                
110
 
                # fake event so we start mark days procedure for selected month
111
 
                # selected month is current month as calendar defaults to selecting
112
 
                # current date
113
 
                self.calendar.emit('month-changed')
114
 
 
115
 
                # select and show logs for last date we have logs with contact
116
 
                # and if we don't have logs at all, default to today
117
 
                result = gajim.logger.get_last_date_that_has_logs(self.jid, self.account)
118
 
                if result is None:
119
 
                        date = time.localtime()
120
 
                else:
121
 
                        tim = result
122
 
                        date = time.localtime(tim)
123
 
 
124
 
                y, m, d = date[0], date[1], date[2]
125
 
                gtk_month = gtkgui_helpers.make_python_month_gtk_month(m)
126
 
                self.calendar.select_month(gtk_month, y)
127
 
                self.calendar.select_day(d)
128
 
                self.add_lines_for_date(y, m, d)
129
 
                
130
123
                self.window.show_all()
131
124
 
 
125
        def _fill_completion_dict(self):
 
126
                '''Fill completion_dict for key auto completion. Then load history for 
 
127
                current jid (by calling another function).
 
128
 
 
129
                Key will be either jid or full_completion_name  
 
130
                (contact name or long description like "pm-contact from groupchat....")
 
131
                
 
132
                {key : (jid, account, nick_name, full_completion_name}
 
133
                this is a generator and does pseudo-threading via idle_add()
 
134
                '''
 
135
                liststore = gtkgui_helpers.get_completion_liststore(self.jid_entry)
 
136
 
 
137
                # Add all jids in logs.db:
 
138
                db_jids = gajim.logger.get_jids_in_db()
 
139
                self.completion_dict = dict.fromkeys(db_jids)
 
140
                
 
141
                self.accounts_seen_online = gajim.contacts.get_accounts()[:]
 
142
 
 
143
                # Enhance contacts of online accounts with contact. Needed for mapping below
 
144
                for account in self.accounts_seen_online:
 
145
                        self.completion_dict.update(
 
146
                                helpers.get_contact_dict_for_account(account))
 
147
                
 
148
                muc_active_img = gtkgui_helpers.load_icon('muc_active')
 
149
                contact_img = gajim.interface.jabber_state_images['16']['online']
 
150
                muc_active_pix = muc_active_img.get_pixbuf()
 
151
                contact_pix = contact_img.get_pixbuf()
 
152
                
 
153
                keys = self.completion_dict.keys()
 
154
                # Move the actual jid at first so we load history faster
 
155
                actual_jid = self.jid_entry.get_text().decode('utf-8')
 
156
                if actual_jid in keys:
 
157
                        keys.remove(actual_jid)
 
158
                        keys.insert(0, actual_jid)
 
159
                if None in keys:
 
160
                        keys.remove(None)
 
161
                # Map jid to info tuple
 
162
                # Warning : This for is time critical with big DB 
 
163
                for key in keys:
 
164
                        completed = key
 
165
                        contact = self.completion_dict[completed]
 
166
                        if contact:
 
167
                                info_name = contact.get_shown_name()
 
168
                                info_completion = info_name
 
169
                                info_jid = contact.jid
 
170
                        else:
 
171
                                # Corrensponding account is offline, we know nothing
 
172
                                info_name = completed.split('@')[0]
 
173
                                info_completion = completed
 
174
                                info_jid = completed
 
175
                
 
176
                        info_acc = self._get_account_for_jid(info_jid)
 
177
                        
 
178
                        if gajim.logger.jid_is_room_jid(completed) or\
 
179
                        gajim.logger.jid_is_from_pm(completed):
 
180
                                pix = muc_active_pix
 
181
                                if gajim.logger.jid_is_from_pm(completed):
 
182
                                        # It's PM. Make it easier to find
 
183
                                        room, nick = gajim.get_room_and_nick_from_fjid(completed)
 
184
                                        info_completion = '%s from %s' % (nick, room)
 
185
                                        completed = info_completion
 
186
                                        info_name = nick
 
187
                        else:
 
188
                                pix = contact_pix
 
189
 
 
190
                        liststore.append((pix, completed))
 
191
                        self.completion_dict[key] = (info_jid, info_acc, info_name,
 
192
                                info_completion)
 
193
                        self.completion_dict[completed] = (info_jid, info_acc,
 
194
                                info_name, info_completion)
 
195
                        if key == actual_jid:
 
196
                                self._load_history(info_jid, info_acc)
 
197
                        yield True
 
198
                keys.sort()
 
199
                yield False
 
200
        
 
201
        def _get_account_for_jid(self, jid):
 
202
                '''Return the corresponding account of the jid.
 
203
                May be None if an account could not be found'''
 
204
                accounts = gajim.contacts.get_accounts()
 
205
                account = None
 
206
                for acc in accounts:
 
207
                        jid_list = gajim.contacts.get_jid_list(acc)
 
208
                        gc_list = gajim.contacts.get_gc_list(acc)
 
209
                        if jid in jid_list or jid in gc_list:
 
210
                                account = acc
 
211
                                break
 
212
                return account
 
213
 
132
214
        def on_history_window_destroy(self, widget):
133
 
                if self.mark_days_idle_call_id:
134
 
                        # if user destroys the window, and we have a generator filling mark days
135
 
                        # stop him!
136
 
                        gobject.source_remove(self.mark_days_idle_call_id)
137
215
                self.history_textview.del_handlers()
138
 
                del gajim.interface.instances['logs'][self.jid]
 
216
                del gajim.interface.instances['logs']
 
217
 
 
218
        def on_history_window_key_press_event(self, widget, event):
 
219
                if event.keyval == gtk.keysyms.Escape:
 
220
                        self.window.destroy()
139
221
 
140
222
        def on_close_button_clicked(self, widget):
141
223
                self.window.destroy()
142
224
 
 
225
        def on_jid_entry_activate(self, widget):
 
226
                if not self.query_combobox.get_active() < 0:
 
227
                        # Don't disable querybox when we have changed the combobox
 
228
                        # to GC or All and hit enter
 
229
                        return
 
230
                jid = self.jid_entry.get_text().decode('utf-8')
 
231
                account = None # we don't know the account, could be any. Search for it!
 
232
                self._load_history(jid, account)
 
233
                self.results_window.set_property('visible', False)
 
234
 
 
235
        def on_jid_entry_focus(self, widget, event):
 
236
                        widget.select_region(0, -1) # select text
 
237
 
 
238
        def _load_history(self, jid_or_name, account = None):
 
239
                '''Load history for the given jid/name and show it''' 
 
240
                if jid_or_name and jid_or_name in self.completion_dict: 
 
241
                        # a full qualified jid or a contact name was entered
 
242
                        info_jid, info_account, info_name, info_completion = self.completion_dict[jid_or_name]
 
243
                        self.jids_to_search = [info_jid]
 
244
                        self.jid = info_jid
 
245
 
 
246
                        if account:
 
247
                                self.account = account
 
248
                        else:
 
249
                                self.account = info_account
 
250
                        if self.account is None: 
 
251
                                # We don't know account. Probably a gc not opened or an
 
252
                                # account not connected.
 
253
                                # Disable possibility to say if we want to log or not
 
254
                                self.checkbutton.set_sensitive(False)
 
255
                        else:
 
256
                                # Are log disabled for account ?
 
257
                                if self.account in gajim.config.get_per('accounts', self.account,
 
258
                                        'no_log_for').split(' '):
 
259
                                        self.checkbutton.set_active(False)
 
260
                                        self.checkbutton.set_sensitive(False)
 
261
                                else:
 
262
                                        # Are log disabled for jid ?
 
263
                                        log = True
 
264
                                        if self.jid in gajim.config.get_per('accounts', self.account,
 
265
                                                'no_log_for').split(' '):
 
266
                                                log = False
 
267
                                        self.checkbutton.set_active(log)
 
268
                                        self.checkbutton.set_sensitive(True)
 
269
                        
 
270
                        self.jids_to_search = [info_jid]
 
271
 
 
272
                        # select logs for last date we have logs with contact
 
273
                        self.calendar.set_sensitive(True)
 
274
                        last_log = \
 
275
                                gajim.logger.get_last_date_that_has_logs(self.jid, self.account)
 
276
 
 
277
                        date = time.localtime(last_log)
 
278
 
 
279
                        y, m, d = date[0], date[1], date[2]
 
280
                        gtk_month = gtkgui_helpers.make_python_month_gtk_month(m)
 
281
                        self.calendar.select_month(gtk_month, y)
 
282
                        self.calendar.select_day(d)
 
283
                        
 
284
                        self.query_entry.set_sensitive(True)
 
285
                        self.query_entry.grab_focus()
 
286
 
 
287
                        title = _('Conversation History with %s') % info_name
 
288
                        self.window.set_title(title)
 
289
                        self.jid_entry.set_text(info_completion)
 
290
 
 
291
                else:   # neither a valid jid, nor an existing contact name was entered
 
292
                        # we have got nothing to show or to search in
 
293
                        self.jid = None
 
294
                        self.account = None
 
295
                        
 
296
                        self.history_buffer.set_text('') # clear the buffer
 
297
                        self.query_entry.set_sensitive(False)
 
298
 
 
299
                        self.checkbutton.set_sensitive(False)
 
300
                        self.calendar.set_sensitive(False)
 
301
                        self.calendar.clear_marks()
 
302
 
 
303
                        self.results_window.set_property('visible', False)
 
304
                        
 
305
                        title = _('Conversation History')
 
306
                        self.window.set_title(title)
 
307
 
143
308
        def on_calendar_day_selected(self, widget):
 
309
                if not self.jid:
 
310
                        return
144
311
                year, month, day = widget.get_date() # integers
145
312
                month = gtkgui_helpers.make_gtk_month_python_month(month)
146
 
                self.add_lines_for_date(year, month, day)
 
313
                self._add_lines_for_date(year, month, day)
147
314
                
148
 
        def do_possible_mark_for_days_in_this_month(self, widget, year, month):
149
 
                '''this is a generator and does pseudo-threading via idle_add()
150
 
                so it runs progressively! yea :)
151
 
                asks for days in this month if they have logs it bolds them (marks them)'''
152
 
                weekday, days_in_this_month = calendar.monthrange(year, month)
153
 
                log_days = gajim.logger.get_days_with_logs(self.jid, year,
154
 
                        month, days_in_this_month, self.account)
155
 
                for day in log_days:
156
 
                        widget.mark_day(day)
157
 
                        yield True
158
 
                yield False
159
 
        
160
315
        def on_calendar_month_changed(self, widget):
 
316
                '''asks for days in this month if they have logs it bolds them (marks 
 
317
                them)
 
318
                '''
 
319
                if not self.jid:
 
320
                        return
161
321
                year, month, day = widget.get_date() # integers
162
322
                # in gtk January is 1, in python January is 0,
163
323
                # I want the second
164
324
                # first day of month is 1 not 0
165
 
                if self.mark_days_idle_call_id:
166
 
                        # if user changed month, and we have a generator filling mark days
167
 
                        # stop him from marking dates for the previously selected month
168
 
                        gobject.source_remove(self.mark_days_idle_call_id)
169
325
                widget.clear_marks()
170
326
                month = gtkgui_helpers.make_gtk_month_python_month(month)
171
 
                self.mark_days_idle_call_id = gobject.idle_add(
172
 
                        self.do_possible_mark_for_days_in_this_month(widget, year, month).next)
 
327
                weekday, days_in_this_month = calendar.monthrange(year, month)
 
328
                try:
 
329
                        log_days = gajim.logger.get_days_with_logs(self.jid, year, month,
 
330
                                days_in_this_month, self.account)
 
331
                except exceptions.PysqliteOperationalError, e:
 
332
                        dialogs.ErrorDialog(_('Disk Error'), str(e))
 
333
                        return
 
334
                for day in log_days:
 
335
                        widget.mark_day(day)
173
336
 
174
 
        def get_string_show_from_constant_int(self, show):
 
337
        def _get_string_show_from_constant_int(self, show):
175
338
                if show == constants.SHOW_ONLINE:
176
339
                        show = 'online'
177
340
                elif show == constants.SHOW_CHAT:
187
350
 
188
351
                return show
189
352
 
190
 
        def add_lines_for_date(self, year, month, day):
 
353
        def _add_lines_for_date(self, year, month, day):
191
354
                '''adds all the lines for given date in textbuffer'''
192
355
                self.history_buffer.set_text('') # clear the buffer first
193
356
                self.last_time_printout = 0
198
361
                for line in lines:
199
362
                        # line[0] is contact_name, line[1] is time of message
200
363
                        # line[2] is kind, line[3] is show, line[4] is message
201
 
                        self.add_new_line(line[0], line[1], line[2], line[3], line[4])
 
364
                        self._add_new_line(line[0], line[1], line[2], line[3], line[4])
202
365
        
203
 
        def add_new_line(self, contact_name, tim, kind, show, message):
 
366
        def _add_new_line(self, contact_name, tim, kind, show, message):
204
367
                '''add a new line in textbuffer'''
205
368
                if not message and kind not in (constants.KIND_STATUS,
206
369
                        constants.KIND_GCSTATUS):
226
389
                tag_name = ''
227
390
                tag_msg = ''
228
391
                
229
 
                show = self.get_string_show_from_constant_int(show)
 
392
                show = self._get_string_show_from_constant_int(show)
230
393
                
231
394
                if kind == constants.KIND_GC_MSG:
232
395
                        tag_name = 'incoming'
233
396
                elif kind in (constants.KIND_SINGLE_MSG_RECV,
234
397
                constants.KIND_CHAT_MSG_RECV):
235
 
                        contact = gajim.contacts.get_first_contact_from_jid(self.account,
236
 
                                self.jid)
237
 
                        if contact:
238
 
                                # he is in our roster, use the name
239
 
                                contact_name = contact.get_shown_name()
240
 
                        else:
241
 
                                room_jid, nick = gajim.get_room_and_nick_from_fjid(self.jid)
242
 
                                # do we have him as gc_contact?
243
 
                                gc_contact = gajim.contacts.get_gc_contact(self.account, room_jid,
244
 
                                        nick)
245
 
                                if gc_contact:
246
 
                                        # so yes, it's pm!
247
 
                                        contact_name = nick
248
 
                                else:
249
 
                                        contact_name = self.jid.split('@')[0]
 
398
                        contact_name = self.completion_dict[self.jid][C_INFO_NAME]
250
399
                        tag_name = 'incoming'
251
400
                elif kind in (constants.KIND_SINGLE_MSG_SENT,
252
401
                constants.KIND_CHAT_MSG_SENT):
253
 
                        contact_name = gajim.nicks[self.account]
 
402
                        if self.account:
 
403
                                contact_name = gajim.nicks[self.account]
 
404
                        else: 
 
405
                                # we don't have roster, we don't know our own nick, use first
 
406
                                # account one (urk!)
 
407
                                account = gajim.contacts.get_accounts()[0] 
 
408
                                contact_name = gajim.nicks[account]
254
409
                        tag_name = 'outgoing'
255
410
                elif kind == constants.KIND_GCSTATUS:
256
411
                        # message here (if not None) is status message
289
444
                else:
290
445
                        self.history_textview.print_real_text(message)
291
446
 
292
 
        def set_unset_expand_on_expander(self, widget):
293
 
                '''expander has to have expand to TRUE so scrolledwindow resizes properly
294
 
                and does not have a static size. when expander is not expanded we set
295
 
                expand property (note the Box one) to FALSE
296
 
                to do this, we first get the box and then apply to expander widget
297
 
                the True/False thingy depending if it's expanded or not
298
 
                this function is called in a timeout just after expanded state changes'''
299
 
                parent = widget.get_parent() # vbox
300
 
                if not parent:
301
 
                        # Windows closed since we launch timeout
302
 
                        return
303
 
                expanded = widget.get_expanded()
304
 
                w, h = self.window.get_size()
305
 
                if expanded: # resize to larger in height the window
306
 
                        self.window.resize(w, int(h*1.3))
307
 
                else: # resize to smaller in height the window
308
 
                        self.window.resize(w, int(h/1.3))
309
 
                # now set expand so if manually resizing scrolledwindow resizes too
310
 
                parent.child_set_property(widget, 'expand', expanded)
311
 
        
312
 
        def on_search_expander_activate(self, widget):
313
 
                if widget.get_expanded(): # it's the OPPOSITE!, it's not expanded
314
 
                        gobject.timeout_add(200, self.set_unset_expand_on_expander, widget)
315
 
                else:
316
 
                        gobject.timeout_add(200, self.set_unset_expand_on_expander, widget)
317
 
                        self.search_button.grab_default()
318
 
                        self.query_entry.grab_focus()
319
 
        
320
 
        def on_search_button_clicked(self, widget):
 
447
        def on_query_entry_activate(self, widget):
321
448
                text = self.query_entry.get_text()
322
449
                model = self.results_treeview.get_model()
323
450
                model.clear()
324
451
                if text == '':
 
452
                        self.results_window.set_property('visible', False)      
325
453
                        return
326
 
                # contact_name, time, kind, show, message, subject
327
 
                results = gajim.logger.get_search_results_for_query(
328
 
                                                self.jid, text, self.account)
329
 
                #FIXME:
330
 
                # add "subject:  | message: " in message column if kind is single
331
 
                # also do we need show at all? (we do not search on subject)
332
 
                for row in results:
333
 
                        contact_name = row[0]
334
 
                        if not contact_name:
335
 
                                kind = row[2]
336
 
                                if kind == constants.KIND_CHAT_MSG_SENT: # it's us! :)
337
 
                                        contact_name = gajim.nicks[self.account]
338
 
                                else:
339
 
                                        contact = gajim.contacts.get_first_contact_from_jid(self.account,
340
 
                                                self.jid)
341
 
                                        if contact:
342
 
                                                contact_name = contact.get_shown_name()
 
454
                else:
 
455
                        self.results_window.set_property('visible', True)
 
456
 
 
457
                # perform search in preselected jids
 
458
                # jids are preselected with the query_combobox (all, single jid...)
 
459
                for jid in self.jids_to_search:
 
460
                        account = self.completion_dict[jid][C_INFO_ACCOUNT]
 
461
                        if account is None:
 
462
                                # We do not know an account. This can only happen if the contact is offine,
 
463
                                # or if we browse a groupchat history. The account is not needed, a dummy can
 
464
                                # be set.
 
465
                                # This may leed to wrong self nick in the displayed history (Uggh!)
 
466
                                account = gajim.contacts.get_accounts()[0]
 
467
 
 
468
                        # contact_name, time, kind, show, message, subject
 
469
                        results = gajim.logger.get_search_results_for_query(
 
470
                                                jid, text, account)
 
471
                        #FIXME:
 
472
                        # add "subject:  | message: " in message column if kind is single
 
473
                        # also do we need show at all? (we do not search on subject)
 
474
                        for row in results:
 
475
                                contact_name = row[0]
 
476
                                if not contact_name:
 
477
                                        kind = row[2]
 
478
                                        if kind == constants.KIND_CHAT_MSG_SENT: # it's us! :)
 
479
                                                contact_name = gajim.nicks[account]
343
480
                                        else:
344
 
                                                contact_name = self.jid
345
 
                        tim = row[1]
346
 
                        message = row[4]
347
 
                        local_time = time.localtime(tim)
348
 
                        date = time.strftime('%x', local_time)
349
 
                        # name, date, message, time (full unix time)
350
 
                        model.append((contact_name, date, message, tim))
351
 
                        
 
481
                                                contact_name = self.completion_dict[jid][C_INFO_NAME]
 
482
                                tim = row[1]
 
483
                                message = row[4]
 
484
                                local_time = time.localtime(tim)
 
485
                                date = time.strftime('%Y-%m-%d', local_time)
 
486
 
 
487
                                #  jid (to which log is assigned to), name, date, message, 
 
488
                                # time (full unix time)
 
489
                                model.append((jid, contact_name, date, message, tim))
 
490
 
 
491
        def on_query_combobox_changed(self, widget):
 
492
                if self.query_combobox.get_active() < 0:
 
493
                        return # custom entry
 
494
                self.account = None
 
495
                self.jid = None
 
496
                self.jids_to_search = []
 
497
                self._load_history(None) # clear textview
 
498
 
 
499
                if self.query_combobox.get_active() == 0:
 
500
                        # JID or Contact name
 
501
                        self.query_entry.set_sensitive(False)
 
502
                        self.jid_entry.grab_focus()
 
503
                if self.query_combobox.get_active() == 1:
 
504
                        # Groupchat Histories
 
505
                        self.query_entry.set_sensitive(True)
 
506
                        self.query_entry.grab_focus()
 
507
                        self.jids_to_search = (jid for jid in gajim.logger.get_jids_in_db() 
 
508
                                        if gajim.logger.jid_is_room_jid(jid))
 
509
                if self.query_combobox.get_active() == 2:
 
510
                        # All Chat Histories
 
511
                        self.query_entry.set_sensitive(True)
 
512
                        self.query_entry.grab_focus()
 
513
                        self.jids_to_search = gajim.logger.get_jids_in_db()
 
514
                                
352
515
        def on_results_treeview_row_activated(self, widget, path, column):
353
516
                '''a row was double clicked, get date from row, and select it in calendar
354
517
                which results to showing conversation logs for that date'''
357
520
                cur_month = gtkgui_helpers.make_gtk_month_python_month(cur_month)
358
521
                model = widget.get_model()
359
522
                # make it a tupple (Y, M, D, 0, 0, 0...)
360
 
                tim = time.strptime(model[path][C_UNIXTIME], '%x')
 
523
                tim = time.strptime(model[path][C_UNIXTIME], '%Y-%m-%d')
361
524
                year = tim[0]
362
525
                gtk_month = tim[1]
363
526
                month = gtkgui_helpers.make_python_month_gtk_month(gtk_month)
364
527
                day = tim[2]
365
 
                
 
528
                        
 
529
                # switch to belonging logfile if necessary
 
530
                log_jid = model[path][C_LOG_JID]
 
531
                if log_jid != self.jid:
 
532
                        self._load_history(log_jid, None)
 
533
 
366
534
                # avoid reruning mark days algo if same month and year!
367
535
                if year != cur_year or gtk_month != cur_month:
368
536
                        self.calendar.select_month(month, year)
369
537
                
370
538
                self.calendar.select_day(day)
371
539
                unix_time = model[path][C_TIME]
372
 
                self.scroll_to_result(unix_time)
 
540
                self._scroll_to_result(unix_time)
373
541
                #FIXME: one day do not search just for unix_time but the whole and user
374
542
                # specific format of the textbuffer line [time] nick: message
375
543
                # and highlight all that
376
544
 
377
 
        def scroll_to_result(self, unix_time):
 
545
        def _scroll_to_result(self, unix_time):
378
546
                '''scrolls to the result using unix_time and highlight line'''
379
547
                start_iter = self.history_buffer.get_start_iter()
380
548
                local_time = time.localtime(float(unix_time))
391
559
                        match_start_mark = self.history_buffer.create_mark('match_start',
392
560
                                match_start_iter, True)
393
561
                        self.history_textview.tv.scroll_to_mark(match_start_mark, 0, True)
 
562
 
 
563
        def on_log_history_checkbutton_toggled(self, widget):
 
564
                # log conversation history?
 
565
                oldlog = True
 
566
                no_log_for = gajim.config.get_per('accounts', self.account,
 
567
                        'no_log_for').split()
 
568
                if self.jid in no_log_for:
 
569
                        oldlog = False
 
570
                log = widget.get_active()
 
571
                if not log and not self.jid in no_log_for:
 
572
                        no_log_for.append(self.jid)
 
573
                if log and self.jid in no_log_for:
 
574
                        no_log_for.remove(self.jid)
 
575
                if oldlog != log:
 
576
                        gajim.config.set_per('accounts', self.account, 'no_log_for',
 
577
                                ' '.join(no_log_for))
 
578
 
 
579
        def open_history(self, jid, account):
 
580
                '''Load chat history of the specified jid'''
 
581
                self.jid_entry.set_text(jid)
 
582
                if account and account not in self.accounts_seen_online:
 
583
                        # Update dict to not only show bare jid
 
584
                        gobject.idle_add(self._fill_completion_dict().next)
 
585
                else:
 
586
                        # Only in that case because it's called by self._fill_completion_dict()
 
587
                        # otherwise 
 
588
                        self._load_history(jid, account)
 
589
                self.results_window.set_property('visible', False)
 
590
 
 
591
# vim: se ts=3: