diff options
Diffstat (limited to 'Speak.activity/chatbox.py')
-rw-r--r-- | Speak.activity/chatbox.py | 348 |
1 files changed, 0 insertions, 348 deletions
diff --git a/Speak.activity/chatbox.py b/Speak.activity/chatbox.py deleted file mode 100644 index f9fb2fd..0000000 --- a/Speak.activity/chatbox.py +++ /dev/null @@ -1,348 +0,0 @@ -# This program 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; either version 2 of the License, or -# (at your option) any later version. -# -# This program 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 this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -# This code is a stripped down version of the Chat - -import gtk -import hippo -import logging -import pango -import re -from datetime import datetime -from gobject import SIGNAL_RUN_FIRST, TYPE_PYOBJECT -from gettext import gettext as _ - -import sugar.graphics.style as style -from sugar.graphics.roundbox import CanvasRoundBox -from sugar.graphics.palette import Palette, CanvasInvoker -from sugar.presence import presenceservice -from sugar.graphics.style import (Color, COLOR_BLACK, COLOR_WHITE) -from sugar.graphics.menuitem import MenuItem -from sugar.activity.activity import get_activity_root - -logger = logging.getLogger('speak') - -URL_REGEXP = re.compile('((http|ftp)s?://)?' - '(([-a-zA-Z0-9]+[.])+[-a-zA-Z0-9]{2,}|([0-9]{1,3}[.]){3}[0-9]{1,3})' - '(:[1-9][0-9]{0,4})?(/[-a-zA-Z0-9/%~@&_+=;:,.?#]*[a-zA-Z0-9/])?') - -class ChatBox(hippo.CanvasScrollbars): - def __init__(self): - hippo.CanvasScrollbars.__init__(self) - - self.owner = presenceservice.get_instance().get_owner() - - # Auto vs manual scrolling: - self._scroll_auto = True - self._scroll_value = 0.0 - self._last_msg_sender = None - # Track last message, to combine several messages: - self._last_msg = None - self._chat_log = '' - - self._conversation = hippo.CanvasBox( - spacing=0, - background_color=COLOR_WHITE.get_int()) - - self.set_policy(hippo.ORIENTATION_HORIZONTAL, - hippo.SCROLLBAR_NEVER) - self.set_root(self._conversation) - - vadj = self.props.widget.get_vadjustment() - vadj.connect('changed', self._scroll_changed_cb) - vadj.connect('value-changed', self._scroll_value_changed_cb) - - def get_log(self): - return self._chat_log - - def add_text(self, buddy, text, status_message=False): - """Display text on screen, with name and colors. - - buddy -- buddy object or dict {nick: string, color: string} - (The dict is for loading the chat log from the journal, - when we don't have the buddy object any more.) - text -- string, what the buddy said - status_message -- boolean - False: show what buddy said - True: show what buddy did - - hippo layout: - .------------- rb ---------------. - | +name_vbox+ +----msg_vbox----+ | - | | | | | | - | | nick: | | +--msg_hbox--+ | | - | | | | | text | | | - | +---------+ | +------------+ | | - | | | | - | | +--msg_hbox--+ | | - | | | text | url | | | - | | +------------+ | | - | +----------------+ | - `--------------------------------' - """ - if not buddy: - buddy = self.owner - - if type(buddy) is dict: - # dict required for loading chat log from journal - nick = buddy['nick'] - color = buddy['color'] - else: - nick = buddy.props.nick - color = buddy.props.color - try: - color_stroke_html, color_fill_html = color.split(',') - except ValueError: - color_stroke_html, color_fill_html = ('#000000', '#888888') - - # Select text color based on fill color: - color_fill_rgba = Color(color_fill_html).get_rgba() - color_fill_gray = (color_fill_rgba[0] + color_fill_rgba[1] + - color_fill_rgba[2])/3 - color_stroke = Color(color_stroke_html).get_int() - color_fill = Color(color_fill_html).get_int() - - if color_fill_gray < 0.5: - text_color = COLOR_WHITE.get_int() - else: - text_color = COLOR_BLACK.get_int() - - self._add_log(nick, color, text, status_message) - - # Check for Right-To-Left languages: - if pango.find_base_dir(nick, -1) == pango.DIRECTION_RTL: - lang_rtl = True - else: - lang_rtl = False - - # Check if new message box or add text to previous: - new_msg = True - if self._last_msg_sender: - if not status_message: - if buddy == self._last_msg_sender: - # Add text to previous message - new_msg = False - - if not new_msg: - rb = self._last_msg - msg_vbox = rb.get_children()[1] - msg_hbox = hippo.CanvasBox( - orientation=hippo.ORIENTATION_HORIZONTAL) - msg_vbox.append(msg_hbox) - else: - rb = CanvasRoundBox(background_color=color_fill, - border_color=color_stroke, - padding=4) - rb.props.border_color = color_stroke # Bug #3742 - self._last_msg = rb - self._last_msg_sender = buddy - if not status_message: - name = hippo.CanvasText(text=nick+': ', - color=text_color) - name_vbox = hippo.CanvasBox( - orientation=hippo.ORIENTATION_VERTICAL) - name_vbox.append(name) - rb.append(name_vbox) - msg_vbox = hippo.CanvasBox( - orientation=hippo.ORIENTATION_VERTICAL) - rb.append(msg_vbox) - msg_hbox = hippo.CanvasBox( - orientation=hippo.ORIENTATION_HORIZONTAL) - msg_vbox.append(msg_hbox) - - if status_message: - self._last_msg_sender = None - - match = URL_REGEXP.search(text) - while match: - # there is a URL in the text - starttext = text[:match.start()] - if starttext: - message = hippo.CanvasText( - text=starttext, - size_mode=hippo.CANVAS_SIZE_WRAP_WORD, - color=text_color, - xalign=hippo.ALIGNMENT_START) - msg_hbox.append(message) - url = text[match.start():match.end()] - - message = CanvasLink( - text=url, - color=text_color) - attrs = pango.AttrList() - attrs.insert(pango.AttrUnderline(pango.UNDERLINE_SINGLE, 0, 32767)) - message.set_property("attributes", attrs) - message.connect('activated', self._link_activated_cb) - - # call interior magic which should mean just: - # CanvasInvoker().parent = message - CanvasInvoker(message) - - msg_hbox.append(message) - text = text[match.end():] - match = URL_REGEXP.search(text) - - if text: - message = hippo.CanvasText( - text=text, - size_mode=hippo.CANVAS_SIZE_WRAP_WORD, - color=text_color, - xalign=hippo.ALIGNMENT_START) - msg_hbox.append(message) - - # Order of boxes for RTL languages: - if lang_rtl: - msg_hbox.reverse() - if new_msg: - rb.reverse() - - if new_msg: - box = hippo.CanvasBox(padding=2) - box.append(rb) - self._conversation.append(box) - - def _scroll_value_changed_cb(self, adj, scroll=None): - """Turn auto scrolling on or off. - - If the user scrolled up, turn it off. - If the user scrolled to the bottom, turn it back on. - """ - if adj.get_value() < self._scroll_value: - self._scroll_auto = False - elif adj.get_value() == adj.upper-adj.page_size: - self._scroll_auto = True - - def _scroll_changed_cb(self, adj, scroll=None): - """Scroll the chat window to the bottom""" - if self._scroll_auto: - adj.set_value(adj.upper-adj.page_size) - self._scroll_value = adj.get_value() - - def _link_activated_cb(self, link): - url = url_check_protocol(link.props.text) - self._show_via_journal(url) - - def _show_via_journal(self, url): - """Ask the journal to display a URL""" - import os - import time - from sugar import profile - from sugar.activity.activity import show_object_in_journal - from sugar.datastore import datastore - logger.debug('Create journal entry for URL: %s', url) - jobject = datastore.create() - metadata = { - 'title': "%s: %s" % (_('URL from Chat'), url), - 'title_set_by_user': '1', - 'icon-color': profile.get_color().to_string(), - 'mime_type': 'text/uri-list', - } - for k,v in metadata.items(): - jobject.metadata[k] = v - file_path = os.path.join(get_activity_root(), 'instance', - '%i_' % time.time()) - open(file_path, 'w').write(url + '\r\n') - os.chmod(file_path, 0755) - jobject.set_file_path(file_path) - datastore.write(jobject) - show_object_in_journal(jobject.object_id) - jobject.destroy() - os.unlink(file_path) - - def _add_log(self, nick, color, text, status_message): - """Add the text to the chat log. - - nick -- string, buddy nickname - color -- string, buddy.props.color - text -- string, body of message - status_message -- boolean - """ - if not nick: - nick = '???' - if not color: - color = '#000000,#FFFFFF' - if not text: - text = '-' - if not status_message: - status_message = False - self._chat_log += '%s\t%s\t%s\t%d\t%s\n' % ( - datetime.strftime(datetime.now(), '%b %d %H:%M:%S'), - nick, color, status_message, text) - -class CanvasLink(hippo.CanvasLink): - def __init__(self, **kwargs): - hippo.CanvasLink.__init__(self, **kwargs) - - def create_palette(self): - return URLMenu(self.props.text) - -class URLMenu(Palette): - def __init__(self, url): - Palette.__init__(self, url) - - self.url = url_check_protocol(url) - - menu_item = MenuItem(_('Copy to Clipboard'), 'edit-copy') - menu_item.connect('activate', self._copy_to_clipboard_cb) - self.menu.append(menu_item) - menu_item.show() - - def create_palette(self): - pass - - def _copy_to_clipboard_cb(self, menuitem): - logger.debug('Copy %s to clipboard', self.url) - clipboard = gtk.clipboard_get() - targets = [("text/uri-list", 0, 0), - ("UTF8_STRING", 0, 1)] - - if not clipboard.set_with_data(targets, - self._clipboard_data_get_cb, - self._clipboard_clear_cb, - (self.url)): - logger.error('GtkClipboard.set_with_data failed!') - else: - self.owns_clipboard = True - - def _clipboard_data_get_cb(self, clipboard, selection, info, data): - logger.debug('_clipboard_data_get_cb data=%s target=%s', data, - selection.target) - if selection.target in ['text/uri-list']: - if not selection.set_uris([data]): - logger.debug('failed to set_uris') - else: - logger.debug('not uri') - if not selection.set_text(data): - logger.debug('failed to set_text') - - def _clipboard_clear_cb(self, clipboard, data): - logger.debug('clipboard_clear_cb') - self.owns_clipboard = False - -def url_check_protocol(url): - """Check that the url has a protocol, otherwise prepend https:// - - url -- string - - Returns url -- string - """ - protocols = ['http://', 'https://', 'ftp://', 'ftps://'] - no_protocol = True - for protocol in protocols: - if url.startswith(protocol): - no_protocol = False - if no_protocol: - url = 'http://' + url - return url - |