1 # -*- coding: utf-8 -*-
3 ## This file is part of Gajim.
5 ## Gajim is free software; you can redistribute it and/or modify
6 ## it under the terms of the GNU General Public License as published
7 ## by the Free Software Foundation; version 3 only.
9 ## Gajim is distributed in the hope that it will be useful,
10 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ## GNU General Public License for more details.
14 ## You should have received a copy of the GNU General Public License
15 ## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
19 GUI classes related to plug-in management.
21 :author: Mateusz Biliński <mateusz@bilinski.it>
23 :copyright: Copyright (2008) Mateusz Biliński <mateusz@bilinski.it>
27 __all__
= ['PluginsWindow']
33 from dialogs
import WarningDialog
, YesNoDialog
, ArchiveChooserDialog
34 from common
import gajim
35 from plugins
.helpers
import log_calls
, log
36 from plugins
.helpers
import GajimPluginActivateException
37 from common
.exceptions
import PluginsystemError
39 class PluginsWindow(object):
40 '''Class for Plugins window'''
42 @log_calls('PluginsWindow')
44 '''Initialize Plugins window'''
45 self
.xml
= gtkgui_helpers
.get_gtk_builder('plugins_window.ui')
46 self
.window
= self
.xml
.get_object('plugins_window')
47 self
.window
.set_transient_for(gajim
.interface
.roster
.window
)
49 widgets_to_extract
= ('plugins_notebook', 'plugin_name_label',
50 'plugin_version_label', 'plugin_authors_label',
51 'plugin_homepage_linkbutton', 'plugin_description_textview',
52 'uninstall_plugin_button', 'configure_plugin_button',
53 'installed_plugins_treeview')
55 for widget_name
in widgets_to_extract
:
56 setattr(self
, widget_name
, self
.xml
.get_object(widget_name
))
58 attr_list
= pango
.AttrList()
59 attr_list
.insert(pango
.AttrWeight(pango
.WEIGHT_BOLD
, 0, -1))
60 self
.plugin_name_label
.set_attributes(attr_list
)
62 self
.installed_plugins_model
= gtk
.ListStore(gobject
.TYPE_PYOBJECT
,
63 gobject
.TYPE_STRING
, gobject
.TYPE_BOOLEAN
)
64 self
.installed_plugins_treeview
.set_model(self
.installed_plugins_model
)
66 renderer
= gtk
.CellRendererText()
67 col
= gtk
.TreeViewColumn(_('Plugin'), renderer
, text
=1)
68 self
.installed_plugins_treeview
.append_column(col
)
70 renderer
= gtk
.CellRendererToggle()
71 renderer
.set_property('activatable', True)
72 renderer
.connect('toggled', self
.installed_plugins_toggled_cb
)
73 col
= gtk
.TreeViewColumn(_('Active'), renderer
, active
=2)
74 self
.installed_plugins_treeview
.append_column(col
)
76 # connect signal for selection change
77 selection
= self
.installed_plugins_treeview
.get_selection()
78 selection
.connect('changed',
79 self
.installed_plugins_treeview_selection_changed
)
80 selection
.set_mode(gtk
.SELECTION_SINGLE
)
82 self
._clear
_installed
_plugin
_info
()
84 self
.fill_installed_plugins_model()
86 self
.xml
.connect_signals(self
)
88 self
.plugins_notebook
.set_current_page(0)
90 self
.window
.show_all()
91 gtkgui_helpers
.possibly_move_window_in_current_desktop(self
.window
)
93 @log_calls('PluginsWindow')
94 def installed_plugins_treeview_selection_changed(self
, treeview_selection
):
95 model
, iter = treeview_selection
.get_selected()
97 plugin
= model
.get_value(iter, 0)
98 plugin_name
= model
.get_value(iter, 1)
99 is_active
= model
.get_value(iter, 2)
101 self
._display
_installed
_plugin
_info
(plugin
)
103 self
._clear
_installed
_plugin
_info
()
105 def _display_installed_plugin_info(self
, plugin
):
106 self
.plugin_name_label
.set_text(plugin
.name
)
107 self
.plugin_version_label
.set_text(plugin
.version
)
108 self
.plugin_authors_label
.set_text(plugin
.authors
)
109 label
= self
.plugin_homepage_linkbutton
.get_children()[0]
110 label
.set_ellipsize(pango
.ELLIPSIZE_END
)
111 self
.plugin_homepage_linkbutton
.set_uri(plugin
.homepage
)
112 self
.plugin_homepage_linkbutton
.set_label(plugin
.homepage
)
113 self
.plugin_homepage_linkbutton
.set_property('sensitive', True)
115 desc_textbuffer
= self
.plugin_description_textview
.get_buffer()
116 desc_textbuffer
.set_text(plugin
.description
)
117 self
.plugin_description_textview
.set_property('sensitive', True)
118 self
.uninstall_plugin_button
.set_property('sensitive',
119 gajim
.PLUGINS_DIRS
[1] in plugin
.__path
__)
120 if plugin
.config_dialog
is None:
121 self
.configure_plugin_button
.set_property('sensitive', False)
123 self
.configure_plugin_button
.set_property('sensitive', True)
125 def _clear_installed_plugin_info(self
):
126 self
.plugin_name_label
.set_text('')
127 self
.plugin_version_label
.set_text('')
128 self
.plugin_authors_label
.set_text('')
129 self
.plugin_homepage_linkbutton
.set_uri('')
130 self
.plugin_homepage_linkbutton
.set_label('')
131 self
.plugin_homepage_linkbutton
.set_property('sensitive', False)
133 desc_textbuffer
= self
.plugin_description_textview
.get_buffer()
134 desc_textbuffer
.set_text('')
135 self
.plugin_description_textview
.set_property('sensitive', False)
136 self
.uninstall_plugin_button
.set_property('sensitive', False)
137 self
.configure_plugin_button
.set_property('sensitive', False)
139 @log_calls('PluginsWindow')
140 def fill_installed_plugins_model(self
):
141 pm
= gajim
.plugin_manager
142 self
.installed_plugins_model
.clear()
143 self
.installed_plugins_model
.set_sort_column_id(1, gtk
.SORT_ASCENDING
)
145 for plugin
in pm
.plugins
:
146 self
.installed_plugins_model
.append([plugin
, plugin
.name
,
149 @log_calls('PluginsWindow')
150 def installed_plugins_toggled_cb(self
, cell
, path
):
151 is_active
= self
.installed_plugins_model
[path
][2]
152 plugin
= self
.installed_plugins_model
[path
][0]
155 gajim
.plugin_manager
.deactivate_plugin(plugin
)
158 gajim
.plugin_manager
.activate_plugin(plugin
)
159 except GajimPluginActivateException
, e
:
160 WarningDialog(_('Plugin failed'), str(e
))
163 self
.installed_plugins_model
[path
][2] = not is_active
165 @log_calls('PluginsWindow')
166 def on_plugins_window_destroy(self
, widget
):
168 del gajim
.interface
.instances
['plugins']
170 @log_calls('PluginsWindow')
171 def on_close_button_clicked(self
, widget
):
172 self
.window
.destroy()
174 @log_calls('PluginsWindow')
175 def on_configure_plugin_button_clicked(self
, widget
):
176 #log.debug('widget: %s'%(widget))
177 selection
= self
.installed_plugins_treeview
.get_selection()
178 model
, iter = selection
.get_selected()
180 plugin
= model
.get_value(iter, 0)
181 plugin_name
= model
.get_value(iter, 1)
182 is_active
= model
.get_value(iter, 2)
185 result
= plugin
.config_dialog
.run(self
.window
)
188 # No plugin selected. this should never be reached. As configure
189 # plugin button should only be clickable when plugin is selected.
190 # XXX: maybe throw exception here?
193 @log_calls('PluginsWindow')
194 def on_uninstall_plugin_button_clicked(self
, widget
):
195 selection
= self
.installed_plugins_treeview
.get_selection()
196 model
, iter = selection
.get_selected()
198 plugin
= model
.get_value(iter, 0)
199 plugin_name
= model
.get_value(iter, 1).decode('utf-8')
200 is_active
= model
.get_value(iter, 2)
202 gajim
.plugin_manager
.remove_plugin(plugin
)
203 except PluginsystemError
, e
:
204 WarningDialog(_('Unable to properly remove the plugin'),
209 @log_calls('PluginsWindow')
210 def on_install_plugin_button_clicked(self
, widget
):
211 def show_warn_dialog():
212 text
= _('Archive is malformed')
213 dialog
= WarningDialog(text
, '', transient_for
=self
.window
)
214 dialog
.set_modal(False)
217 def _on_plugin_exists(zip_filename
):
218 def on_yes(is_checked
):
219 plugin
= gajim
.plugin_manager
.install_from_zip(zip_filename
,
224 model
= self
.installed_plugins_model
226 for row
in xrange(len(model
)):
227 if plugin
== model
[row
][0]:
228 model
.remove(model
.get_iter((row
, 0)))
231 iter_
= model
.append([plugin
, plugin
.name
, False])
232 sel
= self
.installed_plugins_treeview
.get_selection()
233 sel
.select_iter(iter_
)
235 YesNoDialog(_('Plugin already exists'), sectext
=_('Overwrite?'),
236 on_response_yes
=on_yes
)
238 def _try_install(zip_filename
):
240 plugin
= gajim
.plugin_manager
.install_from_zip(zip_filename
)
241 except PluginsystemError
, er_type
:
242 error_text
= str(er_type
)
243 if error_text
== _('Plugin already exists'):
244 _on_plugin_exists(zip_filename
)
247 WarningDialog(error_text
, '"%s"' % zip_filename
, self
.window
)
252 model
= self
.installed_plugins_model
253 iter_
= model
.append([plugin
, plugin
.name
, False])
254 sel
= self
.installed_plugins_treeview
.get_selection()
255 sel
.select_iter(iter_
)
257 self
.dialog
= ArchiveChooserDialog(on_response_ok
=_try_install
)
260 class GajimPluginConfigDialog(gtk
.Dialog
):
262 @log_calls('GajimPluginConfigDialog')
263 def __init__(self
, plugin
, **kwargs
):
264 gtk
.Dialog
.__init
__(self
, '%s %s'%(plugin
.name
, _('Configuration')),
267 self
.add_button('gtk-close', gtk
.RESPONSE_CLOSE
)
269 self
.child
.set_spacing(3)
273 @log_calls('GajimPluginConfigDialog')
274 def run(self
, parent
=None):
275 self
.set_transient_for(parent
)
278 result
= super(GajimPluginConfigDialog
, self
).run()