diff options
Diffstat (limited to 'develop-activity/toolbars.py')
-rw-r--r-- | develop-activity/toolbars.py | 350 |
1 files changed, 350 insertions, 0 deletions
diff --git a/develop-activity/toolbars.py b/develop-activity/toolbars.py new file mode 100644 index 0000000..7bee272 --- /dev/null +++ b/develop-activity/toolbars.py @@ -0,0 +1,350 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (C) 2006, Red Hat, Inc. +# Copyright (C) 2011, One Laptop Per Child +# Copyright (C) 2009, Tomeu Vizoso, Simon Schampijer +# +# 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. +# +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +from gi.repository import Gtk, Gdk +from gi.repository import GObject +from gettext import gettext as _ + +from sugar3.activity.widgets import EditToolbar +from sugar3.graphics import iconentry +from sugar3.graphics.toolbutton import ToolButton + +import sourceview_editor +S_WHERE = sourceview_editor.S_WHERE +SEARCH_ICONS = {False: {S_WHERE.selection: "search-in-selection", + S_WHERE.file: "system-search", + S_WHERE.multifile: "multi-search", + }, + True: {S_WHERE.selection: "regex-in-selection", + S_WHERE.file: "regex", + S_WHERE.multifile: "multi-regex", + }} + + +class DevelopViewToolbar(Gtk.Toolbar): + + def __init__(self, _activity): + self._activity = _activity + + # theme_toggler = ToggleToolButton() + + +class DevelopEditToolbar(EditToolbar): + + def __init__(self, _activity): + EditToolbar.__init__(self) + + self._activity = _activity + self._activity.editor.connect('changed', self._changed_cb) + self._changed_cb(None) + + self.undo.connect('clicked', self._undo_cb) + self.redo.connect('clicked', self._redo_cb) + self.copy.connect('clicked', self._copy_cb) + self.paste.connect('clicked', self._paste_cb) + + def _changed_cb(self, _buffer): + can_undo, can_redo = self._activity.editor.can_undo_redo() + self.undo.set_sensitive(can_undo) + self.redo.set_sensitive(can_redo) + + def _undo_cb(self, button): + self._activity.editor.undo() + self._changed_cb(None) + + def _redo_cb(self, button): + self._activity.editor.redo() + self._changed_cb(None) + + def _copy_cb(self, button): + self._activity.editor.copy() + + def _paste_cb(self, button): + self._activity.editor.paste() + + +class SearchOptions: + + def __init__(self, template=None, **kw): + if template: + self.__dict__ = template.__dict__.copy() + else: + self.__dict__ = {} + self.__dict__.update(kw) + + +class DevelopSearchToolbar(Gtk.Toolbar): + + def __init__(self, _activity): + GObject.GObject.__init__(self) + + self._activity = _activity + + # setup the search options + self.s_opts = SearchOptions( + where=S_WHERE.multifile, + use_regex=False, + ignore_caps=True, + replace_all=False, + #defaults to avoid creating + #a new SearchOptions object for normal searches + #should never be changed, just make a copy like: + #SearchOptions(self.s_opts, forward=False) + forward=True, + stay=False) + + self.safe_to_replace = False + + self._search_entry = iconentry.IconEntry() + self._search_entry.set_icon_from_name( + iconentry.ICON_ENTRY_PRIMARY, + SEARCH_ICONS[self.s_opts.use_regex][self.s_opts.where]) + + self._search_entry.add_clear_button() + self._search_entry.connect('activate', self._search_entry_activated_cb) + self._search_entry.connect('changed', self._search_entry_changed_cb) + self._add_widget(self._search_entry, expand=True) + + self._findprev = ToolButton('go-previous') + self._findprev.set_tooltip(_('Find previous')) + self.insert(self._findprev, -1) + self._findprev.show() + self._findprev.connect('clicked', self._findprev_cb) + + self._findnext = ToolButton('go-next') + self._findnext.set_tooltip(_('Find next')) + self.insert(self._findnext, -1) + self._findnext.show() + self._findnext.connect('clicked', self._findnext_cb) + + """ + self._settings = ToolButton(CAP_ICONS[self.s_opts.ignore_caps]) + self._settings.set_tooltip(_('Search settings')) + self.insert(self._settings, -1) + self._settings.show() + self._settings.connect('clicked', self._settings_cb) + + # Search settings menu + # This menu should attach to something else beside findnext - + #location is temporary. + palette = self._settings.get_palette() + sswo = self._set_where_options + ssho = self._set_how_options + ssco = self._set_cap_options + #TODO: move data structure to a member and the logic to a function + for name, function, options, icon in ( + (_('Ignore capitalization'), ssco, True, "ignore-caps"), + (_('Match capitalization'), ssco, False, "use-caps"), + (None, None, None, None), + (_('Search in selection'), sswo, S_WHERE.selection, + "search-in-selection"), + (_('Search in current file'), sswo, S_WHERE.file, + "system-search"), + (_('Search in all open files'), sswo, S_WHERE.multifile, + "multi-search"), + (None, None, None, None), + (_('Simple search'), ssho, False, "system-search"), + (_('Advanced search'), ssho, True, "regex"), + ): + if not name: + menuitem = Gtk.SeparatorMenuItem() + else: + menuitem = MenuItem(name, icon) + menuitem.connect('activate', function, options) + palette.menu.append(menuitem) + menuitem.show() + + # make expanded non-drawn visible separator to make the replace + #stuff right-align + separator = Gtk.SeparatorToolItem() + separator.props.draw = False + separator.set_expand(True) + self.insert(separator, -1) + separator.show() + + # replace entry + self._replace_entry = iconentry.IconEntry() + self._replace_entry.set_icon_from_name(iconentry.ICON_ENTRY_PRIMARY, + 'system-replace') + self._replace_entry.connect('changed', self._replace_entry_changed_cb) + self._replace_entry.add_clear_button() + self._add_widget(self._replace_entry, expand=True) + + #replace button + self._replace_button = ToolButton(REPLACE_ICONS[ + self.s_opts.replace_all]) + self._replace_button.set_tooltip(_('Replace')) + self.insert(self._replace_button, -1) + self._replace_button.show() + self._replace_button.connect('clicked', self._replace_cb) + + palette = self._replace_button.get_palette() + ssro = self._set_replace_options + #TODO: move data structure to a member and the logic to a function + for name, function, options, icon in ( + (_('Replace one'), ssro, False, "replace-and-find"), + (_('Replace all'), ssro, True, "multi-replace"), + ): + if not name: + menuitem = Gtk.SeparatorMenuItem() + else: + menuitem = MenuItem(name, icon) + menuitem.connect('activate', function, options) + palette.menu.append(menuitem) + menuitem.show() + """ + + self._activity.editor.connect('changed', self._changed_cb) + + self._activity.connect('key_press_event', self._on_key_press_event) + + def _on_key_press_event(self, widget, event): + keyname = Gdk.keyval_name(event.keyval) + if "F5" <= keyname and keyname <= "F8": + if keyname == "F5": + self._go_to_search_entry_cb() + elif keyname == "F6": + self._findprev_cb() + elif keyname == "F7": + self._findnext_cb() + elif keyname == "F8": + self._replace_or_go_to_replace_entry_cb() + return True + + def _go_to_search_entry_cb(self): + entry = self._search_entry + text = self._activity.editor.get_selected() + entry.grab_focus() + if text: + entry.delete_text(0, -1) + entry.insert_text(text) + entry.select_region(0, -1) + else: + entry.delete_text(0, 0) + entry.set_position(-1) + #for some reason, grab_focus doesn't work otherwise + + def _replace_or_go_to_replace_entry_cb(self): + if self.safe_to_replace: + self._replace_cb() + else: + self._replace_entry.select_region(0, -1) + self._replace_entry.grab_focus() + + def _reset_search_icons(self): + self._search_entry.set_icon_from_name( + iconentry.ICON_ENTRY_PRIMARY, + SEARCH_ICONS[self.s_opts.use_regex][self.s_opts.where]) + #self._settings.set_icon(CAP_ICONS[self.s_opts.ignore_caps]) + #self._replace_button.set_icon(REPLACE_ICONS[self.s_opts.replace_all]) + self._reset_replace_sensitivity() + + def _reset_replace_sensitivity(self): + pass + """ + self._replace_button.set_sensitive( + self.s_opts.where == S_WHERE.selection or self.s_opts.replace_all) + """ + + def _set_where_options(self, menu, option): + self.s_opts.where = option # IGNORE:W0201 + self._reset_search_icons() + + def _set_how_options(self, menu, option): + self.s_opts.use_regex = option # IGNORE:W0201 + self._reset_search_icons() + + def _set_cap_options(self, menu, option): + self.s_opts.ignore_caps = option # IGNORE:W0201 + self._reset_search_icons() + + def _set_replace_options(self, menu, option): + self.s_opts.replace_all = option # IGNORE:W0201 + if option and self.s_opts.where == S_WHERE.multifile: + self.s_opts.where = S_WHERE.file # for safety: + #do not replace all in multifile except explicitly + self._reset_search_icons() + + def _changed_cb(self, _buffer): + self._reset_replace_sensitivity() + #if self.s_opts.where == S_WHERE.selection: + # self._set_where_options(None, S_WHERE.file) + + def _settings_cb(self, button): + self._set_cap_options(None, not self.s_opts.ignore_caps) + + def _replace_cb(self, button=None): + pass + """ + ftext = self._search_entry.props.text + rtext = self._replace_entry.props.text + __replaced, found = self._activity.editor.replace(ftext, rtext, + self.s_opts) + if found: + self._replace_button.set_sensitive(True) + """ + + def _search_entry_activated_cb(self, entry): + text = self._search_entry.props.text + if text: + self._findnext_cb(None) + + def _search_entry_changed_cb(self, entry): + self.safe_to_replace = False + text = self._search_entry.props.text + if not text: + self._findprev.set_sensitive(False) + self._findnext.set_sensitive(False) + else: + self._findprev.set_sensitive(True) + self._findnext.set_sensitive(True) + if not self.s_opts.use_regex: + #do not do partial searches for regex + if self._activity.editor.find_next(text): + #no multifile, or focus gets grabbed + pass + #self._replace_button.set_sensitive(True) + + def _replace_entry_changed_cb(self, entry): + if self._replace_entry.props.text: + self.safe_to_replace = True + + def _findprev_cb(self, button=None): + ftext = self._search_entry.props.text + if ftext: + if self._activity.editor.find_next(ftext, direction='backward'): + pass + #self._replace_button.set_sensitive(True) + + def _findnext_cb(self, button=None): + ftext = self._search_entry.props.text + if ftext: + if self._activity.editor.find_next(ftext, direction='forward'): + pass + #self._replace_button.set_sensitive(True) + + # bad paul! this function was copied from sugar's activity.py via Write + def _add_widget(self, widget, expand=False): + tool_item = Gtk.ToolItem() + tool_item.set_expand(expand) + + tool_item.add(widget) + widget.show() + + self.insert(tool_item, -1) + tool_item.show() |