1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
|
# -*- coding: utf-8 -*-
##
import gtk
import gtkgui_helpers
from plugins.gui import GajimPluginConfigDialog
from plugins import GajimPlugin
from plugins.helpers import log_calls
from common import ged
from common import gajim
from common.i18n import Q_
from config import ManageBookmarksWindow
class OfflineBookmarksPlugin(GajimPlugin):
@log_calls('OfflineBookmarksPlugin')
def init(self):
self.description = _('Saving bookmarks inside the plugin configuration '
'file. Allows the use of locally stored bookmarks if the server '
'does not support the storage of bookmarks (eg talk.google.com).<br/>'
'Support to import bookmarks from one account to another.')
self.events_handlers = {
'bookmarks-received': (ged.POSTGUI, self.bookmarks_received),
'signed-in': (ged.POSTGUI, self.handle_event_signed_in),}
self.gui_extension_points = {
'groupchat_control': (self.connect_with_gc_control,
self.disconnect_from_gc_control),}
self.controls = []
self.config_dialog = OfflineBookmarksPluginConfigDialog(self)
@log_calls('OfflineBookmarksPlugin')
def activate(self):
pass
@log_calls('OfflineBookmarksPlugin')
def deactivate(self):
pass
def save_bookmarks(self, account, bookmarks):
jid = gajim.get_jid_from_account(account)
if jid not in self.config:
self.config[jid] = {}
self.config[jid] = bookmarks
def bookmarks_received(self, obj):
self.save_bookmarks(obj.conn.name, obj.bookmarks)
def handle_event_signed_in(self, obj):
account = obj.conn.name
connection = gajim.connections[account]
jid = gajim.get_jid_from_account(obj.conn.name)
bm_jids = [b['jid'] for b in connection.bookmarks]
if jid in self.config:
for bm in self.config[jid]:
if bm['jid'] not in bm_jids:
connection.bookmarks.append(bm)
invisible_show = gajim.SHOW_LIST.index('invisible')
# do not autojoin if we are invisible
if connection.connected == invisible_show:
return
# do not autojoin if bookmarks supported
bookmarks_supported = self.is_bookmark_supported(
gajim.connections[account])
if not bookmarks_supported:
gajim.interface.auto_join_bookmarks(connection.name)
def connect_with_gc_control(self, gc_control):
control = Base(self, gc_control)
self.controls.append(control)
def disconnect_from_gc_control(self, gc_control):
for control in self.controls:
control.disconnect_from_gc_control()
self.controls = []
def is_bookmark_supported(self, account):
if account.is_zeroconf:
return False
return (account.private_storage_supported or (
account.pubsub_supported and account.pubsub_publish_options_supported))
class Base(object):
def __init__(self, plugin, gc_control):
self.plugin = plugin
self.gc_control = gc_control
self.create_buttons()
def create_buttons(self):
# create button
actions_hbox = self.gc_control.xml.get_object('actions_hbox')
self.button = gtk.Button(label=None, stock=None, use_underline=True)
self.button.set_property('relief', gtk.RELIEF_NONE)
self.button.set_property('can-focus', False)
img = gtk.Image()
if gtkgui_helpers.gtk_icon_theme.has_icon('bookmark-new'):
img.set_from_icon_name('bookmark-new', gtk.ICON_SIZE_MENU)
else:
img.set_from_stock('gtk-add', gtk.ICON_SIZE_MENU)
self.button.set_image(img)
self.button.set_tooltip_text(_('Bookmark this room(local)'))
send_button = self.gc_control.xml.get_object('send_button')
send_button_pos = actions_hbox.child_get_property(send_button,
'position')
actions_hbox.add_with_properties(self.button, 'position',
send_button_pos - 1, 'expand', False)
self.button.set_no_show_all(True)
id_ = self.button.connect('clicked', self.add_bookmark_button_clicked)
self.gc_control.handlers[id_] = self.button
for bm in gajim.connections[self.gc_control.account].bookmarks:
if bm['jid'] == self.gc_control.contact.jid:
self.button.hide()
break
else:
account = self.gc_control.account
bookmarks_supported = self.plugin.is_bookmark_supported(
gajim.connections[account])
self.button.set_sensitive(not bookmarks_supported)
self.button.set_visible(not bookmarks_supported)
def add_bookmark_button_clicked(self, widget):
"""
Bookmark the room, without autojoin and not minimized
"""
from dialogs import ErrorDialog, InformationDialog
password = gajim.gc_passwords.get(self.gc_control.room_jid, '')
account = self.gc_control.account
bm = {'name': self.gc_control.name,
'jid': self.gc_control.room_jid,
'autojoin': 0,
'minimize': 0,
'password': password,
'nick': self.gc_control.nick}
place_found = False
index = 0
# check for duplicate entry and respect alpha order
for bookmark in gajim.connections[account].bookmarks:
if bookmark['jid'] == bm['jid']:
ErrorDialog(
_('Bookmark already set'),
_('Group Chat "%s" is already in your bookmarks.') % \
bm['jid'])
return
if bookmark['name'] > bm['name']:
place_found = True
break
index += 1
if place_found:
gajim.connections[account].bookmarks.insert(index, bm)
else:
gajim.connections[account].bookmarks.append(bm)
self.plugin.save_bookmarks(account, gajim.connections[account].bookmarks)
gajim.interface.roster.set_actions_menu_needs_rebuild()
InformationDialog(
_('Bookmark has been added successfully'),
_('You can manage your bookmarks via Actions menu in your roster.'))
def disconnect_from_gc_control(self):
actions_hbox = self.gc_control.xml.get_object('actions_hbox')
actions_hbox.remove(self.button)
class OfflineBookmarksPluginConfigDialog(GajimPluginConfigDialog,
ManageBookmarksWindow):
def init(self):
self.GTK_BUILDER_FILE_PATH = self.plugin.local_file_path(
'config_dialog.ui')
self.xml = gtk.Builder()
self.xml.set_translation_domain('gajim_plugins')
self.xml.add_objects_from_file(self.GTK_BUILDER_FILE_PATH,
['vbox86'])
vbox = self.xml.get_object('vbox86')
self.child.pack_start(vbox)
self.import_from_combo = self.xml.get_object('import_from')
self.import_to_combo = self.xml.get_object('import_to')
def on_run(self):
self.fill_treeview()
#Prepare comboboxes
self.print_status_combobox = self.xml.get_object('print_status_combobox')
model = gtk.ListStore(str, str)
self.option_list = {'': _('Default'), 'all': Q_('?print_status:All'),
'in_and_out': _('Enter and leave only'),
'none': Q_('?print_status:None')}
opts = sorted(self.option_list.keys())
for opt in opts:
model.append([self.option_list[opt], opt])
self.print_status_combobox.set_model(model)
self.print_status_combobox.set_active(1)
#Prepare import_from combobox
model = gtk.ListStore(str)
for account in self.accounts:
model.append([account,])
for account_jid in self.plugin.config:
if account_jid not in self.plugin.config_default_values and \
account_jid not in self.jids:
model.append([account_jid,])
self.import_from_combo.set_model(model)
#Prepare import_to combobox
model = gtk.ListStore(str)
for account in self.accounts:
model.append([account,])
self.import_to_combo.set_model(model)
self.selection = self.view.get_selection()
self.selection.connect('changed', self.bookmark_selected)
#Prepare input fields
self.title_entry = self.xml.get_object('title_entry')
self.title_entry.connect('changed', self.on_title_entry_changed)
self.nick_entry = self.xml.get_object('nick_entry')
self.nick_entry.connect('changed', self.on_nick_entry_changed)
self.server_entry = self.xml.get_object('server_entry')
self.server_entry.connect('changed', self.on_server_entry_changed)
self.room_entry = self.xml.get_object('room_entry')
self.room_entry.connect('changed', self.on_room_entry_changed)
self.pass_entry = self.xml.get_object('pass_entry')
self.pass_entry.connect('changed', self.on_pass_entry_changed)
self.autojoin_checkbutton = self.xml.get_object('autojoin_checkbutton')
self.minimize_checkbutton = self.xml.get_object('minimize_checkbutton')
self.xml.connect_signals(self)
self.connect('hide', self.on_hide)
self.show_all()
self.view.set_cursor((0,))
def fill_treeview(self):
# Account-JID, RoomName, Room-JID, Autojoin, Minimize, Passowrd, Nick,
# Show_Status
self.treestore = gtk.TreeStore(str, str, str, bool, bool, str, str, str)
self.treestore.set_sort_column_id(1, gtk.SORT_ASCENDING)
self.accounts = []
self.jids = []
# Store bookmarks in treeview.
for account in gajim.connections:
if gajim.connections[account].connected <= 1:
continue
if gajim.connections[account].is_zeroconf:
continue
self.accounts.append(account)
self.jids.append(gajim.get_jid_from_account(account))
iter_ = self.treestore.append(None, [None, account, None, None,
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
from common import helpers
# make '1', '0', 'true', 'false' (or other) to True/False
autojoin = helpers.from_xs_boolean_to_python_boolean(
bookmark['autojoin'])
minimize = helpers.from_xs_boolean_to_python_boolean(
bookmark['minimize'])
print_status = bookmark.get('print_status', '')
if print_status not in ('', 'all', 'in_and_out', 'none'):
print_status = ''
self.treestore.append(iter_, [
account,
bookmark['name'],
bookmark['jid'],
autojoin,
minimize,
bookmark['password'],
bookmark['nick'],
print_status ])
self.view = self.xml.get_object('bookmarks_treeview')
self.view.set_model(self.treestore)
self.view.expand_all()
renderer = gtk.CellRendererText()
column = gtk.TreeViewColumn('Bookmarks', renderer, text=1)
if self.view.get_column(0):
self.view.remove_column(self.view.get_column(0))
self.view.append_column(column)
def on_hide(self, widget):
"""
Parse the treestore data into our new bookmarks array, then send the new
bookmarks to the server.
"""
(model, iter_) = self.selection.get_selected()
if iter_ and model.iter_parent(iter_):
#bookmark selected, check it
if not self.check_valid_bookmark():
return
for account in self.treestore:
account_unicode = account[1].decode('utf-8')
gajim.connections[account_unicode].bookmarks = []
for bm in account.iterchildren():
# Convert True/False/None to '1' or '0'
autojoin = unicode(int(bm[3]))
minimize = unicode(int(bm[4]))
name = bm[1]
if name:
name = name.decode('utf-8')
jid = bm[2]
if jid:
jid = jid.decode('utf-8')
pw = bm[5]
if pw:
pw = pw.decode('utf-8')
nick = bm[6]
if nick:
nick = nick.decode('utf-8')
# create the bookmark-dict
bmdict = { 'name': name, 'jid': jid, 'autojoin': autojoin,
'minimize': minimize, 'password': pw, 'nick': nick,
'print_status': bm[7]}
gajim.connections[account_unicode].bookmarks.append(bmdict)
bookmarks_supported = self.plugin.is_bookmark_supported(
gajim.connections[account_unicode])
if bookmarks_supported:
gajim.connections[account_unicode].store_bookmarks()
self.plugin.save_bookmarks(account_unicode,
gajim.connections[account_unicode].bookmarks)
gajim.interface.roster.set_actions_menu_needs_rebuild()
def on_import_to_changed(self, treeview):
self.on_import_from_changed(self.import_from_combo)
def on_import_from_changed(self, widget):
if widget.get_active() == -1 or self.import_to_combo.get_active() == -1:
self.xml.get_object('import_button').set_sensitive(False)
else:
if widget.get_active_text() != self.import_to_combo.get_active_text():
self.xml.get_object('import_button').set_sensitive(True)
else:
self.xml.get_object('import_button').set_sensitive(False)
def on_import_button_clicked(self, widget):
from_ = self.import_from_combo.get_active_text()
to_connection = gajim.connections[self.import_to_combo.get_active_text()]
to_bookmarks = to_connection.bookmarks
if from_ in self.accounts:
from_bookmarks = gajim.connections[from_].bookmarks
else:
from_bookmarks = self.plugin.config[from_]
for bm in from_bookmarks:
for bookmark in to_bookmarks:
if bookmark['jid'] == bm['jid']:
break
else:
to_bookmarks.append(bm)
self.fill_treeview()
self.view.set_cursor((0,))
self.import_from_combo.set_active(-1)
self.import_to_combo.set_active(-1)
|