Welcome to mirror list, hosted at ThFree Co, Russian Federation.

dev.gajim.org/gajim/gajim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYann Leboulanger <asterix@lagaule.org>2011-11-17 00:26:36 +0400
committerYann Leboulanger <asterix@lagaule.org>2011-11-17 00:26:36 +0400
commit6ad3d01fb5684426e9bd243c78849bc7e8219b94 (patch)
treef05b4adca35b2e78b414dd64a44b967d935cb3df /plugins
parent87504e39547d238c9f74e96564c258146359d114 (diff)
remove plugins that have been move to gajim-plugins reprository
Diffstat (limited to 'plugins')
-rw-r--r--plugins/Makefile.am17
-rw-r--r--plugins/banner_tweaks/__init__.py2
-rw-r--r--plugins/banner_tweaks/config_dialog.ui75
-rw-r--r--plugins/banner_tweaks/manifest.ini10
-rw-r--r--plugins/banner_tweaks/plugin.py194
-rw-r--r--plugins/google_translation/__init__.py1
-rw-r--r--plugins/google_translation/manifest.ini8
-rw-r--r--plugins/google_translation/plugin.py284
-rw-r--r--plugins/length_notifier/__init__.py2
-rw-r--r--plugins/length_notifier/config_dialog.ui152
-rw-r--r--plugins/length_notifier/length_notifier.py157
-rw-r--r--plugins/length_notifier/manifest.ini9
-rw-r--r--plugins/plugin_installer/__init__.py1
-rw-r--r--plugins/plugin_installer/config_dialog.ui294
-rw-r--r--plugins/plugin_installer/manifest.ini8
-rw-r--r--plugins/plugin_installer/plugin_installer.py532
-rw-r--r--plugins/triggers/__init__.py1
-rw-r--r--plugins/triggers/config_dialog.ui910
-rw-r--r--plugins/triggers/manifest.ini7
-rw-r--r--plugins/triggers/triggers.py677
-rw-r--r--plugins/whiteboard/__init__.py1
-rw-r--r--plugins/whiteboard/brush_tool.pngbin806 -> 0 bytes
-rw-r--r--plugins/whiteboard/line_tool.pngbin1054 -> 0 bytes
-rw-r--r--plugins/whiteboard/manifest.ini7
-rw-r--r--plugins/whiteboard/oval_tool.pngbin989 -> 0 bytes
-rw-r--r--plugins/whiteboard/plugin.py483
-rw-r--r--plugins/whiteboard/whiteboard.pngbin1550 -> 0 bytes
-rw-r--r--plugins/whiteboard/whiteboard_widget.py418
-rw-r--r--plugins/whiteboard/whiteboard_widget.ui192
29 files changed, 0 insertions, 4442 deletions
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
deleted file mode 100644
index 5ecf73578..000000000
--- a/plugins/Makefile.am
+++ /dev/null
@@ -1,17 +0,0 @@
-INCLUDES = \
- $(PYTHON_INCLUDES)
-
-gajimpluginsdir = $(gajim_pluginsdir)
-
-installedplugins = acronyms_expander banner_tweaks length_notifier plugin_installer triggers whiteboard
-
-installedpluginsfiles = $(wildcard ${srcdir}/${p}/*.py ${srcdir}/${p}/manifest.ini ${srcdir}/${p}/*.ui ${srcdir}/${p}/*.png)
-
-nobase_dist_gajimplugins_PYTHON = $(foreach p, ${installedplugins}, $(installedpluginsfiles))
-
-EXTRA_DIST = \
- $(srcdir)/*/*.py \
- $(srcdir)/*/manifest.ini \
- $(srcdir)/*/*.ui
-
-MAINTAINERCLEANFILES = Makefile.in
diff --git a/plugins/banner_tweaks/__init__.py b/plugins/banner_tweaks/__init__.py
deleted file mode 100644
index a328f68ee..000000000
--- a/plugins/banner_tweaks/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-
-from plugin import BannerTweaksPlugin
diff --git a/plugins/banner_tweaks/config_dialog.ui b/plugins/banner_tweaks/config_dialog.ui
deleted file mode 100644
index 1994c1c9d..000000000
--- a/plugins/banner_tweaks/config_dialog.ui
+++ /dev/null
@@ -1,75 +0,0 @@
-<?xml version="1.0"?>
-<interface>
- <requires lib="gtk+" version="2.16"/>
- <!-- interface-naming-policy toplevel-contextual -->
- <object class="GtkWindow" id="window1">
- <child>
- <object class="GtkVBox" id="banner_tweaks_config_vbox">
- <property name="visible">True</property>
- <property name="border_width">9</property>
- <property name="orientation">vertical</property>
- <property name="spacing">4</property>
- <child>
- <object class="GtkCheckButton" id="show_banner_image_checkbutton">
- <property name="label" translatable="yes">Display status icon</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="tooltip_text" translatable="yes">If checked, status icon will be displayed in chat window banner.</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_show_banner_image_checkbutton_toggled"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="show_banner_online_msg_checkbutton">
- <property name="label" translatable="yes">Display status message of contact</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="tooltip_text" translatable="yes">If checked, status message of contact will be displayed in chat window banner.</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_show_banner_online_msg_checkbutton_toggled"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="show_banner_resource_checkbutton">
- <property name="label" translatable="yes">Display resource name of contact</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="tooltip_text" translatable="yes">If checked, resource name of contact will be displayed in chat window banner.</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_show_banner_resource_checkbutton_toggled"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="banner_small_fonts_checkbutton">
- <property name="label" translatable="yes">Use small fonts for contact name and resource name</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="tooltip_text" translatable="yes">If checked, smaller font will be used to display resource name and contact name in chat window banner.</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_banner_small_fonts_checkbutton_toggled"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">3</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
-</interface>
diff --git a/plugins/banner_tweaks/manifest.ini b/plugins/banner_tweaks/manifest.ini
deleted file mode 100644
index 4cc3652f7..000000000
--- a/plugins/banner_tweaks/manifest.ini
+++ /dev/null
@@ -1,10 +0,0 @@
-[info]
-name: Banner Tweaks
-short_name: banner_tweaks
-version: 0.1
-description: Allows user to tweak chat window banner appearance (eg. make it compact).
- Based on patch by pb in ticket #4133:
- http://trac.gajim.org/attachment/ticket/4133.
-authors = Mateusz Biliński <mateusz@bilinski.it>
-homepage = http://blog.bilinski.it
-
diff --git a/plugins/banner_tweaks/plugin.py b/plugins/banner_tweaks/plugin.py
deleted file mode 100644
index 6439dd51b..000000000
--- a/plugins/banner_tweaks/plugin.py
+++ /dev/null
@@ -1,194 +0,0 @@
-# -*- coding: utf-8 -*-
-
-## This file is part of Gajim.
-##
-## Gajim is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published
-## by the Free Software Foundation; version 3 only.
-##
-## Gajim is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
-##
-
-'''
-Adjustable chat window banner.
-
-Includes tweaks to make it compact.
-
-Based on patch by pb in ticket #4133:
-http://trac.gajim.org/attachment/ticket/4133/gajim-chatbanneroptions-svn10008.patch
-
-:author: Mateusz Biliński <mateusz@bilinski.it>
-:since: 30 July 2008
-:copyright: Copyright (2008) Mateusz Biliński <mateusz@bilinski.it>
-:license: GPL
-'''
-
-import sys
-
-import gtk
-import gobject
-import message_control
-from common import gajim
-from common import helpers
-
-from plugins import GajimPlugin
-from plugins.helpers import log, log_calls
-from plugins.gui import GajimPluginConfigDialog
-
-class BannerTweaksPlugin(GajimPlugin):
-
- @log_calls('BannerTweaksPlugin')
- def init(self):
- self.description = _('Allows user to tweak chat window banner '
- 'appearance (eg. make it compact).\n'
- 'Based on patch by pb in ticket #4133:\n'
- 'http://trac.gajim.org/attachment/ticket/4133.')
- self.config_dialog = BannerTweaksPluginConfigDialog(self)
-
- self.gui_extension_points = {
- 'chat_control_base_draw_banner': (self.chat_control_base_draw_banner_called,
- self.chat_control_base_draw_banner_deactivation)
- }
-
- self.config_default_values = {
- 'show_banner_image': (True, 'If True, Gajim will display a status icon in the banner of chat windows.'),
- 'show_banner_online_msg': (True, 'If True, Gajim will display the status message of the contact in the banner of chat windows.'),
- 'show_banner_resource': (False, 'If True, Gajim will display the resource name of the contact in the banner of chat windows.'),
- 'banner_small_fonts': (False, 'If True, Gajim will use small fonts for contact name and resource name in the banner of chat windows.'),
- 'old_chat_avatar_height': (52, 'chat_avatar_height value before plugin was activated'),
- }
-
- @log_calls('BannerTweaksPlugin')
- def activate(self):
- self.config['old_chat_avatar_height'] = gajim.config.get('chat_avatar_height')
- #gajim.config.set('chat_avatar_height', 28)
-
- @log_calls('BannerTweaksPlugin')
- def deactivate(self):
- gajim.config.set('chat_avatar_height', self.config['old_chat_avatar_height'])
-
- @log_calls('BannerTweaksPlugin')
- def chat_control_base_draw_banner_called(self, chat_control):
- if not self.config['show_banner_online_msg']:
- chat_control.banner_status_label.hide()
- chat_control.banner_status_label.set_no_show_all(True)
- status_text = ''
- chat_control.banner_status_label.set_markup(status_text)
-
- if not self.config['show_banner_image']:
- if chat_control.TYPE_ID == message_control.TYPE_GC:
- banner_status_img = chat_control.xml.get_object(
- 'gc_banner_status_image')
- else:
- banner_status_img = chat_control.xml.get_object(
- 'banner_status_image')
- banner_status_img.clear()
-
- # TODO: part below repeats a lot of code from ChatControl.draw_banner_text()
- # This could be rewritten using re module: getting markup text from
- # banner_name_label and replacing some elements based on plugin config.
- # Would it be faster?
- if self.config['show_banner_resource'] or self.config['banner_small_fonts']:
- banner_name_label = chat_control.xml.get_object('banner_name_label')
- label_text = banner_name_label.get_label()
-
- contact = chat_control.contact
- jid = contact.jid
-
- name = contact.get_shown_name()
- if chat_control.resource:
- name += '/' + chat_control.resource
- elif contact.resource and self.config['show_banner_resource']:
- name += '/' + contact.resource
-
- if chat_control.TYPE_ID == message_control.TYPE_PM:
- name = _('%(nickname)s from group chat %(room_name)s') %\
- {'nickname': name, 'room_name': chat_control.room_name}
- name = gobject.markup_escape_text(name)
-
- # We know our contacts nick, but if another contact has the same nick
- # in another account we need to also display the account.
- # except if we are talking to two different resources of the same contact
- acct_info = ''
- for account in gajim.contacts.get_accounts():
- if account == chat_control.account:
- continue
- if acct_info: # We already found a contact with same nick
- break
- for jid in gajim.contacts.get_jid_list(account):
- other_contact_ = \
- gajim.contacts.get_first_contact_from_jid(account, jid)
- if other_contact_.get_shown_name() == chat_control.contact.get_shown_name():
- acct_info = ' (%s)' % \
- gobject.markup_escape_text(chat_control.account)
- break
-
- font_attrs, font_attrs_small = chat_control.get_font_attrs()
- if self.config['banner_small_fonts']:
- font_attrs = font_attrs_small
-
- st = gajim.config.get('displayed_chat_state_notifications')
- cs = contact.chatstate
- if cs and st in ('composing_only', 'all'):
- if contact.show == 'offline':
- chatstate = ''
- elif st == 'all' or cs == 'composing':
- chatstate = helpers.get_uf_chatstate(cs)
- else:
- chatstate = ''
-
- label_text = '<span %s>%s</span><span %s>%s %s</span>' % \
- (font_attrs, name, font_attrs_small, acct_info, chatstate)
- else:
- # weight="heavy" size="x-large"
- label_text = '<span %s>%s</span><span %s>%s</span>' % \
- (font_attrs, name, font_attrs_small, acct_info)
-
- banner_name_label.set_markup(label_text)
-
- @log_calls('BannerTweaksPlugin')
- def chat_control_base_draw_banner_deactivation(self, chat_control):
- pass
- #chat_control.draw_banner()
-
-class BannerTweaksPluginConfigDialog(GajimPluginConfigDialog):
- 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,
- ['banner_tweaks_config_vbox'])
- self.config_vbox = self.xml.get_object('banner_tweaks_config_vbox')
- self.child.pack_start(self.config_vbox)
-
- self.show_banner_image_checkbutton = self.xml.get_object('show_banner_image_checkbutton')
- self.show_banner_online_msg_checkbutton = self.xml.get_object('show_banner_online_msg_checkbutton')
- self.show_banner_resource_checkbutton = self.xml.get_object('show_banner_resource_checkbutton')
- self.banner_small_fonts_checkbutton = self.xml.get_object('banner_small_fonts_checkbutton')
-
- self.xml.connect_signals(self)
-
- def on_run(self):
- self.show_banner_image_checkbutton.set_active(self.plugin.config['show_banner_image'])
- self.show_banner_online_msg_checkbutton.set_active(self.plugin.config['show_banner_online_msg'])
- self.show_banner_resource_checkbutton.set_active(self.plugin.config['show_banner_resource'])
- self.banner_small_fonts_checkbutton.set_active(self.plugin.config['banner_small_fonts'])
-
- def on_show_banner_image_checkbutton_toggled(self, button):
- self.plugin.config['show_banner_image'] = button.get_active()
-
- def on_show_banner_online_msg_checkbutton_toggled(self, button):
- self.plugin.config['show_banner_online_msg'] = button.get_active()
-
- def on_show_banner_resource_checkbutton_toggled(self, button):
- self.plugin.config['show_banner_resource'] = button.get_active()
-
- def on_banner_small_fonts_checkbutton_toggled(self, button):
- self.plugin.config['banner_small_fonts'] = button.get_active()
diff --git a/plugins/google_translation/__init__.py b/plugins/google_translation/__init__.py
deleted file mode 100644
index dc2c3bc36..000000000
--- a/plugins/google_translation/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from plugin import GoogleTranslationPlugin
diff --git a/plugins/google_translation/manifest.ini b/plugins/google_translation/manifest.ini
deleted file mode 100644
index 2ad728b7d..000000000
--- a/plugins/google_translation/manifest.ini
+++ /dev/null
@@ -1,8 +0,0 @@
-[info]
-name: Google Translation
-short_name: google_translation
-version: 0.2
-description: Translates (currently only incoming) messages using Google Translate.
-authors = Mateusz Biliński <mateusz@bilinski.it>
-homepage = http://blog.bilinski.it
-
diff --git a/plugins/google_translation/plugin.py b/plugins/google_translation/plugin.py
deleted file mode 100644
index 1aa5ed111..000000000
--- a/plugins/google_translation/plugin.py
+++ /dev/null
@@ -1,284 +0,0 @@
-# -*- coding: utf-8 -*-
-##
-## This file is part of Gajim.
-##
-## Gajim is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published
-## by the Free Software Foundation; version 3 only.
-##
-## Gajim is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
-##
-'''
-Google Translation plugin.
-
-Translates (currently only incoming) messages using Google Translate.
-
-:note: consider this as proof-of-concept
-:author: Mateusz Biliński <mateusz@bilinski.it>
-:since: 25th August 2008
-:copyright: Copyright (2008) Mateusz Biliński <mateusz@bilinski.it>
-:license: GPL
-'''
-
-import json
-import urllib2
-import HTMLParser
-import gtk
-from sys import getfilesystemencoding
-
-import chat_control
-import groupchat_control
-
-from common import helpers
-from common import gajim
-
-from plugins import GajimPlugin
-from plugins.helpers import log_calls, log
-from common import ged
-
-languages = {
- _('Afrikaans'): 'af',
- _('Albanian'): 'sq',
- _('Armenian'): 'hy',
- _('Azerbaijani'): 'az',
- _('Arabic'): 'ar',
- _('Basque'): 'eu',
- _('Belarusian'): 'be',
- _('Bulgarian'): 'bg',
- _('Catalan'): 'ca',
- _('Chinese (Simplified)'): 'zh-cn',
- _('Chinese (Traditional)'): 'zh-tw',
- _('Croatian'): 'hr',
- _('Czech'): 'cs',
- _('Danish'): 'da',
- _('Dutch'): 'nl',
- _('English'): 'en',
- _('Estonian'): 'et',
- _('Filipino'): 'tl',
- _('Finnish'): 'fi',
- _('French'): 'fr',
- _('Galician'): 'gl',
- _('Georgian'): 'ka',
- _('German'): 'de',
- _('Greek'): 'el',
- _('Haitian Creole'): 'ht',
- _('Hebrew'): 'iw',
- _('Hindi'): 'hi',
- _('Hungarian'): 'hu',
- _('Icelandic'): 'is',
- _('Indonesian'): 'id',
- _('Italian'): 'it',
- _('Irish'): 'da',
- _('Japanese'): 'ja',
- _('Korean'): 'ko',
- _('Latvian'): 'lv',
- _('Lithuanian'): 'lt',
- _('Macedonian'): 'mk',
- _('Malay'): 'ml',
- _('Maltese'): 'mt',
- _('Norwegian'): 'no',
- _('Persian'): 'fa',
- _('Polish'): 'pl',
- _('Portuguese'): 'pt-BR',
- _('Romanian'): 'ro',
- _('Russian'): 'ru',
- _('Serbian'): 'sr',
- _('Slovak'): 'sk',
- _('Slovenian'): 'sl',
- _('Spanish'): 'es',
- _('Swahili'): 'sw',
- _('Swedish'): 'sv',
- _('Thai'): 'th',
- _('Turkish'): 'tr',
- _('Ukrainian'): 'uk',
- _('Urdu'): 'ur',
- _('Vietnamese'): 'vi',
- _('Welsh'): 'cy',
- _('Yiddish'): 'yi',
-}
-
-class GoogleTranslationPlugin(GajimPlugin):
-
- @log_calls('GoogleTranslationPlugin')
- def init(self):
- self.description = _('Translates (currently only incoming)'
- 'messages using Google Translate.')
- self.config_dialog = None
-
- self.config_default_values = {
- 'per_jid_config': ({}, ''),
- }
-
- self.events_handlers = {'decrypted-message-received': (ged.PREGUI,
- self._nec_decrypted_message_received)}
-
- self.gui_extension_points = {
- 'chat_control_base' : (self.connect_with_control,
- self.disconnect_from_control),
- }
-
- self.controls = []
-
- @log_calls('GoogleTranslationPlugin')
- def translate_text(self, account, text, from_lang, to_lang):
- # Converts text so it can be used within URL as query to Google
- # Translate.
- quoted_text = urllib2.quote(text.encode(getfilesystemencoding()))
- # prepare url
- translation_url = u'https://ajax.googleapis.com/ajax/services/' \
- 'language/translate?q=%(quoted_text)s&' \
- 'langpair=%(from_lang)s%%7C%(to_lang)s&key=notsupplied&v=1.0' % \
- locals()
-
- results = helpers.download_image(account, {'src': translation_url})[0]
- if not results:
- return text
-
- result = json.loads(results)
-
- if result.get('responseStatus', '') != 200:
- return text
-
- translated_text = result['responseData'].get('translatedText', '')
- if translated_text:
- try:
- htmlparser = HTMLParser.HTMLParser()
- translated_text = htmlparser.unescape(translated_text)
- except Exception:
- pass
- return translated_text
- return text
-
- @log_calls('GoogleTranslationPlugin')
- def _nec_decrypted_message_received(self, obj):
- if not obj.msgtxt:
- return
- if obj.jid not in self.config['per_jid_config']:
- return
- if not self.config['per_jid_config'][obj.jid]['enabled']:
- return
- from_lang = self.config['per_jid_config'][obj.jid]['from']
- to_lang = self.config['per_jid_config'][obj.jid]['to']
- translated_text = self.translate_text(obj.conn.name, obj.msgtxt,
- from_lang, to_lang)
- if translated_text:
- obj.msgtxt = translated_text + '\n/' + _('Original text:') + '/ ' +\
- obj.msgtxt
-
- @log_calls('GoogleTranslationPlugin')
- def activate(self):
- pass
-
- @log_calls('GoogleTranslationPlugin')
- def deactivate(self):
- pass
-
- @log_calls('GoogleTranslationPlugin')
- def connect_with_control(self, control):
- base = Base(self, control)
- self.controls.append(base)
-
- @log_calls('GoogleTranslationPlugin')
- def disconnect_from_control(self, chat_control):
- for base in self.controls:
- base.disconnect_from_control()
- self.controls = []
-
-class Base(object):
- def __init__(self, plugin, control):
- self.plugin = plugin
- self.control = control
- self.contact = control.contact
- self.account = control.account
- self.jid = self.contact.jid
- if self.jid in self.plugin.config['per_jid_config']:
- self.config = self.plugin.config['per_jid_config'][self.jid]
- else:
- self.config = {'from': '', 'to': 'en', 'enabled': False}
- self.create_buttons()
-
- def create_buttons(self):
- if isinstance(self.control, chat_control.ChatControl):
- vbox = self.control.xml.get_object('vbox106')
- elif isinstance(self.control, groupchat_control.GroupchatControl):
- vbox = self.control.xml.get_object('gc_textviews_vbox')
- else:
- return
-
- self.expander = gtk.Expander(_('Google translation'))
- hbox = gtk.HBox(spacing=6)
- self.expander.add(hbox)
- label = gtk.Label(_('Translate from'))
- hbox.pack_start(label, False, False)
- liststore1 = gtk.ListStore(str, str)
- liststore2 = gtk.ListStore(str, str)
- cb1 = gtk.ComboBox(liststore1)
- cb2 = gtk.ComboBox(liststore2)
- cell = gtk.CellRendererText()
- cb1.pack_start(cell, True)
- cb1.add_attribute(cell, 'text', 0)
- cell = gtk.CellRendererText()
- cb2.pack_start(cell, True)
- cb2.add_attribute(cell, 'text', 0)
- #Language to translate from
- liststore1.append([_('Auto'), ''])
- if self.config['from'] == '':
- cb1.set_active(0)
- if self.config['from'] == '':
- cb1.set_active(0)
- i = 0
- ls = languages.items()
- ls.sort()
- for l in ls:
- liststore1.append(l)
- if l[1] == self.config['from']:
- cb1.set_active(i+1)
- liststore2.append(l)
- if l[1] == self.config['to']:
- cb2.set_active(i)
- i += 1
-
- hbox.pack_start(cb1, False, False)
- label = gtk.Label(_('to'))
- hbox.pack_start(label, False, False)
- hbox.pack_start(cb2, False, False)
-
- cb = gtk.CheckButton(_('enable'))
- if self.config['enabled']:
- cb.set_active(True)
- hbox.pack_start(cb, False, False)
- vbox.pack_start(self.expander, False, False)
- vbox.reorder_child(self.expander, 1)
-
- cb1.connect('changed', self.on_cb_changed, 'from')
- cb2.connect('changed', self.on_cb_changed, 'to')
- cb.connect('toggled', self.on_cb_toggled)
- self.expander.show_all()
-
- def on_cb_changed(self, widget, option):
- model = widget.get_model()
- it = widget.get_active_iter()
- self.config[option] = model[it][1]
- self.plugin.config['per_jid_config'][self.jid] = self.config
- self.plugin.config.save()
-
- def on_cb_toggled(self, widget):
- self.config['enabled'] = widget.get_active()
- self.plugin.config['per_jid_config'][self.jid] = self.config
- self.plugin.config.save()
-
- def disconnect_from_control(self):
- if isinstance(self.control, chat_control.ChatControl):
- vbox = self.control.xml.get_object('vbox106')
- elif isinstance(self.control, groupchat_control.GroupchatControl):
- vbox = self.control.xml.get_object('gc_textviews_vbox')
- else:
- return
-
- vbox.remove(self.expander)
diff --git a/plugins/length_notifier/__init__.py b/plugins/length_notifier/__init__.py
deleted file mode 100644
index 67c8c614a..000000000
--- a/plugins/length_notifier/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-
-from length_notifier import LengthNotifierPlugin
diff --git a/plugins/length_notifier/config_dialog.ui b/plugins/length_notifier/config_dialog.ui
deleted file mode 100644
index f06bfe115..000000000
--- a/plugins/length_notifier/config_dialog.ui
+++ /dev/null
@@ -1,152 +0,0 @@
-<?xml version="1.0"?>
-<interface>
- <requires lib="gtk+" version="2.16"/>
- <!-- interface-naming-policy toplevel-contextual -->
- <object class="GtkWindow" id="window1">
- <child>
- <object class="GtkTable" id="length_notifier_config_table">
- <property name="visible">True</property>
- <property name="border_width">9</property>
- <property name="n_rows">3</property>
- <property name="n_columns">2</property>
- <property name="column_spacing">7</property>
- <property name="row_spacing">5</property>
- <child>
- <object class="GtkLabel" id="label1">
- <property name="visible">True</property>
- <property name="tooltip_text" translatable="yes">Message length at which notification is invoked.</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Message length:</property>
- </object>
- <packing>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label2">
- <property name="visible">True</property>
- <property name="tooltip_text" translatable="yes">Background color of text entry field in chat window when notification is invoked.</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Notification color:</property>
- </object>
- <packing>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label3">
- <property name="visible">True</property>
- <property name="tooltip_text" translatable="yes">JabberIDs that plugin should be used with (eg. restrict only to one microblogging bot). Use comma (without space) as separator. If empty plugin is used with every JID. </property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">JabberIDs to include:</property>
- </object>
- <packing>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="jids_entry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="tooltip_text" translatable="yes">JabberIDs that plugin should be used with (eg. restrict only to one microblogging bot). Use comma (without space) as separator. If empty plugin is used with every JID. </property>
- <signal name="editing_done" handler="on_jids_entry_editing_done"/>
- <signal name="changed" handler="on_jids_entry_changed"/>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- <child>
- <object class="GtkHBox" id="hbox1">
- <property name="visible">True</property>
- <child>
- <object class="GtkColorButton" id="notification_colorbutton">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="tooltip_text" translatable="yes">Background color of text entry field in chat window when notification is invoked.</property>
- <property name="xalign">0</property>
- <property name="title" translatable="yes">Pick a color for notification</property>
- <property name="color">#000000000000</property>
- <signal name="color_set" handler="on_notification_colorbutton_color_set"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="alignment1">
- <property name="visible">True</property>
- <child>
- <placeholder/>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options"></property>
- </packing>
- </child>
- <child>
- <object class="GtkHBox" id="hbox2">
- <property name="visible">True</property>
- <child>
- <object class="GtkSpinButton" id="message_length_spinbutton">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="tooltip_text" translatable="yes">Message length at which notification is invoked.</property>
- <property name="width_chars">6</property>
- <property name="snap_to_ticks">True</property>
- <property name="numeric">True</property>
- <signal name="value_changed" handler="on_message_length_spinbutton_value_changed"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="alignment2">
- <property name="visible">True</property>
- <child>
- <placeholder/>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="x_options">GTK_FILL</property>
- <property name="y_options">GTK_FILL</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
-</interface>
diff --git a/plugins/length_notifier/length_notifier.py b/plugins/length_notifier/length_notifier.py
deleted file mode 100644
index 3c9e9bccc..000000000
--- a/plugins/length_notifier/length_notifier.py
+++ /dev/null
@@ -1,157 +0,0 @@
-# -*- coding: utf-8 -*-
-
-## This file is part of Gajim.
-##
-## Gajim is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published
-## by the Free Software Foundation; version 3 only.
-##
-## Gajim is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
-##
-
-'''
-Message length notifier plugin.
-
-:author: Mateusz Biliński <mateusz@bilinski.it>
-:since: 1st June 2008
-:copyright: Copyright (2008) Mateusz Biliński <mateusz@bilinski.it>
-:license: GPL
-'''
-
-import sys
-
-import gtk
-
-from plugins import GajimPlugin
-from plugins.helpers import log, log_calls
-from plugins.gui import GajimPluginConfigDialog
-
-class LengthNotifierPlugin(GajimPlugin):
-
- @log_calls('LengthNotifierPlugin')
- def init(self):
- self.description = _('Highlights message entry field in chat window '
- 'when given length of message is exceeded.')
- self.config_dialog = LengthNotifierPluginConfigDialog(self)
-
- self.gui_extension_points = {
- 'chat_control' : (self.connect_with_chat_control,
- self.disconnect_from_chat_control)
- }
-
- self.config_default_values = {
- 'MESSAGE_WARNING_LENGTH' : (140, 'Message length at which notification is invoked.'),
- 'WARNING_COLOR' : ('#F0DB3E', 'Background color of text entry field in chat window when notification is invoked.'),
- 'JIDS' : ([], 'JabberIDs that plugin should be used with (eg. restrict only to one microblogging bot). If empty plugin is used with every JID. [not implemented]')
- }
-
- @log_calls('LengthNotifierPlugin')
- def textview_length_warning(self, tb, chat_control):
- tv = chat_control.msg_textview
- d = chat_control.length_notifier_plugin_data
- t = tb.get_text(tb.get_start_iter(), tb.get_end_iter())
- if t:
- len_t = len(t)
- #print("len_t: %d"%(len_t))
- if len_t>self.config['MESSAGE_WARNING_LENGTH']:
- if not d['prev_color']:
- d['prev_color'] = tv.style.copy().base[gtk.STATE_NORMAL]
- tv.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.config['WARNING_COLOR']))
- elif d['prev_color']:
- tv.modify_base(gtk.STATE_NORMAL, d['prev_color'])
- d['prev_color'] = None
-
- @log_calls('LengthNotifierPlugin')
- def connect_with_chat_control(self, chat_control):
- jid = chat_control.contact.jid
- if self.jid_is_ok(jid):
- d = {'prev_color' : None}
- tv = chat_control.msg_textview
- tb = tv.get_buffer()
- h_id = tb.connect('changed', self.textview_length_warning, chat_control)
- d['h_id'] = h_id
-
- t = tb.get_text(tb.get_start_iter(), tb.get_end_iter())
- if t:
- len_t = len(t)
- if len_t>self.config['MESSAGE_WARNING_LENGTH']:
- d['prev_color'] = tv.style.copy().base[gtk.STATE_NORMAL]
- tv.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(self.config['WARNING_COLOR']))
-
- chat_control.length_notifier_plugin_data = d
-
- return True
-
- return False
-
- @log_calls('LengthNotifierPlugin')
- def disconnect_from_chat_control(self, chat_control):
- try:
- d = chat_control.length_notifier_plugin_data
- tv = chat_control.msg_textview
- tv.get_buffer().disconnect(d['h_id'])
- if d['prev_color']:
- tv.modify_base(gtk.STATE_NORMAL, d['prev_color'])
- except AttributeError, error:
- pass
- #log.debug('Length Notifier Plugin was (probably) never connected with this chat window.\n Error: %s' % (error))
-
- @log_calls('LengthNotifierPlugin')
- def jid_is_ok(self, jid):
- if jid in self.config['JIDS'] or not self.config['JIDS']:
- return True
-
- return False
-
-class LengthNotifierPluginConfigDialog(GajimPluginConfigDialog):
- 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,
- ['length_notifier_config_table'])
- self.config_table = self.xml.get_object('length_notifier_config_table')
- self.child.pack_start(self.config_table)
-
- self.message_length_spinbutton = self.xml.get_object(
- 'message_length_spinbutton')
- self.message_length_spinbutton.get_adjustment().set_all(140, 0, 500, 1,
- 10, 0)
- self.notification_colorbutton = self.xml.get_object(
- 'notification_colorbutton')
- self.jids_entry = self.xml.get_object('jids_entry')
-
- self.xml.connect_signals(self)
-
- def on_run(self):
- self.message_length_spinbutton.set_value(self.plugin.config['MESSAGE_WARNING_LENGTH'])
- self.notification_colorbutton.set_color(gtk.gdk.color_parse(self.plugin.config['WARNING_COLOR']))
- #self.jids_entry.set_text(self.plugin.config['JIDS'])
- self.jids_entry.set_text(','.join(self.plugin.config['JIDS']))
-
- @log_calls('LengthNotifierPluginConfigDialog')
- def on_message_length_spinbutton_value_changed(self, spinbutton):
- self.plugin.config['MESSAGE_WARNING_LENGTH'] = spinbutton.get_value()
-
- @log_calls('LengthNotifierPluginConfigDialog')
- def on_notification_colorbutton_color_set(self, colorbutton):
- self.plugin.config['WARNING_COLOR'] = colorbutton.get_color().to_string()
-
- @log_calls('LengthNotifierPluginConfigDialog')
- def on_jids_entry_changed(self, entry):
- text = entry.get_text()
- if len(text)>0:
- self.plugin.config['JIDS'] = entry.get_text().split(',')
- else:
- self.plugin.config['JIDS'] = []
-
- @log_calls('LengthNotifierPluginConfigDialog')
- def on_jids_entry_editing_done(self, entry):
- pass
diff --git a/plugins/length_notifier/manifest.ini b/plugins/length_notifier/manifest.ini
deleted file mode 100644
index d50feaa8d..000000000
--- a/plugins/length_notifier/manifest.ini
+++ /dev/null
@@ -1,9 +0,0 @@
-[info]
-name: Message Length Notifier
-short_name: length_notifier
-version: 0.1
-description: Highlights message entry field in chat window when given length of message is exceeded.
-authors = Mateusz Biliński <mateusz@bilinski.it>
-homepage = http://blog.bilinski.it
-
-
diff --git a/plugins/plugin_installer/__init__.py b/plugins/plugin_installer/__init__.py
deleted file mode 100644
index a272f29ca..000000000
--- a/plugins/plugin_installer/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from plugin_installer import PluginInstaller
diff --git a/plugins/plugin_installer/config_dialog.ui b/plugins/plugin_installer/config_dialog.ui
deleted file mode 100644
index e6376335c..000000000
--- a/plugins/plugin_installer/config_dialog.ui
+++ /dev/null
@@ -1,294 +0,0 @@
-<?xml version="1.0"?>
-<interface>
- <requires lib="gtk+" version="2.16"/>
- <!-- interface-naming-policy toplevel-contextual -->
- <object class="GtkTextBuffer" id="textbuffer1">
- <property name="text">Plug-in decription should be displayed here. This text will be erased during PluginsWindow initialization.</property>
- </object>
- <object class="GtkWindow" id="window1">
- <child>
- <object class="GtkHPaned" id="hpaned2">
- <property name="width_request">600</property>
- <property name="height_request">350</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="position">340</property>
- <property name="position_set">True</property>
- <child>
- <object class="GtkVBox" id="vbox1">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkScrolledWindow" id="scrolledwindow2">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="border_width">6</property>
- <property name="hscrollbar_policy">never</property>
- <property name="vscrollbar_policy">automatic</property>
- <child>
- <object class="GtkTreeView" id="available_treeview">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="search_column">1</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkProgressBar" id="progressbar">
- <property name="ellipsize">end</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="resize">False</property>
- <property name="shrink">False</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="vbox4">
- <property name="visible">True</property>
- <property name="border_width">5</property>
- <property name="orientation">vertical</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="plugin_name_label1">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label">&lt;empty&gt;</property>
- <property name="selectable">True</property>
- <property name="ellipsize">end</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkHBox" id="hbox8">
- <property name="visible">True</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel" id="label8">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Authors:</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="plugin_authors_label1">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="xpad">6</property>
- <property name="label">&lt;empty&gt;</property>
- <property name="selectable">True</property>
- <property name="ellipsize">end</property>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkHBox" id="hbox9">
- <property name="visible">True</property>
- <child>
- <object class="GtkLabel" id="label9">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Homepage:</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLinkButton" id="plugin_homepage_linkbutton1">
- <property name="label">button</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="relief">none</property>
- <property name="focus_on_click">False</property>
- <property name="xalign">0</property>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="vbox5">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkHBox" id="hbox10">
- <property name="visible">True</property>
- <child>
- <object class="GtkLabel" id="label10">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Description:</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="alignment4">
- <property name="visible">True</property>
- <child>
- <placeholder/>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkTextView" id="plugin_description_textview1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="pixels_above_lines">6</property>
- <property name="wrap_mode">word</property>
- <property name="left_margin">6</property>
- <property name="right_margin">6</property>
- <property name="indent">1</property>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">3</property>
- </packing>
- </child>
- <child>
- <object class="GtkHBox" id="hbox15">
- <property name="visible">True</property>
- <child>
- <placeholder/>
- </child>
- <child>
- <object class="GtkHButtonBox" id="hbuttonbox3">
- <property name="visible">True</property>
- <property name="layout_style">end</property>
- <child>
- <object class="GtkButton" id="inslall_upgrade_button">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">False</property>
- <property name="receives_default">True</property>
- <signal name="clicked" handler="on_inslall_upgrade_clicked"/>
- <child>
- <object class="GtkHBox" id="hbox1">
- <property name="visible">True</property>
- <child>
- <object class="GtkImage" id="image1">
- <property name="visible">True</property>
- <property name="stock">gtk-refresh</property>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label1">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Install/Upgrade</property>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="pack_type">end</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">4</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="resize">True</property>
- <property name="shrink">True</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- <object class="GtkWindow" id="window2">
- <child>
- <object class="GtkHBox" id="hbox111">
- <property name="visible">True</property>
- <child>
- <object class="GtkLabel" id="label1">
- <property name="visible">True</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Ftp server:</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="ftp_server">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="invisible_char">&#x25CF;</property>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
-</interface>
diff --git a/plugins/plugin_installer/manifest.ini b/plugins/plugin_installer/manifest.ini
deleted file mode 100644
index 7a1508150..000000000
--- a/plugins/plugin_installer/manifest.ini
+++ /dev/null
@@ -1,8 +0,0 @@
-[info]
-name: Plugin Installer
-short_name: plugin_installer
-version: 0.5
-description: Install and upgrade plugins from ftp
-authors: Denis Fomin <fominde@gmail.com>
- Yann Leboulanger <asterix@lagaule.org>
-homepage: http://www.gajim.org/
diff --git a/plugins/plugin_installer/plugin_installer.py b/plugins/plugin_installer/plugin_installer.py
deleted file mode 100644
index 1fe131477..000000000
--- a/plugins/plugin_installer/plugin_installer.py
+++ /dev/null
@@ -1,532 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-## plugins/plugin_installer/plugin_installer.py
-##
-## Copyright (C) 2010-2011 Denis Fomin <fominde AT gmail.com>
-## Copyright (C) 2011 Yann Leboulanger <asterix AT lagaule.org>
-##
-## This file is part of Gajim.
-##
-## Gajim is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published
-## by the Free Software Foundation; version 3 only.
-##
-## Gajim is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
-##
-import gtk
-import pango
-import gobject
-import ftplib
-import io
-import threading
-import ConfigParser
-import os
-import fnmatch
-import sys
-
-from common import gajim
-from plugins import GajimPlugin
-from plugins.helpers import log_calls, log
-from dialogs import WarningDialog, HigDialog, YesNoDialog
-from plugins.gui import GajimPluginConfigDialog
-
-
-def convert_version_to_list(version_str):
- version_list = version_str.split('.')
- l = []
- while len(version_list):
- l.append(int(version_list.pop(0)))
- return l
-
-class PluginInstaller(GajimPlugin):
-
- @log_calls('PluginInstallerPlugin')
- def init(self):
- self.description = _('Install and upgrade plugins from ftp')
- self.config_dialog = PluginInstallerPluginConfigDialog(self)
- self.config_default_values = {'ftp_server': ('ftp.gajim.org', '')}
- self.window = None
- self.progressbar = None
- self.available_plugins_model = None
- self.upgrading = False # True when opened from upgrade popup dialog
-
- @log_calls('PluginInstallerPlugin')
- 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)
- gobject.timeout_add_seconds(30, self.check_update)
-
- @log_calls('PluginInstallerPlugin')
- def warn_update(self, plugins):
- def open_update(dummy):
- self.upgrading = True
- self.pl_menuitem.activate()
- nb = gajim.interface.instances['plugins'].plugins_notebook
- gobject.idle_add(nb.set_current_page, 1)
- if plugins:
- plugins_str = '\n'.join(plugins)
- YesNoDialog(_('Plugins updates'), _('Some updates are available for'
- ' your installer plugins. Do you want to update those plugins:'
- '\n%s') % plugins_str, on_response_yes=open_update)
-
- @log_calls('PluginInstallerPlugin')
- def check_update(self):
- def _run():
- try:
- to_update = []
- con = ftplib.FTP_TLS(ftp.server)
- con.login()
- con.prot_p()
- con.cwd('plugins')
- plugins_dirs = con.nlst()
- for dir_ in plugins_dirs:
- try:
- con.retrbinary('RETR %s/manifest.ini' % dir_,
- ftp.handleDownload)
- except Exception, error:
- if str(error).startswith('550'):
- continue
- ftp.config.readfp(io.BytesIO(ftp.buffer_.getvalue()))
- local_version = ftp.get_plugin_version(ftp.config.get(
- 'info', 'name'))
- if local_version:
- local = convert_version_to_list(local_version)
- remote = convert_version_to_list(ftp.config.get('info',
- 'version'))
- if remote > local:
- to_update.append(ftp.config.get('info', 'name'))
- con.quit()
- gobject.idle_add(self.warn_update, to_update)
- except Exception, e:
- log.debug('Ftp error when check updates: %s' % str(e))
- ftp = Ftp(self)
- ftp.run = _run
- ftp.start()
-
- @log_calls('PluginInstallerPlugin')
- def deactivate(self):
- self.pl_menuitem.disconnect(self.id_)
- if hasattr(self, 'page_num'):
- self.notebook.remove_page(self.page_num)
- self.notebook.set_current_page(0)
- if hasattr(self, 'ftp'):
- del self.ftp
-
- def on_activate(self, widget):
- if 'plugins' not in gajim.interface.instances:
- return
- self.installed_plugins_model = gajim.interface.instances[
- 'plugins'].installed_plugins_model
- self.notebook = gajim.interface.instances['plugins'].plugins_notebook
- self.id_n = self.notebook.connect('switch-page',
- self.on_notebook_switch_page)
- self.window = gajim.interface.instances['plugins'].window
- self.window.connect('destroy', self.on_win_destroy)
- 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'])
- hpaned = self.xml.get_object('hpaned2')
- self.page_num = self.notebook.append_page(hpaned,
- gtk.Label(_('Available')))
-
- widgets_to_extract = ('plugin_name_label1',
- 'available_treeview', 'progressbar', 'inslall_upgrade_button',
- 'plugin_authors_label1', 'plugin_authors_label1',
- 'plugin_homepage_linkbutton1', 'plugin_description_textview1')
-
- for widget_name in widgets_to_extract:
- setattr(self, widget_name, self.xml.get_object(widget_name))
-
- attr_list = pango.AttrList()
- attr_list.insert(pango.AttrWeight(pango.WEIGHT_BOLD, 0, -1))
- self.plugin_name_label1.set_attributes(attr_list)
-
- self.available_plugins_model = gtk.ListStore(gobject.TYPE_PYOBJECT,
- gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING,
- gobject.TYPE_BOOLEAN, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT,
- gobject.TYPE_PYOBJECT)
- self.available_treeview.set_model(self.available_plugins_model)
-
- self.progressbar.set_property('no-show-all', True)
- renderer = gtk.CellRendererText()
- col = gtk.TreeViewColumn(_('Plugin'), renderer, text=1)
- col.set_resizable(True)
- col.set_property('expand', True)
- col.set_sizing(gtk.TREE_VIEW_COLUMN_GROW_ONLY)
- self.available_treeview.append_column(col)
- col = gtk.TreeViewColumn(_('Installed\nversion'), renderer, text=2)
- self.available_treeview.append_column(col)
- col = gtk.TreeViewColumn(_('Available\nversion'), renderer, text=3)
- col.set_property('expand', False)
- self.available_treeview.append_column(col)
-
- renderer = gtk.CellRendererToggle()
- renderer.set_property('activatable', True)
- renderer.connect('toggled', self.available_plugins_toggled_cb)
- col = gtk.TreeViewColumn(_('Install /\nUpgrade'), renderer, active=4)
- self.available_treeview.append_column(col)
-
- if gobject.signal_lookup('error_signal', self.window) is 0:
- gobject.signal_new('error_signal', self.window,
- gobject.SIGNAL_RUN_LAST, gobject.TYPE_STRING,
- (gobject.TYPE_STRING,))
- gobject.signal_new('plugin_downloaded', self.window,
- gobject.SIGNAL_RUN_LAST, gobject.TYPE_STRING,
- (gobject.TYPE_PYOBJECT,))
- self.window.connect('error_signal', self.on_some_ftp_error)
- self.window.connect('plugin_downloaded', self.on_plugin_downloaded)
-
- selection = self.available_treeview.get_selection()
- selection.connect('changed',
- self.available_plugins_treeview_selection_changed)
- selection.set_mode(gtk.SELECTION_SINGLE)
-
- self._clear_available_plugin_info()
- self.xml.connect_signals(self)
- self.window.show_all()
-
- def on_win_destroy(self, widget):
- if hasattr(self, 'ftp'):
- del self.ftp
-
- def available_plugins_toggled_cb(self, cell, path):
- is_active = self.available_plugins_model[path][4]
- self.available_plugins_model[path][4] = not is_active
- dir_list = []
- for i in xrange(len(self.available_plugins_model)):
- if self.available_plugins_model[i][4]:
- dir_list.append(self.available_plugins_model[i][0])
- 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):
- if not hasattr(self, 'ftp') and self.page_num == page_num:
- self.available_plugins_model.clear()
- self.progressbar.show()
- self.ftp = Ftp(self)
- self.ftp.remote_dirs = None
- self.ftp.upgrading = True
- self.ftp.start()
-
- def on_inslall_upgrade_clicked(self, widget):
- self.inslall_upgrade_button.set_property('sensitive', False)
- dir_list = []
- for i in xrange(len(self.available_plugins_model)):
- if self.available_plugins_model[i][4]:
- dir_list.append(self.available_plugins_model[i][0])
-
- ftp = Ftp(self)
- ftp.remote_dirs = dir_list
- ftp.start()
-
- def on_some_ftp_error(self, widget, error_text):
- for i in xrange(len(self.available_plugins_model)):
- self.available_plugins_model[i][4] = False
- self.progressbar.hide()
- WarningDialog(_('Ftp error'), error_text, self.window)
-
- def on_plugin_downloaded(self, widget, plugin_dirs):
- for _dir in plugin_dirs:
- is_active = False
- plugins = None
- plugin_dir = os.path.join(gajim.PLUGINS_DIRS[1], _dir)
- plugin = gajim.plugin_manager.get_plugin_by_path(plugin_dir)
- if plugin:
- if plugin.active and plugin.name != self.name:
- is_active = True
- gobject.idle_add(gajim.plugin_manager.deactivate_plugin,
- plugin)
- gajim.plugin_manager.plugins.remove(plugin)
-
- model = self.installed_plugins_model
- for row in xrange(len(model)):
- if plugin == model[row][0]:
- model.remove(model.get_iter((row, 0)))
- break
-
- plugins = self.scan_dir_for_plugin(plugin_dir)
- if not plugins:
- continue
- gajim.plugin_manager.add_plugin(plugins[0])
- plugin = gajim.plugin_manager.plugins[-1]
- for row in xrange(len(self.available_plugins_model)):
- if plugin.name == self.available_plugins_model[row][1]:
- self.available_plugins_model[row][2] = plugin.version
- self.available_plugins_model[row][4] = False
- continue
- if is_active and plugin.name != self.name:
- gobject.idle_add(gajim.plugin_manager.activate_plugin, plugin)
- if plugin.name != 'Plugin Installer':
- self.installed_plugins_model.append([plugin, plugin.name,
- is_active])
- dialog = HigDialog(None, gtk.MESSAGE_INFO, gtk.BUTTONS_OK,
- '', _('All selected plugins downloaded'))
- dialog.set_modal(False)
- dialog.set_transient_for(self.window)
- dialog.popup()
-
- def available_plugins_treeview_selection_changed(self, treeview_selection):
- model, iter = treeview_selection.get_selected()
- if iter:
- self.plugin_name_label1.set_text(model.get_value(iter, 1))
- self.plugin_authors_label1.set_text(model.get_value(iter, 6))
- self.plugin_homepage_linkbutton1.set_uri(model.get_value(iter, 7))
- self.plugin_homepage_linkbutton1.set_label(model.get_value(iter, 7))
- label = self.plugin_homepage_linkbutton1.get_children()[0]
- label.set_ellipsize(pango.ELLIPSIZE_END)
- self.plugin_homepage_linkbutton1.set_property('sensitive', True)
- desc_textbuffer = self.plugin_description_textview1.get_buffer()
- desc_textbuffer.set_text(_(model.get_value(iter, 5)))
- self.plugin_description_textview1.set_property('sensitive', True)
- else:
- self._clear_available_plugin_info()
-
- def _clear_available_plugin_info(self):
- self.plugin_name_label1.set_text('')
- self.plugin_authors_label1.set_text('')
- self.plugin_homepage_linkbutton1.set_uri('')
- self.plugin_homepage_linkbutton1.set_label('')
- self.plugin_homepage_linkbutton1.set_property('sensitive', False)
-
- desc_textbuffer = self.plugin_description_textview1.get_buffer()
- desc_textbuffer.set_text('')
- self.plugin_description_textview1.set_property('sensitive', False)
-
- def scan_dir_for_plugin(self, path):
- plugins_found = []
- conf = ConfigParser.ConfigParser()
- fields = ('name', 'short_name', 'version', 'description', 'authors',
- 'homepage')
- if not os.path.isdir(path):
- return plugins_found
-
- dir_list = os.listdir(path)
- dir_, mod = os.path.split(path)
- sys.path.insert(0, dir_)
-
- manifest_path = os.path.join(path, 'manifest.ini')
- if not os.path.isfile(manifest_path):
- return plugins_found
-
- for elem_name in dir_list:
- file_path = os.path.join(path, elem_name)
- module = None
-
- if os.path.isfile(file_path) and fnmatch.fnmatch(file_path, '*.py'):
- module_name = os.path.splitext(elem_name)[0]
- if module_name == '__init__':
- continue
- try:
- module = __import__('%s.%s' % (mod, module_name))
- except ValueError, value_error:
- pass
- except ImportError, import_error:
- pass
- except AttributeError, attribute_error:
- pass
- if module is None:
- continue
-
- for module_attr_name in [attr_name for attr_name in dir(module)
- if not (attr_name.startswith('__') or attr_name.endswith('__'))]:
- module_attr = getattr(module, module_attr_name)
- try:
- if not issubclass(module_attr, GajimPlugin) or \
- module_attr is GajimPlugin:
- continue
- module_attr.__path__ = os.path.abspath(os.path.dirname(
- file_path))
-
- # read metadata from manifest.ini
- conf.readfp(open(manifest_path, 'r'))
- for option in fields:
- if conf.get('info', option) is '':
- raise ConfigParser.NoOptionError, 'field empty'
- setattr(module_attr, option, conf.get('info', option))
- conf.remove_section('info')
- plugins_found.append(module_attr)
-
- except TypeError, type_error:
- pass
- except ConfigParser.NoOptionError, type_error:
- # all fields are required
- pass
- return plugins_found
-
-
-class Ftp(threading.Thread):
- def __init__(self, plugin):
- super(Ftp, self).__init__()
- self.plugin = plugin
- self.window = plugin.window
- self.server = plugin.config['ftp_server']
- self.progressbar = plugin.progressbar
- self.model = plugin.available_plugins_model
- self.config = ConfigParser.ConfigParser()
- self.buffer_ = io.BytesIO()
- self.remote_dirs = None
- self.append_to_model = True
- self.upgrading = False
-
- def model_append(self, row):
- self.model.append(row)
- return False
-
- def progressbar_pulse(self):
- self.progressbar.pulse()
- return True
-
- def get_plugin_version(self, plugin_name):
- for plugin in gajim.plugin_manager.plugins:
- if plugin.name == plugin_name:
- return plugin.version
-
- def run(self):
- try:
- gobject.idle_add(self.progressbar.set_text,
- _('Connecting to server'))
- self.ftp = ftplib.FTP_TLS(self.server)
- self.ftp.login()
- self.ftp.prot_p()
- self.ftp.cwd('plugins')
- if not self.remote_dirs:
- self.plugins_dirs = self.ftp.nlst()
- progress_step = 1.0 / len(self.plugins_dirs)
- gobject.idle_add(self.progressbar.set_text,
- _('Scan files on the server'))
- for dir_ in self.plugins_dirs:
- fract = self.progressbar.get_fraction() + progress_step
- gobject.idle_add(self.progressbar.set_fraction, fract)
- gobject.idle_add(self.progressbar.set_text,
- _('Read "%s"') % dir_)
- try:
- self.ftp.retrbinary('RETR %s/manifest.ini' % dir_,
- self.handleDownload)
- except Exception, error:
- if str(error).startswith('550'):
- continue
- self.config.readfp(io.BytesIO(self.buffer_.getvalue()))
- local_version = self.get_plugin_version(
- self.config.get('info', 'name'))
- upgrade = False
- if self.upgrading and local_version:
- local = convert_version_to_list(local_version)
- remote = convert_version_to_list(self.config.get('info',
- 'version'))
- if remote > local:
- upgrade = True
- gobject.idle_add(
- self.plugin.inslall_upgrade_button.set_property,
- 'sensitive', True)
- gobject.idle_add(self.model_append, [dir_,
- self.config.get('info', 'name'), local_version,
- self.config.get('info', 'version'), upgrade,
- self.config.get('info', 'description'),
- self.config.get('info', 'authors'),
- self.config.get('info', 'homepage'), ])
- self.plugins_dirs = None
- self.ftp.quit()
- gobject.idle_add(self.progressbar.set_fraction, 0)
- if self.remote_dirs:
- self.download_plugin()
- gobject.idle_add(self.progressbar.hide)
- except Exception, e:
- self.window.emit('error_signal', str(e))
-
- def handleDownload(self, block):
- self.buffer_.write(block)
-
- def download_plugin(self):
- gobject.idle_add(self.progressbar.show)
- self.pulse = gobject.timeout_add(150, self.progressbar_pulse)
- gobject.idle_add(self.progressbar.set_text, _('Create a list of files'))
- for remote_dir in self.remote_dirs:
-
- def nlstr(dir_, subdir=None):
- if subdir:
- dir_ = dir_ + '/' + subdir
- list_ = self.ftp.nlst(dir_)
- for i in list_:
- name = i.split('/')[-1]
- if '.' not in name:
- try:
- if i == self.ftp.nlst(i)[0]:
- files.append(i[1:])
- del dirs[i[1:]]
- except Exception, e:
- # empty dir or file
- continue
- dirs.append(i[1:])
- subdirs = name
- nlstr(dir_, subdirs)
- else:
- files.append(i[1:])
- dirs, files = [], []
- nlstr('/plugins/' + remote_dir)
-
- if not os.path.isdir(gajim.PLUGINS_DIRS[1]):
- os.mkdir(gajim.PLUGINS_DIRS[1])
- local_dir = ld = os.path.join(gajim.PLUGINS_DIRS[1], remote_dir)
- if not os.path.isdir(local_dir):
- os.mkdir(local_dir)
- local_dir = os.path.split(gajim.PLUGINS_DIRS[1])[0]
-
- # creating dirs
- for dir_ in dirs:
- try:
- os.mkdir(os.path.join(local_dir, dir_))
- except OSError, e:
- if str(e).startswith('[Errno 17]'):
- continue
- raise
-
- # downloading files
- for filename in files:
- gobject.idle_add(self.progressbar.set_text,
- _('Downloading "%s"') % filename)
- full_filename = os.path.join(local_dir, filename)
- try:
- self.ftp.retrbinary('RETR /%s' % filename,
- open(full_filename, 'wb').write)
- #full_filename.close()
- except ftplib.error_perm:
- print 'ERROR: cannot read file "%s"' % filename
- os.unlink(filename)
- self.ftp.quit()
- gobject.idle_add(self.window.emit, 'plugin_downloaded',
- self.remote_dirs)
- gobject.source_remove(self.pulse)
-
-
-class PluginInstallerPluginConfigDialog(GajimPluginConfigDialog):
- 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, ['hbox111'])
- hbox = self.xml.get_object('hbox111')
- self.child.pack_start(hbox)
-
- self.xml.connect_signals(self)
- self.connect('hide', self.on_hide)
-
- def on_run(self):
- widget = self.xml.get_object('ftp_server')
- widget.set_text(str(self.plugin.config['ftp_server']))
-
- def on_hide(self, widget):
- widget = self.xml.get_object('ftp_server')
- self.plugin.config['ftp_server'] = widget.get_text()
diff --git a/plugins/triggers/__init__.py b/plugins/triggers/__init__.py
deleted file mode 100644
index 4f8d9f87b..000000000
--- a/plugins/triggers/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from triggers import Triggers
diff --git a/plugins/triggers/config_dialog.ui b/plugins/triggers/config_dialog.ui
deleted file mode 100644
index ddc10c0a2..000000000
--- a/plugins/triggers/config_dialog.ui
+++ /dev/null
@@ -1,910 +0,0 @@
-<?xml version="1.0"?>
-<interface>
- <requires lib="gtk+" version="2.16"/>
- <!-- interface-naming-policy toplevel-contextual -->
- <object class="GtkListStore" id="liststore1">
- <columns>
- <!-- column-name item -->
- <column type="gchararray"/>
- </columns>
- <data>
- <row>
- <col id="0" translatable="yes">contact(s)</col>
- </row>
- <row>
- <col id="0" translatable="yes">group(s)</col>
- </row>
- <row>
- <col id="0" translatable="yes">everybody</col>
- </row>
- </data>
- </object>
- <object class="GtkListStore" id="liststore2">
- <columns>
- <!-- column-name item -->
- <column type="gchararray"/>
- </columns>
- <data>
- <row>
- <col id="0" translatable="yes">Receive a Message</col>
- </row>
- <row>
- <col id="0" translatable="yes">Contact Connects</col>
- </row>
- <row>
- <col id="0" translatable="yes">Contact Disconnects</col>
- </row>
- <row>
- <col id="0" translatable="yes">Contact Changes Status</col>
- </row>
- </data>
- </object>
- <object class="GtkWindow" id="advanced_notifications_window">
- <property name="border_width">6</property>
- <property name="title" translatable="yes">Advanced Notifications Control</property>
- <property name="role">Advanced Notifications Control</property>
- <property name="resizable">False</property>
- <property name="destroy_with_parent">True</property>
- <child>
- <object class="GtkVBox" id="vbox">
- <property name="visible">True</property>
- <property name="border_width">12</property>
- <property name="orientation">vertical</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkVBox" id="vbox100">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="spacing">5</property>
- <child>
- <object class="GtkScrolledWindow" id="scrolledwindow23">
- <property name="height_request">90</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">never</property>
- <property name="vscrollbar_policy">automatic</property>
- <property name="shadow_type">in</property>
- <child>
- <object class="GtkTreeView" id="conditions_treeview">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <signal name="cursor_changed" handler="on_conditions_treeview_cursor_changed"/>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="alignment99">
- <property name="visible">True</property>
- <property name="xalign">1</property>
- <property name="left_padding">212</property>
- <child>
- <object class="GtkHBox" id="hbox3045">
- <property name="visible">True</property>
- <child>
- <object class="GtkHButtonBox" id="hbuttonbox2">
- <property name="visible">True</property>
- <property name="spacing">10</property>
- <child>
- <object class="GtkButton" id="new_button">
- <property name="label">gtk-new</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="receives_default">False</property>
- <property name="use_stock">True</property>
- <signal name="clicked" handler="on_new_button_clicked"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="up_button">
- <property name="label">gtk-go-up</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="receives_default">False</property>
- <property name="use_stock">True</property>
- <signal name="clicked" handler="on_up_button_clicked"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="down_button">
- <property name="label">gtk-go-down</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="receives_default">False</property>
- <property name="use_stock">True</property>
- <signal name="clicked" handler="on_down_button_clicked"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="delete_button">
- <property name="label">gtk-delete</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="receives_default">False</property>
- <property name="use_stock">True</property>
- <signal name="clicked" handler="on_delete_button_clicked"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">3</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="config_vbox">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="spacing">5</property>
- <child>
- <object class="GtkLabel" id="label391">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;Conditions&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkVBox" id="vbox101">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="spacing">5</property>
- <child>
- <object class="GtkHBox" id="hbox3042">
- <property name="visible">True</property>
- <property name="spacing">5</property>
- <child>
- <object class="GtkLabel" id="label401">
- <property name="visible">True</property>
- <property name="label" translatable="yes">When </property>
- <property name="use_markup">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkComboBox" id="event_combobox">
- <property name="visible">True</property>
- <property name="model">liststore2</property>
- <signal name="changed" handler="on_event_combobox_changed"/>
- <child>
- <object class="GtkCellRendererText" id="cellrenderertext2"/>
- <attributes>
- <attribute name="text">0</attribute>
- </attributes>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkHBox" id="hbox3048">
- <property name="visible">True</property>
- <property name="spacing">5</property>
- <child>
- <object class="GtkLabel" id="label400">
- <property name="visible">True</property>
- <property name="label" translatable="yes">for </property>
- <property name="use_markup">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkComboBox" id="recipient_type_combobox">
- <property name="visible">True</property>
- <property name="model">liststore1</property>
- <signal name="changed" handler="on_recipient_type_combobox_changed"/>
- <child>
- <object class="GtkCellRendererText" id="cellrenderertext1"/>
- <attributes>
- <attribute name="text">0</attribute>
- </attributes>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="recipient_list_entry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="no_show_all">True</property>
- <property name="tooltip_text" translatable="yes">comma separated list</property>
- <signal name="changed" handler="on_recipient_list_entry_changed"/>
- </object>
- <packing>
- <property name="position">2</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkHBox" id="hbox3049">
- <property name="visible">True</property>
- <child>
- <object class="GtkLabel" id="label402">
- <property name="visible">True</property>
- <property name="label" translatable="yes">when I'm in</property>
- <property name="use_markup">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkHBox" id="status_hbox">
- <property name="visible">True</property>
- <property name="spacing">3</property>
- <child>
- <object class="GtkRadioButton" id="all_status_rb">
- <property name="label" translatable="yes">All statuses</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_status_radiobutton_toggled"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkRadioButton" id="special_status_rb">
- <property name="label" translatable="yes">One or more special statuses...</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- <property name="group">all_status_rb</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="online_cb">
- <property name="label" translatable="yes">Online / Free For Chat</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="no_show_all">True</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_status_cb_toggled"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="away_cb">
- <property name="label" translatable="yes">Away</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="no_show_all">True</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_status_cb_toggled"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">3</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="xa_cb">
- <property name="label" translatable="yes">Not Available</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="no_show_all">True</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_status_cb_toggled"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">4</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="dnd_cb">
- <property name="label" translatable="yes">Busy </property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="no_show_all">True</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_status_cb_toggled"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">5</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="invisible_cb">
- <property name="label" translatable="yes">Invisible</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="no_show_all">True</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_status_cb_toggled"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">6</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkHBox" id="hbox3053">
- <property name="visible">True</property>
- <child>
- <object class="GtkLabel" id="label408">
- <property name="visible">True</property>
- <property name="label" translatable="yes">and I </property>
- <property name="use_markup">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="tab_opened_cb">
- <property name="label" translatable="yes">Have </property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_tab_opened_cb_toggled"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="not_tab_opened_cb">
- <property name="label" translatable="yes">Don't have </property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_not_tab_opened_cb_toggled"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label409">
- <property name="visible">True</property>
- <property name="label" translatable="yes"> a window/tab opened with that contact </property>
- <property name="use_markup">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">3</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">3</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label392">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;Actions&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkFrame" id="frame35">
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">none</property>
- <child>
- <object class="GtkHBox" id="hbox3027">
- <property name="visible">True</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkCheckButton" id="use_popup_cb">
- <property name="label" translatable="yes">_Inform me with a popup window</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_use_popup_cb_toggled"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="disable_popup_cb">
- <property name="label" translatable="yes">_Disable existing popup window</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_disable_popup_cb_toggled"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- <child type="label">
- <object class="GtkFrame" id="frame38">
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">none</property>
- <child>
- <object class="GtkAlignment" id="alignment93">
- <property name="visible">True</property>
- <property name="border_width">6</property>
- <property name="left_padding">12</property>
- <child>
- <object class="GtkVBox" id="vbox98">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkHBox" id="hbox3028">
- <property name="visible">True</property>
- <property name="spacing">6</property>
- <property name="homogeneous">True</property>
- <child>
- <object class="GtkCheckButton" id="use_sound_cb">
- <property name="label" translatable="yes">Play a sound</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_use_sound_cb_toggled"/>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkHBox" id="sound_file_hbox">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkEntry" id="sound_entry">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <signal name="changed" handler="on_sound_entry_changed"/>
- </object>
- <packing>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="button4">
- <property name="label">...</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- <signal name="clicked" handler="on_browse_for_sounds_button_clicked"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="play_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <signal name="clicked" handler="on_play_button_clicked"/>
- <child>
- <object class="GtkImage" id="image1372">
- <property name="visible">True</property>
- <property name="stock">gtk-media-play</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="disable_sound_cb">
- <property name="label" translatable="yes">_Disable existing sound for this event</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_disable_sound_cb_toggled"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
- </child>
- <child type="label">
- <object class="GtkLabel" id="label394">
- <property name="visible">True</property>
- <property name="label" translatable="yes">&lt;b&gt;Sounds&lt;/b&gt;</property>
- <property name="use_markup">True</property>
- </object>
- </child>
- </object>
- </child>
- </object>
- <packing>
- <property name="position">3</property>
- </packing>
- </child>
- <child>
- <object class="GtkHBox" id="hbox3032">
- <property name="visible">True</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkCheckButton" id="use_auto_open_cb">
- <property name="label" translatable="yes">_Open chat window with user</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_use_auto_open_cb_toggled"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="disable_auto_open_cb">
- <property name="label" translatable="yes">_Disable auto opening chat window</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_disable_auto_open_cb_toggled"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">4</property>
- </packing>
- </child>
- <child>
- <object class="GtkExpander" id="expander1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="expanded">True</property>
- <child>
- <object class="GtkVBox" id="vbox99">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="spacing">5</property>
- <child>
- <object class="GtkHBox" id="hbox3033">
- <property name="visible">True</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkCheckButton" id="run_command_cb">
- <property name="label" translatable="yes">Launch a command</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_run_command_cb_toggled"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="command_entry">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <signal name="changed" handler="on_command_entry_changed"/>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkHBox" id="hbox3035">
- <property name="visible">True</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkCheckButton" id="use_systray_cb">
- <property name="label" translatable="yes">_Show event in notification area</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_use_systray_cb_toggled"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="disable_systray_cb">
- <property name="label" translatable="yes">_Disable showing event in notification area</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_disable_systray_cb_toggled"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkHBox" id="hbox3052">
- <property name="visible">True</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkCheckButton" id="use_roster_cb">
- <property name="label" translatable="yes">_Show event in roster</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_use_roster_cb_toggled"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="disable_roster_cb">
- <property name="label" translatable="yes">_Disable showing event in roster</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_disable_roster_cb_toggled"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="use_urgency_hint_cb">
- <property name="label" translatable="yes">_Activate window manager's UrgencyHint to make chat window in taskbar flash</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="no_show_all">True</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_use_urgency_hint_cb_toggled"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">3</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="disable_urgency_hint_cb">
- <property name="label" translatable="yes">_Deactivate window manager's UrgencyHint</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="no_show_all">True</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_disable_urgency_hint_cb_toggled"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">4</property>
- </packing>
- </child>
- </object>
- </child>
- <child type="label">
- <object class="GtkLabel" id="label395">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Advanced Actions</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="position">5</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- </child>
- </object>
-</interface>
diff --git a/plugins/triggers/manifest.ini b/plugins/triggers/manifest.ini
deleted file mode 100644
index 173bd102d..000000000
--- a/plugins/triggers/manifest.ini
+++ /dev/null
@@ -1,7 +0,0 @@
-[info]
-name: Triggers
-short_name: triggers
-version: 0.0.3
-description: Configure Gajim's behaviour for each contact
-authors: Yann Leboulanger <asterix@lagaule.org>
-homepage: http://trac.gajim.org/wiki/
diff --git a/plugins/triggers/triggers.py b/plugins/triggers/triggers.py
deleted file mode 100644
index 1cfdd9769..000000000
--- a/plugins/triggers/triggers.py
+++ /dev/null
@@ -1,677 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-## plugins/triggers/triggers.py
-##
-## Copyright (C) 2011 Yann Leboulanger <asterix AT lagaule.org>
-##
-## This file is part of Gajim.
-##
-## Gajim is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published
-## by the Free Software Foundation; version 3 only.
-##
-## Gajim is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
-##
-
-import gtk
-import sys
-
-from common import gajim
-from plugins import GajimPlugin
-from plugins.helpers import log_calls
-from plugins.gui import GajimPluginConfigDialog
-from common import ged
-from common import helpers
-
-
-class Triggers(GajimPlugin):
-
- @log_calls('TriggersPlugin')
- def init(self):
- self.description = _('Configure Gajim\'s behaviour for each contact')
- self.config_dialog = TriggersPluginConfigDialog(self)
- self.config_default_values = {}
-
- self.events_handlers = {'notification': (ged.PREGUI, self._nec_notif),
- 'decrypted-message-received': (ged.PREGUI2,
- self._nec_decrypted_message_received),
- 'presence-received': (ged.PREGUI, self._nec_presence_received)}
-
- def _check_rule_recipients(self, obj, rule):
- rule_recipients = [t.strip() for t in rule['recipients'].split(',')]
- if rule['recipient_type'] == 'contact' and obj.jid not in \
- rule_recipients:
- return False
- contact = gajim.contacts.get_first_contact_from_jid(obj.conn.name, obj.jid)
- if not contact: # PM?
- return False
- contact_groups = contact.groups
- group_found = False
- for group in contact_groups:
- if group in rule_recipients:
- group_found = True
- break
- if rule['recipient_type'] == 'group' and not group_found:
- return False
-
- return True
-
- def _check_rule_status(self, obj, rule):
- rule_statuses = rule['status'].split()
- our_status = gajim.SHOW_LIST[obj.conn.connected]
- if rule['status'] != 'all' and our_status not in rule_statuses:
- return False
-
- return True
-
- def _check_rule_tab_opened(self, obj, rule):
- if rule['tab_opened'] == 'both':
- return True
- tab_opened = False
- if gajim.interface.msg_win_mgr.get_control(obj.jid, obj.conn.name):
- tab_opened = True
- if tab_opened and rule['tab_opened'] == 'no':
- return False
- elif not tab_opened and rule['tab_opened'] == 'yes':
- return False
-
- return True
-
- def check_rule_all(self, event, obj, rule):
- # Check notification type
- if rule['event'] != event:
- return False
-
- # notification type is ok. Now check recipient
- if not self._check_rule_recipients(obj, rule):
- return False
-
- # recipient is ok. Now check our status
- if not self._check_rule_status(obj, rule):
- return False
-
- # our_status is ok. Now check opened chat window
- if not self._check_rule_tab_opened(obj, rule):
- return False
-
- # All is ok
- return True
-
- def check_rule_apply_notif(self, obj, rule):
- # Check notification type
- notif_type = ''
- if obj.notif_type == 'msg':
- notif_type = 'message_received'
- elif obj.notif_type == 'pres':
- if obj.base_event.old_show < 2 and obj.base_event.new_show > 1:
- notif_type = 'contact_connected'
- elif obj.base_event.old_show > 1 and obj.base_event.new_show < 2:
- notif_type = 'contact_disconnected'
- else:
- notif_type = 'contact_status_change'
-
- return self.check_rule_all(notif_type, obj, rule)
-
- def check_rule_apply_decrypted_msg(self, obj, rule):
- return self.check_rule_all('message_received', obj, rule)
-
- def check_rule_apply_connected(self, obj, rule):
- return self.check_rule_all('contact_connected', obj, rule)
-
- def check_rule_apply_disconnected(self, obj, rule):
- return self.check_rule_all('contact_disconnected', obj, rule)
-
- def check_rule_apply_status_changed(self, obj, rule):
- return self.check_rule_all('contact_status_change', obj, rule)
-
- def apply_rule_notif(self, obj, rule):
- if rule['sound'] == 'no':
- obj.do_sound = False
- elif rule['sound'] == 'yes':
- obj.do_sound = True
- obj.sound_event = ''
- obj.sound_file = rule['sound_file']
-
- if rule['popup'] == 'no':
- obj.do_popup = False
- elif rule['popup'] == 'yes':
- obj.do_popup = True
-
- if rule['run_command']:
- obj.do_command = True
- obj.command = rule['command']
- else:
- obj.do_command = False
-
- if rule['systray'] == 'no':
- obj.show_in_notification_area = False
- elif rule['systray'] == 'yes':
- obj.show_in_notification_area = True
-
- if rule['roster'] == 'no':
- obj.show_in_roster = False
- elif rule['roster'] == 'yes':
- obj.show_in_roster = True
-
-# if rule['urgency_hint'] == 'no':
-# ?? not in obj actions
-# elif rule['urgency_hint'] == 'yes':
-
- def apply_rule_decrypted_message(self, obj, rule):
- if rule['auto_open'] == 'no':
- obj.popup = False
- elif rule['auto_open'] == 'yes':
- obj.popup = True
-
- def apply_rule_presence(self, obj, rule):
- if rule['auto_open'] == 'no':
- obj.popup = False
- elif rule['auto_open'] == 'yes':
- obj.popup = True
-
- def _nec_all(self, obj, check_func, apply_func):
- # check rules in order
- rules_num = [int(i) for i in self.config.keys()]
- rules_num.sort()
- for num in rules_num:
- rule = self.config[str(num)]
- if check_func(obj, rule):
- apply_func(obj, rule)
- # Should we stop after first valid rule ?
- # break
-
- def _nec_notif(self, obj):
- self._nec_all(obj, self.check_rule_apply_notif, self.apply_rule_notif)
-
- def _nec_decrypted_message_received(self, obj):
- self._nec_all(obj, self.check_rule_apply_decrypted_msg,
- self.apply_rule_decrypted_message)
-
- def _nec_presence_received(self, obj):
- if obj.old_show < 2 and obj.new_show > 1:
- check_func = self.check_rule_apply_connected
- elif obj.old_show > 1 and obj.new_show < 2:
- check_func = self.check_rule_apply_disconnected
- else:
- check_func = self.check_rule_apply_status_changed
- self._nec_all(obj, check_func, self.apply_rule_presence)
-
-
-class TriggersPluginConfigDialog(GajimPluginConfigDialog):
- # {event: widgets_to_disable, }
- events_list = {
- 'message_received': [],
- 'contact_connected': ['use_systray_cb', 'disable_systray_cb',
- 'use_roster_cb', 'disable_roster_cb'],
- 'contact_disconnected': ['use_systray_cb', 'disable_systray_cb',
- 'use_roster_cb', 'disable_roster_cb'],
- 'contact_status_change': ['use_systray_cb', 'disable_systray_cb',
- 'use_roster_cb', 'disable_roster_cb']
- #, 'gc_msg_highlight': [], 'gc_msg': []}
- }
- recipient_types_list = ['contact', 'group', 'all']
- config_options = ['event', 'recipient_type', 'recipients', 'status',
- 'tab_opened', 'sound', 'sound_file', 'popup', 'auto_open',
- 'run_command', 'command', 'systray', 'roster', 'urgency_hint']
-
- 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,
- ['vbox', 'liststore1', 'liststore2'])
- vbox = self.xml.get_object('vbox')
- self.child.pack_start(vbox)
-
- self.xml.connect_signals(self)
- self.connect('hide', self.on_hide)
-
- def on_run(self):
- # fill window
- for w in ('conditions_treeview', 'config_vbox', 'event_combobox',
- 'recipient_type_combobox', 'recipient_list_entry', 'delete_button',
- 'status_hbox', 'use_sound_cb', 'disable_sound_cb', 'use_popup_cb',
- 'disable_popup_cb', 'use_auto_open_cb', 'disable_auto_open_cb',
- 'use_systray_cb', 'disable_systray_cb', 'use_roster_cb',
- 'disable_roster_cb', 'tab_opened_cb', 'not_tab_opened_cb',
- 'sound_entry', 'sound_file_hbox', 'up_button', 'down_button',
- 'run_command_cb', 'command_entry', 'use_urgency_hint_cb',
- 'disable_urgency_hint_cb'):
- self.__dict__[w] = self.xml.get_object(w)
-
- self.config = {}
- for n in self.plugin.config:
- self.config[int(n)] = self.plugin.config[n]
-
- # Contains status checkboxes
- childs = self.status_hbox.get_children()
-
- self.all_status_rb = childs[0]
- self.special_status_rb = childs[1]
- self.online_cb = childs[2]
- self.away_cb = childs[3]
- self.xa_cb = childs[4]
- self.dnd_cb = childs[5]
- self.invisible_cb = childs[6]
-
- if not self.conditions_treeview.get_column(0):
- # window never opened
- model = gtk.ListStore(int, str)
- model.set_sort_column_id(0, gtk.SORT_ASCENDING)
- self.conditions_treeview.set_model(model)
-
- # means number
- col = gtk.TreeViewColumn(_('#'))
- self.conditions_treeview.append_column(col)
- renderer = gtk.CellRendererText()
- col.pack_start(renderer, expand=False)
- col.set_attributes(renderer, text=0)
-
- col = gtk.TreeViewColumn(_('Condition'))
- self.conditions_treeview.append_column(col)
- renderer = gtk.CellRendererText()
- col.pack_start(renderer, expand=True)
- col.set_attributes(renderer, text=1)
- else:
- model = self.conditions_treeview.get_model()
-
- model.clear()
-
- # Fill conditions_treeview
- num = 0
- while num in self.config:
- iter_ = model.append((num, ''))
- path = model.get_path(iter_)
- self.conditions_treeview.set_cursor(path)
- self.active_num = num
- self.initiate_rule_state()
- self.set_treeview_string()
- num += 1
-
- # No rule selected at init time
- self.conditions_treeview.get_selection().unselect_all()
- self.active_num = -1
- self.config_vbox.set_sensitive(False)
- self.delete_button.set_sensitive(False)
- self.down_button.set_sensitive(False)
- self.up_button.set_sensitive(False)
-
- def initiate_rule_state(self):
- """
- Set values for all widgets
- """
- if self.active_num < 0:
- return
- # event
- value = self.config[self.active_num]['event']
- if value:
- self.event_combobox.set_active(self.events_list.keys().index(value))
- else:
- self.event_combobox.set_active(-1)
- # recipient_type
- value = self.config[self.active_num]['recipient_type']
- if value:
- self.recipient_type_combobox.set_active(
- self.recipient_types_list.index(value))
- else:
- self.recipient_type_combobox.set_active(-1)
- # recipient
- value = self.config[self.active_num]['recipients']
- if not value:
- value = ''
- self.recipient_list_entry.set_text(value)
- # status
- value = self.config[self.active_num]['status']
- if value == 'all':
- self.all_status_rb.set_active(True)
- else:
- self.special_status_rb.set_active(True)
- values = value.split()
- for v in ('online', 'away', 'xa', 'dnd', 'invisible'):
- if v in values:
- self.__dict__[v + '_cb'].set_active(True)
- else:
- self.__dict__[v + '_cb'].set_active(False)
- self.on_status_radiobutton_toggled(self.all_status_rb)
-
- # tab_opened
- value = self.config[self.active_num]['tab_opened']
- self.tab_opened_cb.set_active(True)
- self.not_tab_opened_cb.set_active(True)
- if value == 'no':
- self.tab_opened_cb.set_active(False)
- elif value == 'yes':
- self.not_tab_opened_cb.set_active(False)
-
- # sound_file
- value = self.config[self.active_num]['sound_file']
- self.sound_entry.set_text(value)
-
- # sound, popup, auto_open, systray, roster
- for option in ('sound', 'popup', 'auto_open', 'systray', 'roster',
- 'urgency_hint'):
- value = self.config[self.active_num][option]
- if value == 'yes':
- self.__dict__['use_' + option + '_cb'].set_active(True)
- else:
- self.__dict__['use_' + option + '_cb'].set_active(False)
- if value == 'no':
- self.__dict__['disable_' + option + '_cb'].set_active(True)
- else:
- self.__dict__['disable_' + option + '_cb'].set_active(False)
-
- # run_command
- value = self.config[self.active_num]['run_command']
- self.run_command_cb.set_active(value)
-
- # command
- value = self.config[self.active_num]['command']
- self.command_entry.set_text(value)
-
- def set_treeview_string(self):
- (model, iter_) = self.conditions_treeview.get_selection().get_selected()
- if not iter_:
- return
- event = self.event_combobox.get_active_text()
- recipient_type = self.recipient_type_combobox.get_active_text()
- recipient = ''
- if recipient_type != 'everybody':
- recipient = self.recipient_list_entry.get_text()
- if self.all_status_rb.get_active():
- status = ''
- else:
- status = _('when I am ')
- for st in ('online', 'away', 'xa', 'dnd', 'invisible'):
- if self.__dict__[st + '_cb'].get_active():
- status += helpers.get_uf_show(st) + ' '
- model[iter_][1] = "When %s for %s %s %s" % (event, recipient_type,
- recipient, status)
-
- def on_conditions_treeview_cursor_changed(self, widget):
- (model, iter_) = widget.get_selection().get_selected()
- if not iter_:
- self.active_num = ''
- return
- self.active_num = model[iter_][0]
- if self.active_num == '0':
- self.up_button.set_sensitive(False)
- else:
- self.up_button.set_sensitive(True)
- max = self.conditions_treeview.get_model().iter_n_children(None)
- if self.active_num == max - 1:
- self.down_button.set_sensitive(False)
- else:
- self.down_button.set_sensitive(True)
- self.initiate_rule_state()
- self.config_vbox.set_sensitive(True)
- self.delete_button.set_sensitive(True)
-
- def on_new_button_clicked(self, widget):
- model = self.conditions_treeview.get_model()
- num = self.conditions_treeview.get_model().iter_n_children(None)
- self.config[num] = {'event': '', 'recipient_type': 'all',
- 'recipients': '', 'status': 'all', 'tab_opened': 'both',
- 'sound': '', 'sound_file': '', 'popup': '', 'auto_open': '',
- 'run_command': False, 'command': '', 'systray': '', 'roster': '',
- 'urgency_hint': False}
- iter_ = model.append((num, ''))
- path = model.get_path(iter_)
- self.conditions_treeview.set_cursor(path)
- self.active_num = num
- self.set_treeview_string()
- self.config_vbox.set_sensitive(True)
-
- def on_delete_button_clicked(self, widget):
- (model, iter_) = self.conditions_treeview.get_selection().get_selected()
- if not iter_:
- return
- # up all others
- iter2 = model.iter_next(iter_)
- num = self.active_num
- while iter2:
- num = model[iter2][0]
- model[iter2][0] = num - 1
- self.config[num - 1] = self.config[num].copy()
- iter2 = model.iter_next(iter2)
- model.remove(iter_)
- del self.config[num]
- self.active_num = ''
- self.config_vbox.set_sensitive(False)
- self.delete_button.set_sensitive(False)
- self.up_button.set_sensitive(False)
- self.down_button.set_sensitive(False)
-
- def on_up_button_clicked(self, widget):
- (model, iter_) = self.conditions_treeview.get_selection().get_selected()
- if not iter_:
- return
- conf = self.config[self.active_num].copy()
- self.config[self.active_num] = self.config[self.active_num - 1]
- self.config[self.active_num - 1] = conf
-
- model[iter_][0] = self.active_num - 1
- # get previous iter
- path = model.get_path(iter_)
- iter_ = model.get_iter((path[0] - 1,))
- model[iter_][0] = self.active_num
- self.on_conditions_treeview_cursor_changed(self.conditions_treeview)
-
- def on_down_button_clicked(self, widget):
- (model, iter_) = self.conditions_treeview.get_selection().get_selected()
- if not iter_:
- return
- conf = self.config[self.active_num].copy()
- self.config[self.active_num] = self.config[self.active_num + 1]
- self.config[self.active_num + 1] = conf
-
- model[iter_][0] = self.active_num + 1
- iter_ = model.iter_next(iter_)
- model[iter_][0] = self.active_num
- self.on_conditions_treeview_cursor_changed(self.conditions_treeview)
-
- def on_event_combobox_changed(self, widget):
- if self.active_num < 0:
- return
- active = self.event_combobox.get_active()
- if active == -1:
- event = ''
- else:
- event = self.events_list.keys()[active]
- self.config[self.active_num]['event'] = event
- for w in ('use_systray_cb', 'disable_systray_cb', 'use_roster_cb',
- 'disable_roster_cb'):
- self.__dict__[w].set_sensitive(True)
- for w in self.events_list[event]:
- self.__dict__[w].set_sensitive(False)
- self.__dict__[w].set_state(False)
- self.set_treeview_string()
-
- def on_recipient_type_combobox_changed(self, widget):
- if self.active_num < 0:
- return
- recipient_type = self.recipient_types_list[
- self.recipient_type_combobox.get_active()]
- self.config[self.active_num]['recipient_type'] = recipient_type
- if recipient_type == 'all':
- self.recipient_list_entry.hide()
- else:
- self.recipient_list_entry.show()
- self.set_treeview_string()
-
- def on_recipient_list_entry_changed(self, widget):
- if self.active_num < 0:
- return
- recipients = widget.get_text().decode('utf-8')
- #TODO: do some check
- self.config[self.active_num]['recipients'] = recipients
- self.set_treeview_string()
-
- def set_status_config(self):
- if self.active_num < 0:
- return
- status = ''
- for st in ('online', 'away', 'xa', 'dnd', 'invisible'):
- if self.__dict__[st + '_cb'].get_active():
- status += st + ' '
- if status:
- status = status[:-1]
- self.config[self.active_num]['status'] = status
- self.set_treeview_string()
-
- def on_status_radiobutton_toggled(self, widget):
- if self.active_num < 0:
- return
- if self.all_status_rb.get_active():
- self.config[self.active_num]['status'] = 'all'
- # 'All status' clicked
- for st in ('online', 'away', 'xa', 'dnd', 'invisible'):
- self.__dict__[st + '_cb'].hide()
-
- self.special_status_rb.show()
- else:
- self.set_status_config()
- # 'special status' clicked
- for st in ('online', 'away', 'xa', 'dnd', 'invisible'):
- self.__dict__[st + '_cb'].show()
-
- self.special_status_rb.hide()
- self.set_treeview_string()
-
- def on_status_cb_toggled(self, widget):
- if self.active_num < 0:
- return
- self.set_status_config()
-
- # tab_opened OR (not xor) not_tab_opened must be active
- def on_tab_opened_cb_toggled(self, widget):
- if self.active_num < 0:
- return
- if self.tab_opened_cb.get_active():
- if self.not_tab_opened_cb.get_active():
- self.config[self.active_num]['tab_opened'] = 'both'
- else:
- self.config[self.active_num]['tab_opened'] = 'yes'
- else:
- self.not_tab_opened_cb.set_active(True)
- self.config[self.active_num]['tab_opened'] = 'no'
-
- def on_not_tab_opened_cb_toggled(self, widget):
- if self.active_num < 0:
- return
- if self.not_tab_opened_cb.get_active():
- if self.tab_opened_cb.get_active():
- self.config[self.active_num]['tab_opened'] = 'both'
- else:
- self.config[self.active_num]['tab_opened'] = 'no'
- else:
- self.tab_opened_cb.set_active(True)
- self.config[self.active_num]['tab_opened'] = 'yes'
-
- def on_use_it_toggled(self, widget, oposite_widget, option):
- if widget.get_active():
- if oposite_widget.get_active():
- oposite_widget.set_active(False)
- self.config[self.active_num][option] = 'yes'
- elif oposite_widget.get_active():
- self.config[self.active_num][option] = 'no'
- else:
- self.config[self.active_num][option] = ''
-
- def on_disable_it_toggled(self, widget, oposite_widget, option):
- if widget.get_active():
- if oposite_widget.get_active():
- oposite_widget.set_active(False)
- self.config[self.active_num][option] = 'no'
- elif oposite_widget.get_active():
- self.config[self.active_num][option] = 'yes'
- else:
- self.config[self.active_num][option] = ''
-
- def on_use_sound_cb_toggled(self, widget):
- self.on_use_it_toggled(widget, self.disable_sound_cb, 'sound')
- if widget.get_active():
- self.sound_file_hbox.set_sensitive(True)
- else:
- self.sound_file_hbox.set_sensitive(False)
-
- def on_browse_for_sounds_button_clicked(self, widget, data=None):
- if self.active_num < 0:
- return
-
- def on_ok(widget, path_to_snd_file):
- dialog.destroy()
- if not path_to_snd_file:
- path_to_snd_file = ''
- self.config[self.active_num]['sound_file'] = path_to_snd_file
- self.sound_entry.set_text(path_to_snd_file)
-
- path_to_snd_file = self.sound_entry.get_text().decode('utf-8')
- path_to_snd_file = os.path.join(os.getcwd(), path_to_snd_file)
- dialog = SoundChooserDialog(path_to_snd_file, on_ok)
-
- def on_play_button_clicked(self, widget):
- helpers.play_sound_file(self.sound_entry.get_text().decode('utf-8'))
-
- def on_disable_sound_cb_toggled(self, widget):
- self.on_disable_it_toggled(widget, self.use_sound_cb, 'sound')
-
- def on_sound_entry_changed(self, widget):
- self.config[self.active_num]['sound_file'] = widget.get_text().\
- decode('utf-8')
-
- def on_use_popup_cb_toggled(self, widget):
- self.on_use_it_toggled(widget, self.disable_popup_cb, 'popup')
-
- def on_disable_popup_cb_toggled(self, widget):
- self.on_disable_it_toggled(widget, self.use_popup_cb, 'popup')
-
- def on_use_auto_open_cb_toggled(self, widget):
- self.on_use_it_toggled(widget, self.disable_auto_open_cb, 'auto_open')
-
- def on_disable_auto_open_cb_toggled(self, widget):
- self.on_disable_it_toggled(widget, self.use_auto_open_cb, 'auto_open')
-
- def on_run_command_cb_toggled(self, widget):
- self.config[self.active_num]['run_command'] = widget.get_active()
- if widget.get_active():
- self.command_entry.set_sensitive(True)
- else:
- self.command_entry.set_sensitive(False)
-
- def on_command_entry_changed(self, widget):
- self.config[self.active_num]['command'] = widget.get_text().\
- decode('utf-8')
-
- def on_use_systray_cb_toggled(self, widget):
- self.on_use_it_toggled(widget, self.disable_systray_cb, 'systray')
-
- def on_disable_systray_cb_toggled(self, widget):
- self.on_disable_it_toggled(widget, self.use_systray_cb, 'systray')
-
- def on_use_roster_cb_toggled(self, widget):
- self.on_use_it_toggled(widget, self.disable_roster_cb, 'roster')
-
- def on_disable_roster_cb_toggled(self, widget):
- self.on_disable_it_toggled(widget, self.use_roster_cb, 'roster')
-
- def on_use_urgency_hint_cb_toggled(self, widget):
- self.on_use_it_toggled(widget, self.disable_urgency_hint_cb,
- 'uregency_hint')
-
- def on_disable_urgency_hint_cb_toggled(self, widget):
- self.on_disable_it_toggled(widget, self.use_urgency_hint_cb,
- 'uregency_hint')
-
- def on_hide(self, widget):
- # save config
- for n in self.plugin.config:
- del self.plugin.config[n]
- for n in self.config:
- self.plugin.config[str(n)] = self.config[n]
diff --git a/plugins/whiteboard/__init__.py b/plugins/whiteboard/__init__.py
deleted file mode 100644
index 802d00cdf..000000000
--- a/plugins/whiteboard/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-from plugin import WhiteboardPlugin
diff --git a/plugins/whiteboard/brush_tool.png b/plugins/whiteboard/brush_tool.png
deleted file mode 100644
index 266c32171..000000000
--- a/plugins/whiteboard/brush_tool.png
+++ /dev/null
Binary files differ
diff --git a/plugins/whiteboard/line_tool.png b/plugins/whiteboard/line_tool.png
deleted file mode 100644
index 151f58484..000000000
--- a/plugins/whiteboard/line_tool.png
+++ /dev/null
Binary files differ
diff --git a/plugins/whiteboard/manifest.ini b/plugins/whiteboard/manifest.ini
deleted file mode 100644
index a9f67085e..000000000
--- a/plugins/whiteboard/manifest.ini
+++ /dev/null
@@ -1,7 +0,0 @@
-[info]
-name: Whiteboard
-short_name: whiteboard
-version: 0.1
-description: Shows a whiteboard in chat. python-pygoocanvas is required.
-authors = Yann Leboulanger <asterix@lagaule.org>
-homepage = www.gajim.org
diff --git a/plugins/whiteboard/oval_tool.png b/plugins/whiteboard/oval_tool.png
deleted file mode 100644
index efd6f0ca1..000000000
--- a/plugins/whiteboard/oval_tool.png
+++ /dev/null
Binary files differ
diff --git a/plugins/whiteboard/plugin.py b/plugins/whiteboard/plugin.py
deleted file mode 100644
index 9132e9a88..000000000
--- a/plugins/whiteboard/plugin.py
+++ /dev/null
@@ -1,483 +0,0 @@
-## plugins/whiteboard/plugin.py
-##
-## Copyright (C) 2009 Jeff Ling <jeff.ummu AT gmail.com>
-## Copyright (C) 2010 Yann Leboulanger <asterix AT lagaule.org>
-##
-## This file is part of Gajim.
-##
-## Gajim is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published
-## by the Free Software Foundation; version 3 only.
-##
-## Gajim is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
-##
-
-'''
-Whiteboard plugin.
-
-:author: Yann Leboulanger <asterix@lagaule.org>
-:since: 1st November 2010
-:copyright: Copyright (2010) Yann Leboulanger <asterix@lagaule.org>
-:license: GPL
-'''
-
-
-from common import helpers
-from common import gajim
-from plugins import GajimPlugin
-from plugins.plugin import GajimPluginException
-from plugins.helpers import log_calls, log
-import common.xmpp
-import gtk
-import chat_control
-from common import ged
-from common.jingle_session import JingleSession
-from common.jingle_content import JingleContent
-from common.jingle_transport import JingleTransport, TransportType
-import dialogs
-from whiteboard_widget import Whiteboard, HAS_GOOCANVAS
-from common import xmpp
-from common import caps_cache
-
-NS_JINGLE_XHTML = 'urn:xmpp:tmp:jingle:apps:xhtml'
-NS_JINGLE_SXE = 'urn:xmpp:tmp:jingle:transports:sxe'
-NS_SXE = 'urn:xmpp:sxe:0'
-
-class WhiteboardPlugin(GajimPlugin):
- @log_calls('WhiteboardPlugin')
- def init(self):
- self.description = _('Shows a whiteboard in chat.'
- ' python-pygoocanvas is required.')
- self.config_dialog = None
- self.events_handlers = {
- 'jingle-request-received': (ged.GUI1, self._nec_jingle_received),
- 'jingle-connected-received': (ged.GUI1, self._nec_jingle_connected),
- 'jingle-disconnected-received': (ged.GUI1,
- self._nec_jingle_disconnected),
- 'raw-message-received': (ged.GUI1, self._nec_raw_message),
- }
- self.gui_extension_points = {
- 'chat_control_base' : (self.connect_with_chat_control,
- self.disconnect_from_chat_control),
- 'chat_control_base_update_toolbar': (self.update_button_state,
- None),
- }
- self.controls = []
- self.sid = None
-
- @log_calls('WhiteboardPlugin')
- def _compute_caps_hash(self):
- for a in gajim.connections:
- gajim.caps_hash[a] = caps_cache.compute_caps_hash([
- gajim.gajim_identity], gajim.gajim_common_features + \
- gajim.gajim_optional_features[a])
- # re-send presence with new hash
- connected = gajim.connections[a].connected
- if connected > 1 and gajim.SHOW_LIST[connected] != 'invisible':
- gajim.connections[a].change_status(gajim.SHOW_LIST[connected],
- gajim.connections[a].status)
-
- @log_calls('WhiteboardPlugin')
- def activate(self):
- if not HAS_GOOCANVAS:
- raise GajimPluginException('python-pygoocanvas is missing!')
- if NS_JINGLE_SXE not in gajim.gajim_common_features:
- gajim.gajim_common_features.append(NS_JINGLE_SXE)
- if NS_SXE not in gajim.gajim_common_features:
- gajim.gajim_common_features.append(NS_SXE)
- self._compute_caps_hash()
-
- @log_calls('WhiteboardPlugin')
- def deactivate(self):
- if NS_JINGLE_SXE in gajim.gajim_common_features:
- gajim.gajim_common_features.remove(NS_JINGLE_SXE)
- if NS_SXE in gajim.gajim_common_features:
- gajim.gajim_common_features.remove(NS_SXE)
- self._compute_caps_hash()
-
- @log_calls('WhiteboardPlugin')
- def connect_with_chat_control(self, control):
- if isinstance(control, chat_control.ChatControl):
- base = Base(self, control)
- self.controls.append(base)
-
- @log_calls('WhiteboardPlugin')
- def disconnect_from_chat_control(self, chat_control):
- for base in self.controls:
- base.disconnect_from_chat_control()
- self.controls = []
-
- @log_calls('WhiteboardPlugin')
- def update_button_state(self, control):
- for base in self.controls:
- if base.chat_control == control:
- if control.contact.supports(NS_JINGLE_SXE) and \
- control.contact.supports(NS_SXE):
- base.button.set_sensitive(True)
- tooltip_text = _('Show whiteboard')
- else:
- base.button.set_sensitive(False)
- tooltip_text = _('Client on the other side '
- 'does not support the whiteboard')
- base.button.set_tooltip_text(tooltip_text)
-
- @log_calls('WhiteboardPlugin')
- def show_request_dialog(self, account, fjid, jid, sid, content_types):
- def on_ok():
- session = gajim.connections[account].get_jingle_session(fjid, sid)
- self.sid = session.sid
- if not session.accepted:
- session.approve_session()
- for content in content_types:
- session.approve_content(content)
- for _jid in (fjid, jid):
- ctrl = gajim.interface.msg_win_mgr.get_control(_jid, account)
- if ctrl:
- break
- if not ctrl:
- # create it
- gajim.interface.new_chat_from_jid(account, jid)
- ctrl = gajim.interface.msg_win_mgr.get_control(jid, account)
- session = session.contents[('initiator', 'xhtml')]
- ctrl.draw_whiteboard(session)
-
- def on_cancel():
- session = gajim.connections[account].get_jingle_session(fjid, sid)
- session.decline_session()
-
- contact = gajim.contacts.get_first_contact_from_jid(account, jid)
- if contact:
- name = contact.get_shown_name()
- else:
- name = jid
- pritext = _('Incoming Whiteboard')
- sectext = _('%(name)s (%(jid)s) wants to start a whiteboard with '
- 'you. Do you want to accept?') % {'name': name, 'jid': jid}
- dialog = dialogs.NonModalConfirmationDialog(pritext, sectext=sectext,
- on_response_ok=on_ok, on_response_cancel=on_cancel)
- dialog.popup()
-
- @log_calls('WhiteboardPlugin')
- def _nec_jingle_received(self, obj):
- if not HAS_GOOCANVAS:
- return
- content_types = set(c[0] for c in obj.contents)
- if 'xhtml' not in content_types:
- return
- self.show_request_dialog(obj.conn.name, obj.fjid, obj.jid, obj.sid,
- content_types)
-
- @log_calls('WhiteboardPlugin')
- def _nec_jingle_connected(self, obj):
- if not HAS_GOOCANVAS:
- return
- account = obj.conn.name
- ctrl = (gajim.interface.msg_win_mgr.get_control(obj.fjid, account)
- or gajim.interface.msg_win_mgr.get_control(obj.jid, account))
- if not ctrl:
- return
- session = gajim.connections[obj.conn.name].get_jingle_session(obj.fjid,
- obj.sid)
-
- if ('initiator', 'xhtml') not in session.contents:
- return
-
- session = session.contents[('initiator', 'xhtml')]
- ctrl.draw_whiteboard(session)
-
- @log_calls('WhiteboardPlugin')
- def _nec_jingle_disconnected(self, obj):
- for base in self.controls:
- if base.sid == obj.sid:
- base.stop_whiteboard(reason = obj.reason)
-
- @log_calls('WhiteboardPlugin')
- def _nec_raw_message(self, obj):
- if not HAS_GOOCANVAS:
- return
- if obj.stanza.getTag('sxe', namespace=NS_SXE):
- account = obj.conn.name
-
- try:
- fjid = helpers.get_full_jid_from_iq(obj.stanza)
- except helpers.InvalidFormat:
- obj.conn.dispatch('ERROR', (_('Invalid Jabber ID'),
- _('A message from a non-valid JID arrived, it has been '
- 'ignored.')))
-
- jid = gajim.get_jid_without_resource(fjid)
- ctrl = (gajim.interface.msg_win_mgr.get_control(fjid, account)
- or gajim.interface.msg_win_mgr.get_control(jid, account))
- if not ctrl:
- return
- sxe = obj.stanza.getTag('sxe')
- if not sxe:
- return
- sid = sxe.getAttr('session')
- if (jid, sid) not in obj.conn._sessions:
- pass
-# newjingle = JingleSession(con=self, weinitiate=False, jid=jid, sid=sid)
-# self.addJingle(newjingle)
-
- # we already have such session in dispatcher...
- session = obj.conn.get_jingle_session(fjid, sid)
- cn = session.contents[('initiator', 'xhtml')]
- error = obj.stanza.getTag('error')
- if error:
- action = 'iq-error'
- else:
- action = 'edit'
-
- cn.on_stanza(obj.stanza, sxe, error, action)
-# def __editCB(self, stanza, content, error, action):
- #new_tags = sxe.getTags('new')
- #remove_tags = sxe.getTags('remove')
-
- #if new_tags is not None:
- ## Process new elements
- #for tag in new_tags:
- #if tag.getAttr('type') == 'element':
- #ctrl.whiteboard.recieve_element(tag)
- #elif tag.getAttr('type') == 'attr':
- #ctrl.whiteboard.recieve_attr(tag)
- #ctrl.whiteboard.apply_new()
-
- #if remove_tags is not None:
- ## Delete rids
- #for tag in remove_tags:
- #target = tag.getAttr('target')
- #ctrl.whiteboard.image.del_rid(target)
-
- # Stop propagating this event, it's handled
- return True
-
-
-class Base(object):
- def __init__(self, plugin, chat_control):
- self.plugin = plugin
- self.chat_control = chat_control
- self.chat_control.draw_whiteboard = self.draw_whiteboard
- self.contact = self.chat_control.contact
- self.account = self.chat_control.account
- self.jid = self.contact.get_full_jid()
- self.create_buttons()
- self.whiteboard = None
- self.sid = None
-
- def create_buttons(self):
- # create whiteboard button
- actions_hbox = self.chat_control.xml.get_object('actions_hbox')
- self.button = gtk.ToggleButton(label=None, use_underline=True)
- self.button.set_property('relief', gtk.RELIEF_NONE)
- self.button.set_property('can-focus', False)
- img = gtk.Image()
- img_path = self.plugin.local_file_path('whiteboard.png')
- pixbuf = gtk.gdk.pixbuf_new_from_file(img_path)
- iconset = gtk.IconSet(pixbuf=pixbuf)
- factory = gtk.IconFactory()
- factory.add('whiteboard', iconset)
- img_path = self.plugin.local_file_path('brush_tool.png')
- pixbuf = gtk.gdk.pixbuf_new_from_file(img_path)
- iconset = gtk.IconSet(pixbuf=pixbuf)
- factory.add('brush_tool', iconset)
- img_path = self.plugin.local_file_path('line_tool.png')
- pixbuf = gtk.gdk.pixbuf_new_from_file(img_path)
- iconset = gtk.IconSet(pixbuf=pixbuf)
- factory.add('line_tool', iconset)
- img_path = self.plugin.local_file_path('oval_tool.png')
- pixbuf = gtk.gdk.pixbuf_new_from_file(img_path)
- iconset = gtk.IconSet(pixbuf=pixbuf)
- factory.add('oval_tool', iconset)
- factory.add_default()
- img.set_from_stock('whiteboard', gtk.ICON_SIZE_MENU)
- self.button.set_image(img)
- send_button = self.chat_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)
- id_ = self.button.connect('toggled', self.on_whiteboard_button_toggled)
- self.chat_control.handlers[id_] = self.button
- self.button.show()
-
- def draw_whiteboard(self, content):
- hbox = self.chat_control.xml.get_object('chat_control_hbox')
- if len(hbox.get_children()) == 1:
- self.whiteboard = Whiteboard(self.account, self.contact, content,
- self.plugin)
- # set minimum size
- self.whiteboard.hbox.set_size_request(300, 0)
- hbox.pack_start(self.whiteboard.hbox, expand=False, fill=False)
- self.whiteboard.hbox.show_all()
- self.button.set_active(True)
- content.control = self
- self.sid = content.session.sid
-
- def on_whiteboard_button_toggled(self, widget):
- """
- Popup whiteboard
- """
- if widget.get_active():
- if not self.whiteboard:
- self.start_whiteboard()
- else:
- self.stop_whiteboard()
-
- def start_whiteboard(self):
- conn = gajim.connections[self.chat_control.account]
- jingle = JingleSession(conn, weinitiate=True, jid=self.jid)
- self.sid = jingle.sid
- conn._sessions[jingle.sid] = jingle
- content = JingleWhiteboard(jingle)
- content.control = self
- jingle.add_content('xhtml', content)
- jingle.start_session()
-
- def stop_whiteboard(self, reason=None):
- conn = gajim.connections[self.chat_control.account]
- self.sid = None
- session = conn.get_jingle_session(self.jid, media='xhtml')
- if session:
- session.end_session()
- self.button.set_active(False)
- if reason:
- txt = _('Whiteboard stopped: %(reason)s') % {'reason': reason}
- self.chat_control.print_conversation(txt, 'info')
- if not self.whiteboard:
- return
- hbox = self.chat_control.xml.get_object('chat_control_hbox')
- if self.whiteboard.hbox in hbox.get_children():
- if hasattr(self.whiteboard, 'hbox'):
- hbox.remove(self.whiteboard.hbox)
- self.whiteboard = None
-
- def disconnect_from_chat_control(self):
- actions_hbox = self.chat_control.xml.get_object('actions_hbox')
- actions_hbox.remove(self.button)
-
-class JingleWhiteboard(JingleContent):
- ''' Jingle Whiteboard sessions consist of xhtml content'''
- def __init__(self, session, transport=None):
- if not transport:
- transport = JingleTransportSXE()
- JingleContent.__init__(self, session, transport)
- self.media = 'xhtml'
- self.negotiated = True # there is nothing to negotiate
- self.last_rid = 0
- self.callbacks['session-accept'] += [self._sessionAcceptCB]
- self.callbacks['session-terminate'] += [self._stop]
- self.callbacks['session-terminate-sent'] += [self._stop]
- self.callbacks['edit'] = [self._EditCB]
-
- def _EditCB(self, stanza, content, error, action):
- new_tags = content.getTags('new')
- remove_tags = content.getTags('remove')
-
- if new_tags is not None:
- # Process new elements
- for tag in new_tags:
- if tag.getAttr('type') == 'element':
- self.control.whiteboard.recieve_element(tag)
- elif tag.getAttr('type') == 'attr':
- self.control.whiteboard.recieve_attr(tag)
- self.control.whiteboard.apply_new()
-
- if remove_tags is not None:
- # Delete rids
- for tag in remove_tags:
- target = tag.getAttr('target')
- self.control.whiteboard.image.del_rid(target)
-
- def _sessionAcceptCB(self, stanza, content, error, action):
- log.debug('session accepted')
- self.session.connection.dispatch('WHITEBOARD_ACCEPTED',
- (self.session.peerjid, self.session.sid))
-
- def generate_rids(self, x):
- # generates x number of rids and returns in list
- rids = []
- for x in range(x):
- rids.append(str(self.last_rid))
- self.last_rid += 1
- return rids
-
- def send_whiteboard_node(self, items, rids):
- # takes int rid and dict items and sends it as a node
- # sends new item
- jid = self.session.peerjid
- sid = self.session.sid
- message = xmpp.Message(to=jid)
- sxe = message.addChild(name='sxe', attrs={'session': sid},
- namespace=NS_SXE)
-
- for x in rids:
- if items[x]['type'] == 'element':
- parent = x
- attrs = {'rid': x,
- 'name': items[x]['data'][0].getName(),
- 'type': items[x]['type']}
- sxe.addChild(name='new', attrs=attrs)
- if items[x]['type'] == 'attr':
- attr_name = items[x]['data']
- chdata = items[parent]['data'][0].getAttr(attr_name)
- attrs = {'rid': x,
- 'name': attr_name,
- 'type': items[x]['type'],
- 'chdata': chdata,
- 'parent': parent}
- sxe.addChild(name='new', attrs=attrs)
- self.session.connection.connection.send(message)
-
- def delete_whiteboard_node(self, rids):
- message = xmpp.Message(to=self.session.peerjid)
- sxe = message.addChild(name='sxe', attrs={'session': self.session.sid},
- namespace=NS_SXE)
-
- for x in rids:
- sxe.addChild(name='remove', attrs = {'target': x})
- self.session.connection.connection.send(message)
-
- def send_items(self, items, rids):
- # recieves dict items and a list of rids of items to send
- # TODO: is there a less clumsy way that doesn't involve passing
- # whole list
- self.send_whiteboard_node(items, rids)
-
- def del_item(self, rids):
- self.delete_whiteboard_node(rids)
-
- def encode(self, xml):
- # encodes it sendable string
- return 'data:text/xml,' + urllib.quote(xml)
-
- def _fill_content(self, content):
- content.addChild(NS_JINGLE_XHTML + ' description')
-
- def _stop(self, *things):
- pass
-
- def __del__(self):
- pass
-
-def get_content(desc):
- return JingleWhiteboard
-
-common.jingle_content.contents[NS_JINGLE_XHTML] = get_content
-
-class JingleTransportSXE(JingleTransport):
- def __init__(self):
- JingleTransport.__init__(self, TransportType.streaming)
-
- def make_transport(self, candidates=None):
- transport = JingleTransport.make_transport(self, candidates)
- transport.setNamespace(NS_JINGLE_SXE)
- transport.setTagData('host', 'TODO')
- return transport
-
-common.jingle_transport.transports[NS_JINGLE_SXE] = JingleTransportSXE
diff --git a/plugins/whiteboard/whiteboard.png b/plugins/whiteboard/whiteboard.png
deleted file mode 100644
index 13318e3a7..000000000
--- a/plugins/whiteboard/whiteboard.png
+++ /dev/null
Binary files differ
diff --git a/plugins/whiteboard/whiteboard_widget.py b/plugins/whiteboard/whiteboard_widget.py
deleted file mode 100644
index 2435ae1f6..000000000
--- a/plugins/whiteboard/whiteboard_widget.py
+++ /dev/null
@@ -1,418 +0,0 @@
-## plugins/whiteboard/whiteboard_widget.py
-##
-## Copyright (C) 2009 Jeff Ling <jeff.ummu AT gmail.com>
-## Copyright (C) 2010 Yann Leboulanger <asterix AT lagaule.org>
-##
-## This file is part of Gajim.
-##
-## Gajim is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published
-## by the Free Software Foundation; version 3 only.
-##
-## Gajim is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
-##
-
-import gtk
-import gtkgui_helpers
-try:
- import goocanvas
- HAS_GOOCANVAS = True
-except:
- HAS_GOOCANVAS = False
-from common.xmpp import Node
-from common import gajim
-from dialogs import FileChooserDialog
-
-'''
-A whiteboard widget made for Gajim.
-- Ummu
-'''
-
-class Whiteboard(object):
- def __init__(self, account, contact, session, plugin):
- self.plugin = plugin
- file_path = plugin.local_file_path('whiteboard_widget.ui')
- xml = gtk.Builder()
- xml.set_translation_domain('gajim_plugins')
- xml.add_from_file(file_path)
- self.hbox = xml.get_object('whiteboard_hbox')
- self.canevas = goocanvas.Canvas()
- self.hbox.pack_start(self.canevas)
- self.hbox.reorder_child(self.canevas, 0)
- self.canevas.set_flags(gtk.CAN_FOCUS)
- self.fg_color_select_button = xml.get_object('fg_color_button')
- self.root = self.canevas.get_root_item()
- self.tool_buttons = []
- for tool in ('brush', 'oval', 'line', 'delete'):
- self.tool_buttons.append(xml.get_object(tool + '_button'))
- xml.get_object('brush_button').set_active(True)
-
- # Events
- self.canevas.connect('button-press-event', self.button_press_event)
- self.canevas.connect('button-release-event', self.button_release_event)
- self.canevas.connect('motion-notify-event', self.motion_notify_event)
- self.canevas.connect('item-created', self.item_created)
-
- # Config
- self.line_width = 2
- xml.get_object('size_scale').set_value(2)
- self.color = str(self.fg_color_select_button.get_color())
-
- # SVG Storage
- self.image = SVGObject(self.root, session)
-
- xml.connect_signals(self)
-
- # Temporary Variables for items
- self.item_temp = None
- self.item_temp_coords = (0, 0)
- self.item_data = None
-
- # Will be {ID: {type:'element', data:[node, goocanvas]}, ID2: {}} instance
- self.recieving = {}
-
- def on_tool_button_toggled(self, widget):
- for btn in self.tool_buttons:
- if btn == widget:
- continue
- btn.set_active(False)
-
- def on_brush_button_toggled(self, widget):
- if widget.get_active():
- self.image.draw_tool = 'brush'
- self.on_tool_button_toggled(widget)
-
- def on_oval_button_toggled(self, widget):
- if widget.get_active():
- self.image.draw_tool = 'oval'
- self.on_tool_button_toggled(widget)
-
- def on_line_button_toggled(self, widget):
- if widget.get_active():
- self.image.draw_tool = 'line'
- self.on_tool_button_toggled(widget)
-
- def on_delete_button_toggled(self, widget):
- if widget.get_active():
- self.image.draw_tool = 'delete'
- self.on_tool_button_toggled(widget)
-
- def on_clear_button_clicked(self, widget):
- self.image.clear_canvas()
-
- def on_export_button_clicked(self, widget):
- SvgChooserDialog(self.image.export_svg)
-
- def on_fg_color_button_color_set(self, widget):
- self.color = str(self.fg_color_select_button.get_color())
-
- def item_created(self, canvas, item, model):
- print 'item created'
- item.connect('button-press-event', self.item_button_press_events)
-
- def item_button_press_events(self, item, target_item, event):
- if self.image.draw_tool == 'delete':
- self.image.del_item(item)
-
- def on_size_scale_format_value(self, widget):
- self.line_width = int(widget.get_value())
-
- def button_press_event(self, widget, event):
- x = event.x
- y = event.y
- state = event.state
- self.item_temp_coords = (x, y)
-
- if self.image.draw_tool == 'brush':
- self.item_temp = goocanvas.Ellipse(parent=self.root,
- center_x=x,
- center_y=y,
- radius_x=1,
- radius_y=1,
- stroke_color=self.color,
- fill_color=self.color,
- line_width=self.line_width)
- self.item_data = 'M %s,%s L ' % (x, y)
-
- elif self.image.draw_tool == 'oval':
- self.item_data = True
-
- if self.image.draw_tool == 'line':
- self.item_data = 'M %s,%s L' % (x, y)
-
- def motion_notify_event(self, widget, event):
- x = event.x
- y = event.y
- state = event.state
- if self.item_temp is not None:
- self.item_temp.remove()
-
- if self.item_data is not None:
- if self.image.draw_tool == 'brush':
- self.item_data = self.item_data + '%s,%s ' % (x, y)
- self.item_temp = goocanvas.Path(parent=self.root,
- data=self.item_data, line_width=self.line_width,
- stroke_color=self.color)
- elif self.image.draw_tool == 'oval':
- self.item_temp = goocanvas.Ellipse(parent=self.root,
- center_x=self.item_temp_coords[0] + (x - self.item_temp_coords[0]) / 2,
- center_y=self.item_temp_coords[1] + (y - self.item_temp_coords[1]) / 2,
- radius_x=abs(x - self.item_temp_coords[0]) / 2,
- radius_y=abs(y - self.item_temp_coords[1]) / 2,
- stroke_color=self.color,
- line_width=self.line_width)
- elif self.image.draw_tool == 'line':
- self.item_data = 'M %s,%s L' % self.item_temp_coords
- self.item_data = self.item_data + ' %s,%s' % (x, y)
- self.item_temp = goocanvas.Path(parent=self.root,
- data=self.item_data, line_width=self.line_width,
- stroke_color=self.color)
-
- def button_release_event(self, widget, event):
- x = event.x
- y = event.y
- state = event.state
-
- if self.image.draw_tool == 'brush':
- self.item_data = self.item_data + '%s,%s' % (x, y)
- if x == self.item_temp_coords[0] and y == self.item_temp_coords[1]:
- goocanvas.Ellipse(parent=self.root,
- center_x=x,
- center_y=y,
- radius_x=1,
- radius_y=1,
- stroke_color=self.color,
- fill_color=self.color,
- line_width=self.line_width)
- self.image.add_path(self.item_data, self.line_width, self.color)
-
- if self.image.draw_tool == 'oval':
- cx = self.item_temp_coords[0] + (x - self.item_temp_coords[0]) / 2
- cy = self.item_temp_coords[1] + (y - self.item_temp_coords[1]) / 2
- rx = abs(x - self.item_temp_coords[0]) / 2
- ry = abs(y - self.item_temp_coords[1]) / 2
- self.image.add_ellipse(cx, cy, rx, ry, self.line_width, self.color)
-
- if self.image.draw_tool == 'line':
- self.item_data = 'M %s,%s L' % self.item_temp_coords
- self.item_data = self.item_data + ' %s,%s' % (x, y)
- if x == self.item_temp_coords[0] and y == self.item_temp_coords[1]:
- goocanvas.Ellipse(parent=self.root,
- center_x=x,
- center_y=y,
- radius_x=1,
- radius_y=1,
- stroke_color='black',
- fill_color='black',
- line_width=self.line_width)
- self.image.add_path(self.item_data, self.line_width, self.color)
-
- if self.image.draw_tool == 'delete':
- pass
-
- self.item_data = None
- if self.item_temp is not None:
- self.item_temp.remove()
- self.item_temp = None
-
- def recieve_element(self, element):
- node = self.image.g.addChild(name=element.getAttr('name'))
- self.image.g.addChild(node=node)
- self.recieving[element.getAttr('rid')] = {'type':'element',
- 'data':[node],
- 'children':[]}
-
- def recieve_attr(self, element):
- node = self.recieving[element.getAttr('parent')]['data'][0]
- node.setAttr(element.getAttr('name'), element.getAttr('chdata'))
-
- self.recieving[element.getAttr('rid')] = {'type':'attr',
- 'data':element.getAttr('name'),
- 'parent':node}
- self.recieving[element.getAttr('parent')]['children'].append(element.getAttr('rid'))
-
- def apply_new(self):
- for x in self.recieving.keys():
- if self.recieving[x]['type'] == 'element':
- self.image.add_recieved(x, self.recieving)
-
- self.recieving = {}
-
-class SvgChooserDialog(FileChooserDialog):
- def __init__(self, on_response_ok=None, on_response_cancel=None):
- '''
- Choose in which SVG file to store the image
- '''
- def on_ok(widget, callback):
- '''
- check if file exists and call callback
- '''
- path_to_file = self.get_filename()
- path_to_file = gtkgui_helpers.decode_filechooser_file_paths(
- (path_to_file,))[0]
- widget.destroy()
- callback(path_to_file)
-
- FileChooserDialog.__init__(self,
- title_text=_('Save Image as...'),
- action=gtk.FILE_CHOOSER_ACTION_SAVE,
- buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN,
- gtk.RESPONSE_OK),
- current_folder='',
- default_response=gtk.RESPONSE_OK,
- on_response_ok=(on_ok, on_response_ok),
- on_response_cancel=on_response_cancel)
-
- filter_ = gtk.FileFilter()
- filter_.set_name(_('All files'))
- filter_.add_pattern('*')
- self.add_filter(filter_)
-
- filter_ = gtk.FileFilter()
- filter_.set_name(_('SVG Files'))
- filter_.add_pattern('*.svg')
- self.add_filter(filter_)
- self.set_filter(filter_)
-
-
-class SVGObject():
- ''' A class to store the svg document and make changes to it.'''
-
- def __init__(self, root, session, height=300, width=300):
- # Will be {ID: {type:'element', data:[node, goocanvas]}, ID2: {}} instance
- self.items = {}
- self.root = root
- self.draw_tool = 'brush'
-
- # sxe session
- self.session = session
-
- # initialize svg document
- self.svg = Node(node='<svg/>')
- self.svg.setAttr('version', '1.1')
- self.svg.setAttr('height', str(height))
- self.svg.setAttr('width', str(width))
- self.svg.setAttr('xmlns', 'http://www.w3.org/2000/svg')
- # TODO: make this settable
- self.g = self.svg.addChild(name='g')
- self.g.setAttr('fill', 'none')
- self.g.setAttr('stroke-linecap', 'round')
-
- def add_path(self, data, line_width, color):
- ''' adds the path to the items listing, both minidom node and goocanvas
- object in a tuple '''
-
- goocanvas_obj = goocanvas.Path(parent=self.root, data=data,
- line_width=line_width, stroke_color=color)
- goocanvas_obj.connect('button-press-event', self.item_button_press_events)
-
- node = self.g.addChild(name='path')
- node.setAttr('d', data)
- node.setAttr('stroke-width', str(line_width))
- node.setAttr('stroke', color)
- self.g.addChild(node=node)
-
- rids = self.session.generate_rids(4)
- self.items[rids[0]] = {'type':'element', 'data':[node, goocanvas_obj], 'children':rids[1:]}
- self.items[rids[1]] = {'type':'attr', 'data':'d', 'parent':node}
- self.items[rids[2]] = {'type':'attr', 'data':'stroke-width', 'parent':node}
- self.items[rids[3]] = {'type':'attr', 'data':'stroke', 'parent':node}
-
- self.session.send_items(self.items, rids)
-
- def add_recieved(self, parent_rid, new_items):
- ''' adds the path to the items listing, both minidom node and goocanvas
- object in a tuple '''
- node = new_items[parent_rid]['data'][0]
-
- self.items[parent_rid] = new_items[parent_rid]
- for x in new_items[parent_rid]['children']:
- self.items[x] = new_items[x]
-
- if node.getName() == 'path':
- goocanvas_obj = goocanvas.Path(parent=self.root,
- data=node.getAttr('d'),
- line_width=int(node.getAttr('stroke-width')),
- stroke_color=node.getAttr('stroke'))
-
- if node.getName() == 'ellipse':
- goocanvas_obj = goocanvas.Ellipse(parent=self.root,
- center_x=float(node.getAttr('cx')),
- center_y=float(node.getAttr('cy')),
- radius_x=float(node.getAttr('rx')),
- radius_y=float(node.getAttr('ry')),
- stroke_color=node.getAttr('stroke'),
- line_width=float(node.getAttr('stroke-width')))
-
- self.items[parent_rid]['data'].append(goocanvas_obj)
- goocanvas_obj.connect('button-press-event', self.item_button_press_events)
-
- def add_ellipse(self, cx, cy, rx, ry, line_width, stroke_color):
- ''' adds the ellipse to the items listing, both minidom node and goocanvas
- object in a tuple '''
-
- goocanvas_obj = goocanvas.Ellipse(parent=self.root,
- center_x=cx,
- center_y=cy,
- radius_x=rx,
- radius_y=ry,
- stroke_color=stroke_color,
- line_width=line_width)
- goocanvas_obj.connect('button-press-event', self.item_button_press_events)
-
- node = self.g.addChild(name='ellipse')
- node.setAttr('cx', str(cx))
- node.setAttr('cy', str(cy))
- node.setAttr('rx', str(rx))
- node.setAttr('ry', str(ry))
- node.setAttr('stroke-width', str(line_width))
- node.setAttr('stroke', stroke_color)
- self.g.addChild(node=node)
-
- rids = self.session.generate_rids(7)
- self.items[rids[0]] = {'type':'element', 'data':[node, goocanvas_obj], 'children':rids[1:]}
- self.items[rids[1]] = {'type':'attr', 'data':'cx', 'parent':node}
- self.items[rids[2]] = {'type':'attr', 'data':'cy', 'parent':node}
- self.items[rids[3]] = {'type':'attr', 'data':'rx', 'parent':node}
- self.items[rids[4]] = {'type':'attr', 'data':'ry', 'parent':node}
- self.items[rids[5]] = {'type':'attr', 'data':'stroke-width', 'parent':node}
- self.items[rids[6]] = {'type':'attr', 'data':'stroke', 'parent':node}
-
- self.session.send_items(self.items, rids)
-
- def del_item(self, item):
- rids = []
- for x in self.items.keys():
- if self.items[x]['type'] == 'element':
- if self.items[x]['data'][1] == item:
- for y in self.items[x]['children']:
- rids.append(y)
- self.del_rid(y)
- rids.append(x)
- self.del_rid(x)
- break
- self.session.del_item(rids)
-
- def clear_canvas(self):
- for x in self.items.keys():
- if self.items[x]['type'] == 'element':
- self.del_rid(x)
-
- def del_rid(self, rid):
- if self.items[rid]['type'] == 'element':
- self.items[rid]['data'][1].remove()
- del self.items[rid]
-
- def export_svg(self, filename):
- f = open(filename, 'w')
- f.writelines(str(self.svg))
- f.close()
-
- def item_button_press_events(self, item, target_item, event):
- self.del_item(item)
diff --git a/plugins/whiteboard/whiteboard_widget.ui b/plugins/whiteboard/whiteboard_widget.ui
deleted file mode 100644
index fddd2cb75..000000000
--- a/plugins/whiteboard/whiteboard_widget.ui
+++ /dev/null
@@ -1,192 +0,0 @@
-<?xml version="1.0"?>
-<interface>
- <requires lib="gtk+" version="2.16"/>
- <!-- interface-naming-policy project-wide -->
- <object class="GtkHBox" id="whiteboard_hbox">
- <property name="visible">True</property>
- <property name="border_width">3</property>
- <property name="spacing">6</property>
- <child>
- <placeholder/>
- </child>
- <child>
- <object class="GtkVBox" id="vbuttonbox1">
- <property name="visible">True</property>
- <property name="border_width">6</property>
- <property name="orientation">vertical</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkToggleButton" id="brush_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="tooltip_text" translatable="yes">Brush Tool: Draw freehand lines</property>
- <signal name="toggled" handler="on_brush_button_toggled"/>
- <child>
- <object class="GtkImage" id="image5">
- <property name="visible">True</property>
- <property name="stock">brush_tool</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkToggleButton" id="oval_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="tooltip_text" translatable="yes">Oval Tool: Draw circles and ellipses</property>
- <signal name="toggled" handler="on_oval_button_toggled"/>
- <child>
- <object class="GtkImage" id="image6">
- <property name="visible">True</property>
- <property name="stock">oval_tool</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkToggleButton" id="line_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="tooltip_text" translatable="yes">Line Tool: Draw straight lines</property>
- <signal name="toggled" handler="on_line_button_toggled"/>
- <child>
- <object class="GtkImage" id="image7">
- <property name="visible">True</property>
- <property name="stock">line_tool</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkToggleButton" id="delete_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="tooltip_text" translatable="yes">Delete Tool: Remove individual figures</property>
- <signal name="toggled" handler="on_delete_button_toggled"/>
- <child>
- <object class="GtkImage" id="image2">
- <property name="visible">True</property>
- <property name="stock">gtk-delete</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">3</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="clear_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="tooltip_text" translatable="yes">Clear Canvas: Cleanup canvas</property>
- <signal name="clicked" handler="on_clear_button_clicked"/>
- <child>
- <object class="GtkImage" id="image3">
- <property name="visible">True</property>
- <property name="stock">gtk-clear</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">4</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="export_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="tooltip_text" translatable="yes">Export Image: Save image to svg file</property>
- <signal name="clicked" handler="on_export_button_clicked"/>
- <child>
- <object class="GtkImage" id="image4">
- <property name="visible">True</property>
- <property name="stock">gtk-save-as</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">5</property>
- </packing>
- </child>
- <child>
- <object class="GtkVScale" id="size_scale">
- <property name="height_request">68</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="tooltip_text" translatable="yes">Line width</property>
- <property name="orientation">vertical</property>
- <property name="adjustment">adjustment1</property>
- <property name="inverted">True</property>
- <property name="digits">0</property>
- <property name="value_pos">bottom</property>
- <signal name="value_changed" handler="on_size_scale_format_value"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">6</property>
- </packing>
- </child>
- <child>
- <object class="GtkColorButton" id="fg_color_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="tooltip_text" translatable="yes">Foreground color</property>
- <property name="color">#000000000000</property>
- <signal name="color_set" handler="on_fg_color_button_color_set"/>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">7</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <object class="GtkImage" id="image1">
- <property name="visible">True</property>
- <property name="stock">gtk-delete</property>
- </object>
- <object class="GtkAdjustment" id="adjustment1">
- <property name="value">2</property>
- <property name="lower">1</property>
- <property name="upper">110</property>
- <property name="step_increment">1</property>
- <property name="page_increment">10</property>
- <property name="page_size">10</property>
- </object>
-</interface>