Newer
Older
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
# -*- coding: utf-8 -*-
##
from gi.repository import Gtk
from gi.repository import GdkPixbuf
from gi.repository import Pango
from gi.repository import GObject
import io
import configparser
import os
import zipfile
import tempfile
from shutil import rmtree
import sys
import imp
from common import gajim
from plugins import GajimPlugin
from plugins.helpers import log_calls
from htmltextview import HtmlTextView
from conversation_textview import ConversationTextview
from dialogs import WarningDialog, HigDialog
(
C_PIXBUF,
C_NAME,
C_DESCRIPTION,
C_AUTHORS,
C_CONVERTER,
C_HOMEPAGE,
C_UPGRADE) = range(7)
class EmoticonsPackPlugin(GajimPlugin):
@log_calls('EmoticonsPackPlugin')
def init(self):
self.description = _('Install, update and view detailed legend '
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
self.config_dialog = None # EmoticonsPackPluginConfigDialog(self)
self.window = None
self.model = None
self.connected_ids = {}
self.tmp_dir = ''
@log_calls('EmoticonsPackPlugin')
def activate(self):
self.pl_menuitem = gajim.interface.roster.xml.get_object(
'plugins_menuitem')
self.id_ = self.pl_menuitem.connect_after('activate', self.on_activate)
if 'plugins' in gajim.interface.instances:
self.on_activate(None)
@log_calls('EmoticonsPackPlugin')
def deactivate(self):
self.pl_menuitem.disconnect(self.id_)
if hasattr(self, 'page_num'):
self.notebook.remove_page(self.notebook.page_num(self.hpaned))
self.notebook.set_current_page(0)
for id_, widget in list(self.connected_ids.items()):
widget.disconnect(id_)
del self.page_num
def on_activate(self, widget):
if 'plugins' not in gajim.interface.instances:
return
if hasattr(self, 'page_num'):
# 'Available' tab exists
return
self.installed_plugins_model = gajim.interface.instances[
'plugins'].installed_plugins_model
self.notebook = gajim.interface.instances['plugins'].plugins_notebook
id_ = self.notebook.connect(
'switch-page', self.on_notebook_switch_page)
self.connected_ids[id_] = self.notebook
self.window = gajim.interface.instances['plugins'].window
id_ = self.window.connect('destroy', self.on_win_destroy)
self.connected_ids[id_] = self.window
self.Gtk_BUILDER_FILE_PATH = self.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, ['hpaned2'])
self.hpaned = self.xml.get_object('hpaned2')
self.page_num = self.notebook.append_page(self.hpaned, Gtk.Label(_(
'Emoticons')))
widgets_to_extract = (
'set_name', 'available_treeview', 'homepage_linkbutton',
'inslall_upgrade_button', 'authors_label', 'converter_label',)
for widget_name in widgets_to_extract:
setattr(self, widget_name, self.xml.get_object(widget_name))
self.model = Gtk.ListStore(
GdkPixbuf.Pixbuf, GObject.TYPE_STRING,
GObject.TYPE_STRING, GObject.TYPE_STRING,
GObject.TYPE_STRING, GObject.TYPE_STRING, GObject.TYPE_BOOLEAN)
self.available_treeview.set_model(self.model)
self.available_treeview.set_rules_hint(True)
self.model.set_sort_column_id(1, Gtk.SortType.ASCENDING)
#self.progressbar.set_property('no-show-all', True)
renderer = Gtk.CellRendererText()
col = Gtk.TreeViewColumn(_('Name'))
cell = Gtk.CellRendererPixbuf()
col.pack_start(cell, False)
col.add_attribute(cell, 'pixbuf', C_PIXBUF)
col.pack_start(renderer, True)
col.add_attribute(renderer, 'text', C_NAME)
col.set_property('expand', True)
col.set_sizing(Gtk.TreeViewColumnSizing.GROW_ONLY)
self.available_treeview.append_column(col)
renderer = Gtk.CellRendererToggle()
renderer.set_property('activatable', True)
renderer.connect('toggled', self.available_emoticons_toggled_cb)
col = Gtk.TreeViewColumn(
_('Install /\nUpgrade'), renderer, active=C_UPGRADE)
col.set_property('expand', False)
col.set_resizable(False)
self.available_treeview.append_column(col)
selection = self.available_treeview.get_selection()
selection.connect('changed', self.emoticons_treeview_selection_changed)
selection.set_mode(Gtk.SelectionMode.SINGLE)
self.emoticons_description_textview = ConversationTextview(None)
sw.add(self.emoticons_description_textview.tv)
self.xml.connect_signals(self)
self.window.show_all()
def on_legend_button_clicked(self, widget):
self.xml.get_object('scrolledwindow1').get_children()[0].destroy()
treeview_selection = self.available_treeview.get_selection()
model, iter = treeview_selection.get_selected()
name = model.get_value(iter, C_NAME)
label = self.xml.get_object('label2')
if label.get_text() == _('Legend'):
label.set_text(_('Description'))
sys.path.append(os.path.join(self.tmp_dir, name))
import emoticons
imp.reload(emoticons)
self.emoticons_description_textview = Gtk.TextView()
sw.add(self.emoticons_description_textview)
buff = self.emoticons_description_textview.get_buffer()
for icon in emoticons.emoticons:
icon_file = os.path.join(self.tmp_dir, name, icon)
with open(icon_file, 'rb') as _file:
data = _file.read()
pbl = GdkPixbuf.PixbufLoader()
pbl.write(data)
pbl.close()
if icon.endswith('.gif'):
img = Gtk.Image()
img.set_from_animation(pbl.get_animation())
img.show()
anchor = buff.create_child_anchor(buff.get_end_iter())
self.emoticons_description_textview.add_child_at_anchor(
img, anchor)
else:
buff.insert_pixbuf(buff.get_end_iter(), pbl.get_pixbuf())
text = ' , '.join(emoticons.emoticons[icon])
buff.insert(buff.get_end_iter(), text + '\n', -1)
self.emoticons_description_textview.set_property('sensitive', True)
sys.path.remove(os.path.join(self.tmp_dir, name))
else:
self.emoticons_description_textview = ConversationTextview(None)
sw.add(self.emoticons_description_textview.tv)
desc = _(model.get_value(iter, C_DESCRIPTION))
if not desc.startswith('<body '):
desc = '<body xmlns=\'http://www.w3.org/1999/xhtml\'>' + \
desc + ' </body>'
desc = desc.replace('preview.image', ('file:' + os.path.join(
self.tmp_dir, name, 'preview.png'))).replace('\n', '<br/>')
self.emoticons_description_textview.tv.display_html(
desc, self.emoticons_description_textview)
self.emoticons_description_textview.tv.set_property(
'sensitive', True)
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
def on_inslall_upgrade_clicked(self, widget):
self.inslall_upgrade_button.set_property('sensitive', False)
self.errors = ''
def on_error(func, path, error):
if func == os.path.islink:
# if symlink
os.unlink(path)
return
# access is denied or other
# WarningDialog(_('Can\'t remove dir'), error[1], self.window)
self.errors += str(error[1])
name_list = []
for i in range(len(self.model)):
if self.model[i][C_UPGRADE]:
name_list.append(self.model[i][C_NAME])
for name in name_list:
# remove dirs
target_dir = os.path.join(gajim.MY_EMOTS_PATH, name)
if os.path.isdir(target_dir):
rmtree(target_dir, False, on_error)
# unzip new files
zip_file = os.path.join(self.__path__, 'emoticons_pack.zip')
with zipfile.ZipFile(zip_file, 'r') as myzip:
namelist = myzip.namelist()
for n in namelist:
if not n.startswith(name):
continue
try:
icon_file = myzip.extract(n, path=gajim.MY_EMOTS_PATH)
except Exception as e:
self.errors += str(e)
# unset all checkbattons
for i in range(len(self.model)):
self.model[i][C_UPGRADE] = False
if self.errors:
WarningDialog(
_('Not fully installed'),
'Access is denied or other', self.window)
else:
# show dialog
dialog = HigDialog(
None, Gtk.MessageType.INFO, Gtk.ButtonsType.OK, '',
_('All selected emoticons installed(upgraded)'))
dialog.set_modal(False)
dialog.set_transient_for(self.window)
dialog.popup()
def on_win_destroy(self, widget):
if hasattr(self, 'page_num'):
del self.page_num
def available_emoticons_toggled_cb(self, cell, path):
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
is_active = self.model[path][C_UPGRADE]
self.model[path][C_UPGRADE] = not is_active
dir_list = []
for i in range(len(self.model)):
if self.model[i][C_UPGRADE]:
dir_list.append(self.model[i][C_NAME])
if not dir_list:
self.inslall_upgrade_button.set_property('sensitive', False)
else:
self.inslall_upgrade_button.set_property('sensitive', True)
def on_notebook_switch_page(self, widget, page, page_num):
tab_label_text = self.notebook.get_tab_label_text(self.hpaned)
if tab_label_text != (_('Emoticons')):
return
self.model.clear()
self.fill_table()
self.select_root_iter()
def fill_table(self):
conf = configparser.ConfigParser()
# read metadata from contents.ini
contents_path = os.path.join(self.__path__, 'contents.ini')
with open(contents_path) as _file:
conf.read_file(_file)
for section in conf.sections():
# get icon
filename = conf.get(section, 'icon')
filename = os.path.join(section, filename)
zip_file = os.path.join(self.__path__, 'emoticons_pack.zip')
with zipfile.ZipFile(zip_file, 'r') as myzip:
icon_file = myzip.open(filename, mode='r')
data = icon_file.read()
pbl = GdkPixbuf.PixbufLoader()
pbl.set_size(16, 16)
pbl.write(data)
pbl.close()
icon = pbl.get_pixbuf()
self.model.append(
[icon, section,
conf.get(section, 'description'),
conf.get(section, 'authors', fallback=_('Unknown')),
conf.get(section, 'converter', fallback=_('Unknown')),
conf.get(section, 'homepage'), False])
conf.remove_section(section)
def emoticons_treeview_selection_changed(self, treeview_selection):
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
model, iter = treeview_selection.get_selected()
label = self.xml.get_object('label2')
label.set_text(_('Legend'))
if iter:
set_name = model.get_value(iter, C_NAME)
if os.path.isdir(self.tmp_dir):
rmtree(self.tmp_dir, True)
self.tmp_dir = tempfile.mkdtemp()
# unzip new files
zip_file = os.path.join(self.__path__, 'emoticons_pack.zip')
with zipfile.ZipFile(zip_file, 'r') as myzip:
namelist = myzip.namelist()
for n in namelist:
if not n.startswith(set_name):
continue
myzip.extract(n, path=self.tmp_dir)
self.set_name.set_text(set_name)
self.authors_label.set_text(model.get_value(iter, C_AUTHORS))
self.converter_label.set_text(model.get_value(iter, C_CONVERTER))
self.homepage_linkbutton.set_uri(
model.get_value(iter, C_HOMEPAGE))
self.homepage_linkbutton.set_label(
model.get_value(iter, C_HOMEPAGE))
label = self.homepage_linkbutton.get_children()[0]
label.set_ellipsize(Pango.EllipsizeMode.END)
self.homepage_linkbutton.set_property('sensitive', True)
self.xml.get_object('scrolledwindow1').get_children()[0].destroy()
self.emoticons_description_textview = ConversationTextview(None)
sw.add(self.emoticons_description_textview.tv)
sw.show_all()
desc = _(model.get_value(iter, C_DESCRIPTION))
if not desc.startswith('<body '):
desc = '<body xmlns=\'http://www.w3.org/1999/xhtml\'>' + \
desc + ' </body>'
else:
desc = desc.replace('preview.image', ('file:' + os.path.join(
self.tmp_dir, set_name, 'preview.png')))
self.emoticons_description_textview.tv.display_html(
desc, self.emoticons_description_textview)
self.emoticons_description_textview.tv.set_property(
'sensitive', True)
self.set_name.set_text('')
self.authors_label.set_text('')
self.homepage_linkbutton.set_uri('')
self.homepage_linkbutton.set_label('')
self.homepage_linkbutton.set_property('sensitive', False)
def select_root_iter(self):
if hasattr(self, 'page_num'):
selection = self.available_treeview.get_selection()
if selection.count_selected_rows() == 0:
root_iter = self.model.get_iter_first()
selection.select_iter(root_iter)
scr_win = self.xml.get_object('scrolledwindow2')
vadjustment = scr_win.get_vadjustment()
if vadjustment:
vadjustment.set_value(0)
#GObject.idle_add(self.available_treeview.grab_focus)