Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGonzalo Odiard <godiard@gmail.com>2014-09-19 02:21:42 (GMT)
committer Gonzalo Odiard <godiard@gmail.com>2014-09-19 02:21:42 (GMT)
commit0031c938d369df5492aea3abe202a3df8280caef (patch)
tree7921e67021318b60998bd3d5e766325b7c528126
parente40924288954679b718fe000c51a29c2e398a148 (diff)
Initial version of tag editor widgetHEADmaster
-rw-r--r--tag_editor.py146
1 files changed, 146 insertions, 0 deletions
diff --git a/tag_editor.py b/tag_editor.py
new file mode 100644
index 0000000..a2a2984
--- /dev/null
+++ b/tag_editor.py
@@ -0,0 +1,146 @@
+import logging
+import os
+from gettext import gettext as _
+
+from gi.repository import Gtk
+from gi.repository import Gdk
+from gi.repository import GObject
+from gi.repository import Pango
+
+from sugar3.graphics.palette import WidgetInvoker
+from sugar3.graphics.palette import Palette
+from sugar3.graphics.palettemenu import PaletteMenuBox
+from sugar3.graphics.palettemenu import PaletteMenuItem
+from sugar3.graphics import style
+
+LONG_TEXT = 'This is a text with tags'
+
+TAG_LIST = ['#art', '#math', '#love', '#robots']
+
+TIMEOUT = 500
+
+
+class TextViewInvoker(WidgetInvoker):
+
+ def __init__(self, textview):
+ WidgetInvoker.__init__(self, textview)
+ self._textview = textview
+
+ def get_rect(self):
+ loc_strong, _loc_weak = self._textview.get_cursor_locations(None)
+
+ rect = Gdk.Rectangle()
+ rect.x = loc_strong.x
+ rect.y = loc_strong.y + loc_strong.height * 2
+ rect.width = loc_strong.width
+ rect.height = loc_strong.height
+ return rect
+
+ def has_rectangle_gap(self):
+ return False
+
+
+class TagEditor(Gtk.TextView):
+
+ def __init__(self, text, tag_list):
+ Gtk.TextView.__init__(self)
+ text_buffer = Gtk.TextBuffer()
+ self._test_hid = None
+ text_buffer.set_text(text)
+ self.set_buffer(text_buffer)
+
+ self._palette_invoker = TextViewInvoker(self)
+ self._palette_invoker.attach(self)
+ self.connect('destroy', self.__destroy_cb)
+
+ text_buffer.connect('changed', self.__buffer_changed_cb)
+ self.connect('move-cursor', self.__move_cursor_cb)
+
+ def __destroy_cb(self, icon):
+ if self._palette_invoker is not None:
+ self._palette_invoker.detach()
+
+ def __buffer_changed_cb(self, text_buffer):
+ self._delayed_word_test()
+
+ def __move_cursor_cb(self, text_view, step, count, extended_selection):
+ self._delayed_word_test()
+
+ def _delayed_word_test(self):
+ if self._test_hid is not None:
+ GObject.source_remove(self._test_hid)
+ self._test_hid = GObject.timeout_add(TIMEOUT, self._real_word_test)
+
+ def _real_word_test(self):
+ tbuffer = self.get_buffer()
+ cursor_position = tbuffer.props.cursor_position
+ text = tbuffer.get_text(
+ tbuffer.get_start_iter(), tbuffer.get_end_iter(), False)
+ if cursor_position == len(text):
+ if text[cursor_position - 1] == '#':
+ self._show_menu()
+ else:
+ previous_space = text.rfind(' ', 0, cursor_position)
+ if text[previous_space + 1] == '#':
+ self._show_menu()
+
+ def _show_menu(self):
+ logging.error('Show menu ')
+ if self._palette_invoker is not None:
+ self._palette = Palette(_('Select tag'))
+ menu_box = PaletteMenuBox()
+ self._palette.set_content(menu_box)
+ menu_box.show()
+ for tag in TAG_LIST:
+ menu_item = PaletteMenuItem()
+ menu_item.set_label(tag)
+ menu_item.connect('activate', self._add_tag, tag)
+ menu_box.append_item(menu_item)
+ menu_item.show()
+
+ self._palette_invoker.set_palette(self._palette)
+ self._palette.popup(immediate=True)
+
+ def _add_tag(self, menu, tag):
+ # probably this is not the best way to replace the word
+ tbuffer = self.get_buffer()
+ cursor_position = tbuffer.props.cursor_position
+ text = tbuffer.get_text(
+ tbuffer.get_start_iter(), tbuffer.get_end_iter(), False)
+
+ bold_tag = tbuffer.create_tag('b', weight=Pango.Weight.BOLD)
+ if cursor_position == len(text):
+ start_iter = tbuffer.get_iter_at_offset(len(text) - 2)
+ end_iter = tbuffer.get_end_iter()
+ else:
+ previous_space = text.rfind(' ', 0, cursor_position)
+ next_space = text.find(' ', cursor_position)
+ start_iter = tbuffer.get_iter_at_offset(previous_space)
+ end_iter = tbuffer.get_iter_at_offset(next_space)
+
+ tbuffer.delete(start_iter, end_iter)
+ tbuffer.insert_with_tags(start_iter, tag, bold_tag)
+
+
+win = Gtk.Window()
+box = Gtk.VBox()
+
+# setup theme, copied form sugar main.py
+settings = Gtk.Settings.get_default()
+sugar_theme = 'sugar-72'
+if 'SUGAR_SCALING' in os.environ:
+ if os.environ['SUGAR_SCALING'] == '100':
+ sugar_theme = 'sugar-100'
+settings.set_property('gtk-theme-name', sugar_theme)
+settings.set_property('gtk-icon-theme-name', 'sugar')
+# icons_path = os.path.join(config.data_path, 'icons')
+# Gtk.IconTheme.get_default().append_search_path(icons_path)
+
+label = TagEditor(LONG_TEXT, TAG_LIST)
+
+box.add(label)
+win.add(box)
+
+win.connect("delete-event", Gtk.main_quit)
+win.show_all()
+Gtk.main()