From e40381a498a1ce2cb6afc0412da699270f17ce77 Mon Sep 17 00:00:00 2001 From: Dan Krejsa Date: Tue, 10 Mar 2009 00:34:16 +0000 Subject: Add initial text search functionality. --- diff --git a/spock.py b/spock.py index 1a8a785..685dd42 100755 --- a/spock.py +++ b/spock.py @@ -114,7 +114,50 @@ class SpockScanner: if self.skip_expr() == ')': raise ghilbert.GhError('delimitError 3') return (start, self.i) - + +class SpockBuffer(gtksourceview2.Buffer): + + def __init__(self): + gtksourceview2.Buffer.__init__(self) + self.error_tag = self.create_tag("ErrorTag", background="yellow", + editable=False) + self.good_tag = self.create_tag("GoodTag", background="#e0ffe0") + self.search_tag = self.create_tag("search", foreground="white", background="blue") + + def search_end(self): + start, end = self.get_bounds() + self.remove_tag(self.search_tag, start, end) + + def search(self, text, forward): + start, end = self.get_bounds() + self.remove_tag(self.search_tag, start, end) + + insert_mark = self.get_insert() + it = self.get_iter_at_mark(insert_mark) + if forward: + if it.get_offset() == end.get_offset(): + it = start + ret = it.forward_search(text, gtk.TEXT_SEARCH_TEXT_ONLY) + if ret is None: + self.place_cursor(end) + return False + start, end = ret + it = end + else: + if it.get_offset() == 0: + it = end + ret = it.backward_search(text, gtk.TEXT_SEARCH_TEXT_ONLY) + if ret is None: + self.place_cursor(start) + return False + start, end = ret + it = start +## print "search: '%s' cursor %d start %d end %d\n" % \ +## (text[:10], it.get_offset(), start.get_offset(), end.get_offset()) + self.apply_tag(self.search_tag, start, end) + self.place_cursor(it) + return True + class Spock: @@ -322,6 +365,38 @@ class Spock: def verify_one_button_callback(self, widget, data=None): self.verify(True) + def find(self): + if not self.searching: + self.searching = True + self.statuslabel.set_text("") + self.search_entry.grab_focus() + else: + self.searching = False + self.source_buffer.search_end() + self.source_view.grab_focus() + + def search_op(self, forward): + self.searching = True + self.statuslabel.set_text("") + self.search_entry.grab_focus() + self.search_dir_forward = forward + sb = self.source_buffer + res = sb.search(self.search_entry.get_text(), forward) + self.source_view.scroll_mark_onscreen(sb.get_insert()) + if not res: + self.statuslabel.set_text(_("*** Text not found, will wrap ***")) + + def search_activate_callback(self, entry): + """ Search text entry activate callback """ + self.search_op(self.search_dir_forward) + + def search_lose_focus_callback(self, widget, event): + self.source_buffer.search_end() + +# def search_key_press_callback(self, widget, event): +# if event.string == '\x1b': +# self.source_view.grab_focus() + def addShortcutButton(self, box, name, expansion): button = gtk.Button(name) button.connect('clicked', self.shortcut_button_callback, name + ' ' + expansion) @@ -362,7 +437,8 @@ class Spock: def create_source_view(self): self.error_set = False - sb = gtksourceview2.Buffer() +# sb = gtksourceview2.Buffer() + sb = SpockBuffer() self.source_buffer = sb sv = gtksourceview2.View(sb) self.source_view = sv @@ -370,9 +446,8 @@ class Spock: pfont = pango.FontDescription("Monospace 10") sv.modify_font(pfont) sb.set_highlight_matching_brackets(True) - self.error_tag = sb.create_tag("ErrorTag", background="yellow", - editable=False) - self.good_tag = sb.create_tag("GoodTag", background="#e0ffe0") + self.error_tag = sb.error_tag + self.good_tag = sb.good_tag # good_offset marks the point up to which the text has been validated # correct self.good_offset = 0 @@ -436,10 +511,10 @@ class Spock: '(THM_NAME ((DVAR1 DVAR2 ...) ...) ((HYPNAME HYPEXPR) ...) (CONC ...) (PROOFSTEP ...))') self.addShortcutButton (hbox, 'def', '((DEF_TERMNAME VAR ...) DEF_EXPANSION)') - hbox.pack_start(gtk.VSeparator(), True, True, 0) - self.addShortcutButton (hbox, 'var', '(KIND VARNAME ...)') self.addShortcutButton (hbox, 'export', '(INTERFACE_NAME IFACE_FILE_URI (PARAMS ...) "")') + hbox.pack_start(gtk.VSeparator(), True, True, 0) + self.addShortcutButton (hbox, 'var', '(KIND VARNAME ...)') self.addShortcutButton (hbox, 'kindbind', '(KIND1 KIND2)') self.addShortcutButton (hbox, 'termbind', '(TERM_NAME1 TERM_NAME2)') @@ -468,6 +543,17 @@ class Spock: button.show() hbox.pack_start (button, expand=False) + self.search_dir_forward = True + self.searching = False + entry = gtk.Entry() + self.search_entry = entry + entry.set_width_chars (10) + entry.show() + entry.connect('activate', self.search_activate_callback) + entry.connect('focus-out-event', self.search_lose_focus_callback) +# entry.connect('key-press-event', self.search_key_press_callback) + hbox.pack_start (entry, expand=False) + self.statuslabel = gtk.Label('OK') self.statuslabel.set_alignment(1.0, 0.0) self.statuslabel.show() @@ -559,10 +645,17 @@ class SpockWindow(gtk.Window): actions = [ # Name, stock id, label, accelerator, tooltip, callback ("FileMenu", None, "_File", None, None, None), - ("FileSave", gtk.STOCK_SAVE, "_Save", "S", "Save work now", + ("FileSave", gtk.STOCK_SAVE, _("_Save"), _("S"), _("Save work now"), self.do_save), - ("FileQuit", gtk.STOCK_QUIT, "_Quit", "Q", "Q-Tip", - self.do_quit) + ("FileQuit", gtk.STOCK_QUIT, _("_Quit"), _("Q"), _("Q-Tip"), + self.do_quit), + ("EditMenu", None, "_Edit", None, None, None), + ("EditFind", gtk.STOCK_FIND, _("_Find"), _("F"), _("Find"), + self.do_search), + ("EditFindNext", gtk.STOCK_GO_DOWN, _(" _Next"), _("N"), _("Find next occurrence"), + self.do_search_forward), + ("EditFindPrevious", gtk.STOCK_GO_UP, _(" _Previous"), _("P"), _("Find previous occurrence"), + self.do_search_backward), ] g.add_actions(actions) @@ -576,6 +669,12 @@ class SpockWindow(gtk.Window): + + + + + + ''' @@ -617,6 +716,15 @@ class SpockWindow(gtk.Window): self.spock.write_file(self.spock.current_file) self.destroy(widget) + def do_search(self, widget): + self.spock.find() + + def do_search_forward(self, widget): + self.spock.search_op(True) + + def do_search_backward(self, widget): + self.spock.search_op(False) + def delete_event_cb(self, widget, event, data=None): logger.info("delete_event_cb") return False diff --git a/sugar_and_spock.py b/sugar_and_spock.py index aa08ae7..d882618 100644 --- a/sugar_and_spock.py +++ b/sugar_and_spock.py @@ -4,6 +4,7 @@ # ... and everything knock ;-) from sugar.activity import activity +from sugar.graphics.toolbutton import ToolButton import spock import gtk @@ -11,6 +12,47 @@ import ghilbert import sys, os, array from gettext import gettext as _ +class EditToolbar(gtk.Toolbar): + + def __init__(self, shpock): + gtk.Toolbar.__init__(self) + self.shpock = shpock + + # system-search + self.find = ToolButton('system-search') + self.find.set_tooltip(_('Find')) + self.insert(self.find, -1) + self.find.props.accelerator = _('F') + self.find.connect('clicked', self._find_cb) + self.find.show() + + # go-next + self.find_next = ToolButton('go-next') + self.find_next.set_tooltip(_('Find next occurrence')) + self.insert(self.find_next, -1) + self.find_next.props.accelerator = _('N') + self.find_next.connect('clicked', self._find_next_cb) + self.find_next.show() + + # go-previous + self.find_prev = ToolButton('go-previous') + self.find_prev.set_tooltip(_('Find previous occurrence')) + self.insert(self.find_prev, -1) + self.find_prev.props.accelerator = _('P') + self.find_prev.connect('clicked', self._find_prev_cb) + self.find_prev.show() + + def _find_next_cb(self, widget): + spock = self.shpock.spockObj + spock.search_op(True) + + def _find_prev_cb(self, widget): + spock = self.shpock.spockObj + spock.search_op(False) + + def _find_cb(self, widget): + spock = self.shpock.spockObj + spock.find() class Shpock(activity.Activity): @@ -28,6 +70,11 @@ class Shpock(activity.Activity): # bar that appears on every Sugar window and contains essential # functionalities, such as the 'Collaborate' and 'Close' buttons. toolbox = activity.ActivityToolbox(self) + + self._edit_toolbar = EditToolbar(self) + toolbox.add_toolbar(_('Edit'), self._edit_toolbar) + self._edit_toolbar.show() + self.set_toolbox(toolbox) toolbox.show() -- cgit v0.9.1