def __init__(self, buffer=None, width_in_chars=81, aspect_ratio=0.33, fdesc=None): _View.__init__(self, buffer=buffer if buffer else Buffer()) self._fdesc = fdesc if fdesc is not None else pango.FontDescription("mono 10") self.modify_font(self._fdesc) self._width_in_chars = width_in_chars self._aspect_ratio = aspect_ratio self._adjust_size_request()
def __init__(self, manager, editor): View.__init__(self, Buffer()) self.__init_attributes(manager, editor) self.__set_properties() self.__add_view_to_scrolled_window() self.__sigid1 = manager.connect("destroy", self.__destroy_cb) self.__sigid2 = manager.connect("description-treeview-sensitivity", self.__sensitive_cb) self.__sigid3 = manager.connect("description-treeview-cursor-changed", self.__changed_cb) self.__sigid4 = manager.connect("selected-templates-dictionary-key", self.__key_cb) self.__sigid5 = manager.connect("templates-dictionary", self.__dictionary_cb) self.__sigid6 = self.connect("button-press-event", self.__button_press_event_cb)
def _init (cls): def callback (widget, allocation): cls.widgets["enterGameNotationFrame"].set_size_request( 223, allocation.height-4) cls.widgets["enterGameNotationSidePanel"].connect_after("size-allocate", callback) flags = [] if isInstalled(): path = gettext.find("pychess") else: path = gettext.find("pychess", localedir=addDataPrefix("lang")) if path: loc = locale.getdefaultlocale()[0][-2:].lower() flags.append(addDataPrefix("flags/%s.png" % loc)) flags.append(addDataPrefix("flags/us.png")) cls.ib = ImageButton(flags) cls.widgets["imageButtonDock"].add(cls.ib) cls.ib.show() cls.sourcebuffer = SourceBuffer() sourceview = SourceView(cls.sourcebuffer) cls.widgets["scrolledwindow6"].add(sourceview) sourceview.show() # Pgn format does not allow tabulator sourceview.set_insert_spaces_instead_of_tabs(True) sourceview.set_wrap_mode(gtk.WRAP_WORD) man = LanguageManager() # Init new version if hasattr(man.props, 'search_path'): path = os.path.join(getDataPrefix(),"gtksourceview-1.0/language-specs") man.props.search_path = man.props.search_path + [path] if 'pgn' in man.get_language_ids(): lang = man.get_language('pgn') cls.sourcebuffer.set_language(lang) else: log.warn("Unable to load pgn syntax-highlighting.") cls.sourcebuffer.set_highlight_syntax(True) # Init old version else: os.environ["XDG_DATA_DIRS"] = getDataPrefix()+":/usr/share/" man = LanguageManager() for lang in man.get_available_languages(): if lang.get_name() == "PGN": cls.sourcebuffer.set_language(lang) break else: log.warn("Unable to load pgn syntax-highlighting.") cls.sourcebuffer.set_highlight(True)
def __init__(self, filename=None, text=None, title="View"): # Defining the main window window = gtk.Window(gtk.WINDOW_TOPLEVEL) window.set_resizable(True) window.connect("destroy", self.close_window, window) window.set_title(title) window.set_border_width(0) window.set_position(gtk.WIN_POS_CENTER) window.set_size_request(600, 400) #Creating a vertical box box = gtk.VBox(False, 10) box.set_border_width(10) window.add(box) box.show() # TODO add status bar where this message can be reported? if not HAVE_SOURCEVIEW or lang is None: print "UNABLE TO LOCATE ASCEND LANGUAGE DESCRIPTION for gtksourceview" #Creating a ScrolledWindow for the textview widget scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) view = MyView() view.set_editable(False) buff = MyBuffer() if HAVE_SOURCEVIEW: buff.set_language(lang) buff.set_highlight_syntax(True) view.set_buffer(buff) scroll.add(view) scroll.show() view.show() box.pack_start(scroll) if filename is not None: #Get the content of the file model = open(filename, "r") if model: string = model.read() model.close() buff.set_text(string) else: self.reporter.reportError("Error opening the file") elif text is not None: buff.set_text(text) else: buff.set_text("Nothing was selected") window.show()
def __init__(self, filename=None, text=None, title="View"): # Defining the main window window = gtk.Window(gtk.WINDOW_TOPLEVEL) window.set_resizable(True) window.connect("destroy", self.close_window, window) window.set_title(title) window.set_border_width(0) window.set_position(gtk.WIN_POS_CENTER) window.set_size_request(600,400) #Creating a vertical box box = gtk.VBox(False, 10) box.set_border_width(10) window.add(box) box.show() # TODO add status bar where this message can be reported? if not HAVE_SOURCEVIEW or lang is None: print "UNABLE TO LOCATE ASCEND LANGUAGE DESCRIPTION for gtksourceview" #Creating a ScrolledWindow for the textview widget scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) view = MyView() view.set_editable(False) buff = MyBuffer() if HAVE_SOURCEVIEW: buff.set_language(lang) buff.set_highlight_syntax(True) view.set_buffer(buff) scroll.add(view) scroll.show() view.show() box.pack_start(scroll) if filename is not None: #Get the content of the file model = open(filename, "r") if model: string = model.read() model.close() buff.set_text(string) else: self.reporter.reportError( "Error opening the file" ) elif text is not None: buff.set_text(text) else: buff.set_text("Nothing was selected") window.show()
def __init__(self, manager, editor): View.__init__(self, Buffer()) self.__init_attributes(manager, editor) self.__add_view_to_scrolled_window() self.__sigid1 = manager.connect("destroy", self.__destroy_cb) self.__sigid2 = manager.connect("valid-trigger", self.__valid_cb)
def __init__(self, filename=None, content=None, title=None, parent=None, autosave=False): gtk.Window.__init__(self, type=gtk.WINDOW_TOPLEVEL) vbox = gtk.VBox() self.add(vbox) self.__ui_string = """ <ui> <menubar name='Menubar'> <menu action='FileMenu'> <menuitem action='Save'/> <menuitem action='SaveAs'/> <separator/> <menuitem action='ReadOnly'/> <separator/> <menuitem action='Revert'/> <separator/> <menuitem action='Close'/> </menu> <menu action='EditMenu'> <menuitem action='Undo'/> <menuitem action='Redo'/> <separator/> <menuitem action='Find'/> <menuitem action='GotoLine'/> </menu> <menu action='ToolsMenu'> <menuitem action='About'/> </menu> </menubar> </ui> """ self.__create_ui() vbox.pack_start(self._ui.get_widget('/Menubar'), expand=False) self.__filename = os.path.abspath(filename) self.__autosave = autosave self.__modified = False self.__last_len = 0 self.__save_text_id = 0 self.gtksourceview_mode = gtksourceview_avail if gtksourceview_avail: self.input = SourceBuffer() self.input_view = SourceView(self.input) if gtksourceview2_avail: self.input.connect('notify::can-undo', lambda *args: self.__sync_undoredo()) self.input.connect('notify::can-redo', lambda *args: self.__sync_undoredo()) else: self.input.connect('can-undo', lambda *args: self.__sync_undoredo()) self.input.connect('can-redo', lambda *args: self.__sync_undoredo()) else: self.input = gtk.TextBuffer() self.input_view = gtk.TextView(self.input) self.input_view.set_wrap_mode(gtk.WRAP_WORD) self.input_view.connect("key-press-event", self.__handle_key_press_event) scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS) scroll.add(self.input_view) vbox.pack_start(scroll, True, True) if filename and os.path.isfile(self.__filename): _logger.debug("reading %s", self.__filename) f = open_text_file(self.__filename, 'r') self.__original_text = f.read() else: self.__original_text = content if self.__original_text: if gtksourceview_avail: self.input.begin_not_undoable_action() self.input.set_property('text', self.__original_text) self.__last_len = self.input.get_char_count() if gtksourceview_avail: self.input.end_not_undoable_action() self.input.move_mark_by_name('insert', self.input.get_start_iter()) self.input.move_mark_by_name('selection_bound', self.input.get_start_iter()) self.input.connect('mark-set', self.__on_mark_set) self.__searcharea = InlineSearchArea(self.input_view) self.__searcharea.connect('close', self.__on_search_close) self.__searcharea.show_all() self.__searcharea.hide() self.__searcharea.set_no_show_all(True) vbox.pack_start(self.__searcharea, expand=False) self.__status_hbox = gtk.HBox() self.__statusbar = gtk.Statusbar() self.__status_hbox.pack_start(self.__statusbar, expand=True) self.__statusbar_ctx = self.__statusbar.get_context_id("HotEditor") self.__pos_status = gtk.Statusbar() self.__pos_status.set_size_request(160, 10) # Taken from GEdit self.__pos_context = self.__pos_status.get_context_id("HotEditor") self.__status_hbox.pack_start(self.__pos_status, expand=False) vbox.pack_start(self.__status_hbox, expand=False) self.__sync_undoredo() self.__sync_modified_sensitivity() self.input.connect("changed", self.__handle_text_changed) self.connect("delete-event", self.__handle_delete_event) self.__sync_title() if parent: self.set_transient_for(parent) self.set_size_request(800, 600)
class HotEditorWindow(gtk.Window): def __init__(self, filename=None, content=None, title=None, parent=None, autosave=False): gtk.Window.__init__(self, type=gtk.WINDOW_TOPLEVEL) vbox = gtk.VBox() self.add(vbox) self.__ui_string = """ <ui> <menubar name='Menubar'> <menu action='FileMenu'> <menuitem action='Save'/> <menuitem action='SaveAs'/> <separator/> <menuitem action='ReadOnly'/> <separator/> <menuitem action='Revert'/> <separator/> <menuitem action='Close'/> </menu> <menu action='EditMenu'> <menuitem action='Undo'/> <menuitem action='Redo'/> <separator/> <menuitem action='Find'/> <menuitem action='GotoLine'/> </menu> <menu action='ToolsMenu'> <menuitem action='About'/> </menu> </menubar> </ui> """ self.__create_ui() vbox.pack_start(self._ui.get_widget('/Menubar'), expand=False) self.__filename = os.path.abspath(filename) self.__autosave = autosave self.__modified = False self.__last_len = 0 self.__save_text_id = 0 self.gtksourceview_mode = gtksourceview_avail if gtksourceview_avail: self.input = SourceBuffer() self.input_view = SourceView(self.input) if gtksourceview2_avail: self.input.connect('notify::can-undo', lambda *args: self.__sync_undoredo()) self.input.connect('notify::can-redo', lambda *args: self.__sync_undoredo()) else: self.input.connect('can-undo', lambda *args: self.__sync_undoredo()) self.input.connect('can-redo', lambda *args: self.__sync_undoredo()) else: self.input = gtk.TextBuffer() self.input_view = gtk.TextView(self.input) self.input_view.set_wrap_mode(gtk.WRAP_WORD) self.input_view.connect("key-press-event", self.__handle_key_press_event) scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS) scroll.add(self.input_view) vbox.pack_start(scroll, True, True) if filename and os.path.isfile(self.__filename): _logger.debug("reading %s", self.__filename) f = open_text_file(self.__filename, 'r') self.__original_text = f.read() else: self.__original_text = content if self.__original_text: if gtksourceview_avail: self.input.begin_not_undoable_action() self.input.set_property('text', self.__original_text) self.__last_len = self.input.get_char_count() if gtksourceview_avail: self.input.end_not_undoable_action() self.input.move_mark_by_name('insert', self.input.get_start_iter()) self.input.move_mark_by_name('selection_bound', self.input.get_start_iter()) self.input.connect('mark-set', self.__on_mark_set) self.__searcharea = InlineSearchArea(self.input_view) self.__searcharea.connect('close', self.__on_search_close) self.__searcharea.show_all() self.__searcharea.hide() self.__searcharea.set_no_show_all(True) vbox.pack_start(self.__searcharea, expand=False) self.__status_hbox = gtk.HBox() self.__statusbar = gtk.Statusbar() self.__status_hbox.pack_start(self.__statusbar, expand=True) self.__statusbar_ctx = self.__statusbar.get_context_id("HotEditor") self.__pos_status = gtk.Statusbar() self.__pos_status.set_size_request(160, 10) # Taken from GEdit self.__pos_context = self.__pos_status.get_context_id("HotEditor") self.__status_hbox.pack_start(self.__pos_status, expand=False) vbox.pack_start(self.__status_hbox, expand=False) self.__sync_undoredo() self.__sync_modified_sensitivity() self.input.connect("changed", self.__handle_text_changed) self.connect("delete-event", self.__handle_delete_event) self.__sync_title() if parent: self.set_transient_for(parent) self.set_size_request(800, 600) def __on_search_close(self, sa): self.__searcharea.hide() def set_read_only(self, readonly): readonly_toggle = self.__actiongroup.get_action('ReadOnly') readonly_toggle.set_active(readonly) def set_code_mode(self, codemode): if not self.gtksourceview_mode: return # Non-code is the default if not codemode: return self.input_view.modify_font(pango.FontDescription("monospace")) fs = Filesystem.getInstance() try: mimetype = fs.get_file_sync(self.__filename).mimetype except FileStatError, e: mimetype = None target_lang = None if gtksourceview2_avail: import gtksourceview2 langman = gtksourceview2.language_manager_get_default() for language_id in langman.get_language_ids(): language = langman.get_language(language_id) for langmime in language.get_mime_types(): if mimetype == langmime: target_lang = language break if target_lang: break self.input.set_highlight_syntax(True) else: import gtksourceview target_lang = gtksourceview.SourceLanguagesManager( ).get_language_from_mime_type(mimetype) self.input.set_highlight(True) if target_lang: self.input.set_language(target_lang)
def __init_attributes(self, editor): self.__editor = editor from gtksourceview2 import View, Buffer self.__view = View(Buffer()) return
class View(object): def __init__(self, editor): self.__init_attributes(editor) self.__add_view_to_scroll() self.__set_properties() self.__sigid1 = editor.connect("quit", self.__quit_cb) self.__sigid2 = editor.connect("checking-file", self.__update_cb) self.__sigid3 = editor.connect_after("load-error", self.__update_cb) self.__sigid4 = editor.connect("renamed-file", self.__update_cb) editor.register_object(self) def __init_attributes(self, editor): self.__editor = editor from gtksourceview2 import View, Buffer self.__view = View(Buffer()) return def __destroy(self): self.__editor.disconnect_signal(self.__sigid1, self.__editor) self.__editor.disconnect_signal(self.__sigid2, self.__editor) self.__editor.disconnect_signal(self.__sigid3, self.__editor) self.__editor.disconnect_signal(self.__sigid4, self.__editor) self.__editor.unregister_object(self) del self return False def __set_properties(self): from gtk import DEST_DEFAULT_ALL targets = [("text/uri-list", 0, 80)] from gtk.gdk import ACTION_COPY self.__view.set_pixels_above_lines(2) self.__view.set_pixels_below_lines(2) self.__view.set_pixels_inside_wrap(2) self.__view.drag_dest_set(DEST_DEFAULT_ALL, targets, ACTION_COPY) self.__view.drag_dest_add_text_targets() self.__view.set_property("can-focus", True) self.__view.set_property("auto-indent", True) self.__view.set_property("highlight-current-line", True) self.__view.set_property("show-line-numbers", True) self.__view.set_property("indent-width", -1) from gtksourceview2 import SMART_HOME_END_BEFORE self.__view.set_property("smart-home-end", SMART_HOME_END_BEFORE) self.__update_view() self.__view.set_property("sensitive", True) return False def __update_view(self): language = self.__editor.language language = language if language else "plain text" from SCRIBES.TabWidthMetadata import get_value as tab_width self.__view.set_property("tab-width", tab_width(language)) from SCRIBES.MarginPositionMetadata import get_value as margin_position self.__view.set_property("right-margin-position", margin_position(language)) from SCRIBES.DisplayRightMarginMetadata import get_value as show_margin self.__view.set_property("show-right-margin", show_margin(language)) from SCRIBES.UseTabsMetadata import get_value as use_tabs self.__view.set_property("insert-spaces-instead-of-tabs",(not use_tabs(language))) from SCRIBES.FontMetadata import get_value as font_name from pango import FontDescription font = FontDescription(font_name(language)) self.__view.modify_font(font) from gtk import WRAP_WORD_CHAR, WRAP_NONE from SCRIBES.TextWrappingMetadata import get_value as wrap_mode_bool wrap_mode = self.__view.set_wrap_mode wrap_mode(WRAP_WORD_CHAR) if wrap_mode_bool(language) else wrap_mode(WRAP_NONE) self.__view.grab_focus() return False def __add_view_to_scroll(self): swin = self.__editor.gui.get_widget("ScrolledWindow") swin.add(self.__view) swin.show_all() self.__view.grab_focus() return False def __quit_cb(self, *args): self.__destroy() return False def __update_cb(self, *args): from gobject import idle_add idle_add(self.__update_view) return False
class HotEditorWindow(gtk.Window): def __init__(self, filename=None, content=None, title=None, parent=None, autosave=False): gtk.Window.__init__(self, type=gtk.WINDOW_TOPLEVEL) vbox = gtk.VBox() self.add(vbox) self.__ui_string = """ <ui> <menubar name='Menubar'> <menu action='FileMenu'> <menuitem action='Save'/> <menuitem action='SaveAs'/> <separator/> <menuitem action='ReadOnly'/> <separator/> <menuitem action='Revert'/> <separator/> <menuitem action='Close'/> </menu> <menu action='EditMenu'> <menuitem action='Undo'/> <menuitem action='Redo'/> <separator/> <menuitem action='Find'/> <menuitem action='GotoLine'/> </menu> <menu action='ToolsMenu'> <menuitem action='About'/> </menu> </menubar> </ui> """ self.__create_ui() vbox.pack_start(self._ui.get_widget('/Menubar'), expand=False) self.__filename = os.path.abspath(filename) self.__autosave = autosave self.__modified = False self.__last_len = 0 self.__save_text_id = 0 self.gtksourceview_mode = gtksourceview_avail if gtksourceview_avail: self.input = SourceBuffer() self.input_view = SourceView(self.input) if gtksourceview2_avail: self.input.connect('notify::can-undo', lambda *args: self.__sync_undoredo()) self.input.connect('notify::can-redo', lambda *args: self.__sync_undoredo()) else: self.input.connect('can-undo', lambda *args: self.__sync_undoredo()) self.input.connect('can-redo', lambda *args: self.__sync_undoredo()) else: self.input = gtk.TextBuffer() self.input_view = gtk.TextView(self.input) self.input_view.set_wrap_mode(gtk.WRAP_WORD) self.input_view.connect("key-press-event", self.__handle_key_press_event) scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS) scroll.add(self.input_view) vbox.pack_start(scroll, True, True) if filename and os.path.isfile(self.__filename): _logger.debug("reading %s", self.__filename) f = open_text_file(self.__filename, 'r') self.__original_text = f.read() else: self.__original_text = content if self.__original_text: if gtksourceview_avail: self.input.begin_not_undoable_action() self.input.set_property('text', self.__original_text) self.__last_len = self.input.get_char_count() if gtksourceview_avail: self.input.end_not_undoable_action() self.input.move_mark_by_name('insert', self.input.get_start_iter()) self.input.move_mark_by_name('selection_bound', self.input.get_start_iter()) self.input.connect('mark-set', self.__on_mark_set) self.__searcharea = InlineSearchArea(self.input_view) self.__searcharea.connect('close', self.__on_search_close) self.__searcharea.show_all() self.__searcharea.hide() self.__searcharea.set_no_show_all(True) vbox.pack_start(self.__searcharea, expand=False) self.__status_hbox = gtk.HBox() self.__statusbar = gtk.Statusbar() self.__status_hbox.pack_start(self.__statusbar, expand=True) self.__statusbar_ctx = self.__statusbar.get_context_id("HotEditor") self.__pos_status = gtk.Statusbar() self.__pos_status.set_size_request(160, 10) # Taken from GEdit self.__pos_context = self.__pos_status.get_context_id("HotEditor") self.__status_hbox.pack_start(self.__pos_status, expand=False) vbox.pack_start(self.__status_hbox, expand=False) self.__sync_undoredo() self.__sync_modified_sensitivity() self.input.connect("changed", self.__handle_text_changed) self.connect("delete-event", self.__handle_delete_event) self.__sync_title() if parent: self.set_transient_for(parent) self.set_size_request(800, 600) def __on_search_close(self, sa): self.__searcharea.hide() def set_read_only(self, readonly): readonly_toggle = self.__actiongroup.get_action('ReadOnly') readonly_toggle.set_active(readonly) def set_code_mode(self, codemode): if not self.gtksourceview_mode: return # Non-code is the default if not codemode: return self.input_view.modify_font(pango.FontDescription("monospace")) fs = Filesystem.getInstance() try: mimetype = fs.get_file_sync(self.__filename).mimetype except FileStatError, e: mimetype = None target_lang = None if gtksourceview2_avail: import gtksourceview2 langman = gtksourceview2.language_manager_get_default() for language_id in langman.get_language_ids(): language = langman.get_language(language_id) for langmime in language.get_mime_types(): if mimetype == langmime: target_lang = language break if target_lang: break self.input.set_highlight_syntax(True) else: import gtksourceview target_lang = gtksourceview.SourceLanguagesManager().get_language_from_mime_type(mimetype) self.input.set_highlight(True) if target_lang: self.input.set_language(target_lang)
class View(object): def __init__(self, editor): self.__init_attributes(editor) self.__add_view_to_scroll() self.__set_properties() self.__sigid1 = editor.connect("quit", self.__quit_cb) self.__sigid2 = editor.connect("checking-file", self.__update_cb) self.__sigid3 = editor.connect_after("load-error", self.__update_cb) self.__sigid4 = editor.connect("renamed-file", self.__update_cb) editor.register_object(self) def __init_attributes(self, editor): self.__editor = editor from gtksourceview2 import View, Buffer self.__view = View(Buffer()) return def __destroy(self): self.__editor.disconnect_signal(self.__sigid1, self.__editor) self.__editor.disconnect_signal(self.__sigid2, self.__editor) self.__editor.disconnect_signal(self.__sigid3, self.__editor) self.__editor.disconnect_signal(self.__sigid4, self.__editor) self.__editor.unregister_object(self) del self return False def __set_properties(self): from gtk import DEST_DEFAULT_ALL targets = [("text/uri-list", 0, 80)] from gtk.gdk import ACTION_COPY self.__view.set_pixels_above_lines(2) self.__view.set_pixels_below_lines(2) self.__view.set_pixels_inside_wrap(2) self.__view.drag_dest_set(DEST_DEFAULT_ALL, targets, ACTION_COPY) self.__view.drag_dest_add_text_targets() self.__view.set_property("can-focus", True) self.__view.set_property("auto-indent", True) self.__view.set_property("highlight-current-line", True) self.__view.set_property("show-line-numbers", True) self.__view.set_property("indent-width", -1) from gtksourceview2 import SMART_HOME_END_BEFORE self.__view.set_property("smart-home-end", SMART_HOME_END_BEFORE) self.__update_view() self.__view.set_property("sensitive", True) return False def __update_view(self): language = self.__editor.language language = language if language else "plain text" from SCRIBES.TabWidthMetadata import get_value as tab_width self.__view.set_property("tab-width", tab_width(language)) from SCRIBES.MarginPositionMetadata import get_value as margin_position self.__view.set_property("right-margin-position", margin_position(language)) from SCRIBES.DisplayRightMarginMetadata import get_value as show_margin self.__view.set_property("show-right-margin", show_margin(language)) from SCRIBES.UseTabsMetadata import get_value as use_tabs self.__view.set_property("insert-spaces-instead-of-tabs", (not use_tabs(language))) from SCRIBES.FontMetadata import get_value as font_name from pango import FontDescription font = FontDescription(font_name(language)) self.__view.modify_font(font) from gtk import WRAP_WORD_CHAR, WRAP_NONE from SCRIBES.TextWrappingMetadata import get_value as wrap_mode_bool wrap_mode = self.__view.set_wrap_mode wrap_mode(WRAP_WORD_CHAR) if wrap_mode_bool(language) else wrap_mode( WRAP_NONE) self.__view.grab_focus() return False def __add_view_to_scroll(self): swin = self.__editor.gui.get_widget("ScrolledWindow") swin.add(self.__view) swin.show_all() self.__view.grab_focus() return False def __quit_cb(self, *args): self.__destroy() return False def __update_cb(self, *args): from gobject import idle_add idle_add(self.__update_view) return False
class HotEditorWindow(gtk.Window): def __init__(self, filename=None, content=None, title=None, parent=None, autosave=False): gtk.Window.__init__(self, type=gtk.WINDOW_TOPLEVEL) vbox = gtk.VBox() self.add(vbox) self.__ui_string = """ <ui> <menubar name='Menubar'> <menu action='FileMenu'> <menuitem action='Save'/> <menuitem action='SaveAs'/> <separator/> <menuitem action='ReadOnly'/> <separator/> <menuitem action='Revert'/> <separator/> <menuitem action='Close'/> </menu> <menu action='EditMenu'> <menuitem action='Undo'/> <menuitem action='Redo'/> <separator/> <menuitem action='Find'/> <menuitem action='GotoLine'/> </menu> <menu action='ToolsMenu'> <menuitem action='About'/> </menu> </menubar> </ui> """ self.__create_ui() vbox.pack_start(self._ui.get_widget('/Menubar'), expand=False) self.__filename = os.path.abspath(filename) self.__autosave = autosave self.__modified = False self.__last_len = 0 self.__save_text_id = 0 self.gtksourceview_mode = gtksourceview_avail if gtksourceview_avail: self.input = SourceBuffer() self.input_view = SourceView(self.input) if gtksourceview2_avail: self.input.connect('notify::can-undo', lambda *args: self.__sync_undoredo()) self.input.connect('notify::can-redo', lambda *args: self.__sync_undoredo()) else: self.input.connect('can-undo', lambda *args: self.__sync_undoredo()) self.input.connect('can-redo', lambda *args: self.__sync_undoredo()) else: self.input = gtk.TextBuffer() self.input_view = gtk.TextView(self.input) self.input_view.set_wrap_mode(gtk.WRAP_WORD) self.input_view.connect("key-press-event", self.__handle_key_press_event) scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS) scroll.add(self.input_view) vbox.pack_start(scroll, True, True) if filename and os.path.isfile(self.__filename): _logger.debug("reading %s", self.__filename) f = open_text_file(self.__filename, 'r') self.__original_text = f.read() else: self.__original_text = content if self.__original_text: if gtksourceview_avail: self.input.begin_not_undoable_action() self.input.set_property('text', self.__original_text) self.__last_len = self.input.get_char_count() if gtksourceview_avail: self.input.end_not_undoable_action() self.input.move_mark_by_name('insert', self.input.get_start_iter()) self.input.move_mark_by_name('selection_bound', self.input.get_start_iter()) self.input.connect('mark-set', self.__on_mark_set) self.__searcharea = InlineSearchArea(self.input_view) self.__searcharea.connect('close', self.__on_search_close) self.__searcharea.show_all() self.__searcharea.hide() self.__searcharea.set_no_show_all(True) vbox.pack_start(self.__searcharea, expand=False) self.__status_hbox = gtk.HBox() self.__statusbar = gtk.Statusbar() self.__status_hbox.pack_start(self.__statusbar, expand=True) self.__statusbar_ctx = self.__statusbar.get_context_id("HotEditor") self.__pos_status = gtk.Statusbar() self.__pos_status.set_size_request(160, 10) # Taken from GEdit self.__pos_context = self.__pos_status.get_context_id("HotEditor") self.__status_hbox.pack_start(self.__pos_status, expand=False) vbox.pack_start(self.__status_hbox, expand=False) self.__sync_undoredo() self.__sync_modified_sensitivity() self.input.connect("changed", self.__handle_text_changed) self.connect("delete-event", self.__handle_delete_event) self.__sync_title() if parent: self.set_transient_for(parent) self.set_size_request(800, 600) def __on_search_close(self, sa): self.__searcharea.hide() def set_read_only(self, readonly): readonly_toggle = self.__actiongroup.get_action('ReadOnly') readonly_toggle.set_active(readonly) def set_code_mode(self, codemode): if not self.gtksourceview_mode: return # Non-code is the default if not codemode: return self.input_view.modify_font(pango.FontDescription("monospace")) fs = Filesystem.getInstance() try: mimetype = fs.get_file_sync(self.__filename).mimetype except FileStatError as e: mimetype = None target_lang = None if gtksourceview2_avail: import gtksourceview2 langman = gtksourceview2.language_manager_get_default() for language_id in langman.get_language_ids(): language = langman.get_language(language_id) for langmime in language.get_mime_types(): if mimetype == langmime: target_lang = language break if target_lang: break self.input.set_highlight_syntax(True) else: import gtksourceview target_lang = gtksourceview.SourceLanguagesManager().get_language_from_mime_type(mimetype) self.input.set_highlight(True) if target_lang: self.input.set_language(target_lang) def goto_line(self, lineno): iter = self.input.get_iter_at_line(lineno) self.input.place_cursor(iter) def __sync_title(self): if self.__filename: (dn, bn) = os.path.split(self.__filename) self.set_title('%s (%s)' % (bn,dn)) else: self.set_title('Untitled') def __show_msg(self, text): id = self.__statusbar.push(self.__statusbar_ctx, text) gobject.timeout_add(3000, lambda: self.__statusbar.remove(self.__statusbar_ctx, id)) def __do_save(self, status): if self.__save_text_id > 0: gobject.source_remove(self.__save_text_id) if not self.__modified: self.__show_msg(_("Already saved")) return self.__idle_save_text(status) @log_except(_logger) def __idle_save_text(self, status): self.__save_text_id = 0 _logger.debug("autosaving to %s", self.__filename) dn,bn = os.path.split(self.__filename) try: perms = os.stat(self.__filename).st_mode except: perms = None (tempfd, temppath) = tempfile.mkstemp('.tmp', self.__filename, dn) os.close(tempfd) f = open_text_file(temppath, 'w') text = self.input.get_property("text") utext = str(text) f.write(utext) f.flush() os.fsync(tempfd) f.close() if perms is not None: os.chmod(temppath, perms) atomic_rename(temppath, self.__filename) self.__show_msg(status + _("...done")) self.__modified = False self.__sync_modified_sensitivity() _logger.debug("autosave complete") return False def __handle_key_press_event(self, input_view, event): # <Control>Return is the most natural keybinding for save-and-close, but support # <Control>w for compat. This doesn't replicate all the complicated multiple-groups # handling that would goes on inside GTK+, but that's OK for a compatibility crutch if event.state & gtk.gdk.CONTROL_MASK != 0 and event.keyval in (gtk.keysyms.w, gtk.keysyms.W): self.__handle_close() return True if event.keyval == gtk.keysyms.Escape: self.__handle_close() return True return False def __on_mark_set(self, buf, iter, mark): cursor = buf.get_insert() if cursor != mark: return self.__pos_status.pop(self.__pos_context) ln = iter.get_line() col = iter.get_line_offset() self.__pos_status.push(self.__pos_context, _('Ln %d, Col %d') % (ln, col)) def __handle_text_changed(self, text): _logger.debug("handling text changed") self.__modified = True self.__sync_modified_sensitivity() if not (self.__filename and self.__autosave): return charcount = text.get_char_count() # Don't autosave on deletions if charcount < self.__last_len: return self.__last_len = charcount if self.__save_text_id != 0: gobject.source_remove(self.__save_text_id) self.__save_text_id = gobject.timeout_add(15000, self.__idle_save_text, _("Autosaving")) @log_except(_logger) def __revert_cb(self, action): self.__handle_revert() def __handle_revert(self): self.input.set_property('text', self.__original_text) @log_except(_logger) def __save_cb(self, action): self.__do_save(_("Saving...")) @log_except(_logger) def __save_as_cb(self, action): chooser = gtk.FileChooserDialog(_("Save As..."), self, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK)) chooser.set_default_response(gtk.RESPONSE_OK) response = chooser.run() filename = None if response == gtk.RESPONSE_OK: filename = chooser.get_filename() self.__filename = filename chooser.destroy() def __handle_delete_event(self, w, e): return self.__handle_close() @log_except(_logger) def __close_cb(self, action): self.__handle_close() def __sync_modified_sensitivity(self): self.__actiongroup.get_action('Save').set_sensitive(self.__modified) @log_except(_logger) def __handle_close(self): _logger.debug("got close") if not self.__modified: self.destroy() elif self.__filename and self.__autosave: self.__save_cb(None) self.destroy() else: dialog = gtk.MessageDialog(parent=self, buttons=gtk.BUTTONS_NONE, type=gtk.MESSAGE_QUESTION, message_format=_("Save changes before closing?")) dialog.add_button(_('Close without saving'), gtk.RESPONSE_REJECT) dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) dialog.add_button(gtk.STOCK_SAVE, gtk.RESPONSE_APPLY) dialog.set_default_response(gtk.RESPONSE_CANCEL) resp = dialog.run() dialog.destroy() if resp == gtk.RESPONSE_REJECT: self.destroy() elif resp == gtk.RESPONSE_CANCEL: pass elif resp == gtk.RESPONSE_APPLY: self.__save_cb(None) self.destroy() return True @log_except(_logger) def __undo_cb(self, action): self.input.undo() @log_except(_logger) def __redo_cb(self, action): self.input.redo() def __sync_undoredo(self): self.__actiongroup.get_action('Redo').set_sensitive(gtksourceview_avail and self.input.can_redo()) self.__actiongroup.get_action('Undo').set_sensitive(gtksourceview_avail and self.input.can_undo()) @log_except(_logger) def __search_cb(self, a): self.__searcharea.show() self.__searcharea.focus() @log_except(_logger) def __goto_line_cb(self, a): dlg = GotoLineDialog(self) line_num = dlg.run_get_line() dlg.destroy() if line_num is None: return iter = self.input.get_iter_at_line(line_num) self.input.place_cursor(iter) self.input_view.scroll_mark_onscreen(self.input.get_mark('insert')) @log_except(_logger) def __toggle_read_only_cb(self, a): active = a.get_active() self.input_view.set_editable(not active) def __create_ui(self): self.__actiongroup = ag = gtk.ActionGroup('WindowActions') actions = [ ('FileMenu', None, _('_File')), ('Save', gtk.STOCK_SAVE, _('_Save'), '<control>s', _('Save to current file'), self.__save_cb), ('SaveAs', gtk.STOCK_SAVE, _('Save _As'), '<control><shift>s', _('Save to a new file'), self.__save_as_cb), ('Revert', None, '_Revert', None, _('Revert to saved text'), self.__revert_cb), ('Close', gtk.STOCK_CLOSE, _('_Close'), '<control>Return', _('Save and close'), self.__close_cb), ('EditMenu', None, '_Edit'), ('Undo', gtk.STOCK_UNDO, _('_Undo'), '<control>z', _('Undo previous action'), self.__undo_cb), ('Redo', gtk.STOCK_REDO, _('_Redo'), '<control><shift>Z', _('Redo action'), self.__redo_cb), ('Find', gtk.STOCK_FIND, _('_Find'), '<control>f', _('Find text'), self.__search_cb), ('GotoLine', gtk.STOCK_JUMP_TO, _('_Go to Line'), '<control>l', _('Jump to line number'), self.__goto_line_cb), ('ToolsMenu', None, _('_Tools')), ('About', gtk.STOCK_ABOUT, _('_About'), None, _('About Hotwire'), self.__help_about_cb), ] toggle_actions = [ ('ReadOnly', None, _('Read _Only'), None, _('Toggle read-only mode'), self.__toggle_read_only_cb), ] ag.add_actions(actions) ag.add_toggle_actions(toggle_actions) self._ui = gtk.UIManager() self._ui.insert_action_group(ag, 0) self._ui.add_ui_from_string(self.__ui_string) self.add_accel_group(self._ui.get_accel_group()) def __help_about_cb(self, action): dialog = HotwireAboutDialog() dialog.run() dialog.destroy()
def _on_document_added(self, model, idx, content): view = View() view.show() lang = self._language_manager.get_language("gobject-creator") buf = Buffer(language=lang) buf.set_highlight_syntax(True) view.set_buffer(buf) view.set_auto_indent(True) view.set_show_line_numbers(Settings.get().show_line_numbers) font_desc = pango.FontDescription(Settings.get().font_name) view.modify_font(font_desc) doc_container = gtk.ScrolledWindow() doc_container.show() doc_container.add(view) hbox = gtk.HBox() hbox.show() label = gtk.Label("") label.show() hbox.pack_start(label) close_button = gtk.Button() image = gtk.Image() image.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_MENU) close_button.set_image(image) close_button.set_relief(gtk.RELIEF_NONE) close_button.show() hbox.pack_start(close_button) self._notebook.insert_page(doc_container, hbox, idx ) self._notebook.set_current_page(idx) view.connect("button_press_event", self._on_button_pressed ) close_button.connect( "clicked", self._on_close_button_clicked ) buf = view.get_buffer() buf.connect( "changed", self._on_buffer_changed ) self._set_document_title(idx) buf.set_text(content)
class HotEditorWindow(gtk.Window): def __init__(self, filename=None, content=None, title=None, parent=None, autosave=False): gtk.Window.__init__(self, type=gtk.WINDOW_TOPLEVEL) vbox = gtk.VBox() self.add(vbox) self.__ui_string = """ <ui> <menubar name='Menubar'> <menu action='FileMenu'> <menuitem action='Save'/> <menuitem action='SaveAs'/> <separator/> <menuitem action='ReadOnly'/> <separator/> <menuitem action='Revert'/> <separator/> <menuitem action='Close'/> </menu> <menu action='EditMenu'> <menuitem action='Undo'/> <menuitem action='Redo'/> <separator/> <menuitem action='Find'/> <menuitem action='GotoLine'/> </menu> <menu action='ToolsMenu'> <menuitem action='About'/> </menu> </menubar> </ui> """ self.__create_ui() vbox.pack_start(self._ui.get_widget('/Menubar'), expand=False) self.__filename = os.path.abspath(filename) self.__autosave = autosave self.__modified = False self.__last_len = 0 self.__save_text_id = 0 self.gtksourceview_mode = gtksourceview_avail if gtksourceview_avail: self.input = SourceBuffer() self.input_view = SourceView(self.input) if gtksourceview2_avail: self.input.connect('notify::can-undo', lambda *args: self.__sync_undoredo()) self.input.connect('notify::can-redo', lambda *args: self.__sync_undoredo()) else: self.input.connect('can-undo', lambda *args: self.__sync_undoredo()) self.input.connect('can-redo', lambda *args: self.__sync_undoredo()) else: self.input = gtk.TextBuffer() self.input_view = gtk.TextView(self.input) self.input_view.set_wrap_mode(gtk.WRAP_WORD) self.input_view.connect("key-press-event", self.__handle_key_press_event) scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS) scroll.add(self.input_view) vbox.pack_start(scroll, True, True) if filename and os.path.isfile(self.__filename): _logger.debug("reading %s", self.__filename) f = open_text_file(self.__filename, 'r') self.__original_text = f.read() else: self.__original_text = content if self.__original_text: if gtksourceview_avail: self.input.begin_not_undoable_action() self.input.set_property('text', self.__original_text) self.__last_len = self.input.get_char_count() if gtksourceview_avail: self.input.end_not_undoable_action() self.input.move_mark_by_name('insert', self.input.get_start_iter()) self.input.move_mark_by_name('selection_bound', self.input.get_start_iter()) self.input.connect('mark-set', self.__on_mark_set) self.__searcharea = InlineSearchArea(self.input_view) self.__searcharea.connect('close', self.__on_search_close) self.__searcharea.show_all() self.__searcharea.hide() self.__searcharea.set_no_show_all(True) vbox.pack_start(self.__searcharea, expand=False) self.__status_hbox = gtk.HBox() self.__statusbar = gtk.Statusbar() self.__status_hbox.pack_start(self.__statusbar, expand=True) self.__statusbar_ctx = self.__statusbar.get_context_id("HotEditor") self.__pos_status = gtk.Statusbar() self.__pos_status.set_size_request(160, 10) # Taken from GEdit self.__pos_context = self.__pos_status.get_context_id("HotEditor") self.__status_hbox.pack_start(self.__pos_status, expand=False) vbox.pack_start(self.__status_hbox, expand=False) self.__sync_undoredo() self.__sync_modified_sensitivity() self.input.connect("changed", self.__handle_text_changed) self.connect("delete-event", self.__handle_delete_event) self.__sync_title() if parent: self.set_transient_for(parent) self.set_size_request(800, 600) def __on_search_close(self, sa): self.__searcharea.hide() def set_read_only(self, readonly): readonly_toggle = self.__actiongroup.get_action('ReadOnly') readonly_toggle.set_active(readonly) def set_code_mode(self, codemode): if not self.gtksourceview_mode: return # Non-code is the default if not codemode: return self.input_view.modify_font(pango.FontDescription("monospace")) fs = Filesystem.getInstance() try: mimetype = fs.get_file_sync(self.__filename).mimetype except FileStatError as e: mimetype = None target_lang = None if gtksourceview2_avail: import gtksourceview2 langman = gtksourceview2.language_manager_get_default() for language_id in langman.get_language_ids(): language = langman.get_language(language_id) for langmime in language.get_mime_types(): if mimetype == langmime: target_lang = language break if target_lang: break self.input.set_highlight_syntax(True) else: import gtksourceview target_lang = gtksourceview.SourceLanguagesManager( ).get_language_from_mime_type(mimetype) self.input.set_highlight(True) if target_lang: self.input.set_language(target_lang) def goto_line(self, lineno): iter = self.input.get_iter_at_line(lineno) self.input.place_cursor(iter) def __sync_title(self): if self.__filename: (dn, bn) = os.path.split(self.__filename) self.set_title('%s (%s)' % (bn, dn)) else: self.set_title('Untitled') def __show_msg(self, text): id = self.__statusbar.push(self.__statusbar_ctx, text) gobject.timeout_add( 3000, lambda: self.__statusbar.remove(self.__statusbar_ctx, id)) def __do_save(self, status): if self.__save_text_id > 0: gobject.source_remove(self.__save_text_id) if not self.__modified: self.__show_msg(_("Already saved")) return self.__idle_save_text(status) @log_except(_logger) def __idle_save_text(self, status): self.__save_text_id = 0 _logger.debug("autosaving to %s", self.__filename) dn, bn = os.path.split(self.__filename) try: perms = os.stat(self.__filename).st_mode except: perms = None (tempfd, temppath) = tempfile.mkstemp('.tmp', self.__filename, dn) os.close(tempfd) f = open_text_file(temppath, 'w') text = self.input.get_property("text") utext = str(text) f.write(utext) f.flush() os.fsync(tempfd) f.close() if perms is not None: os.chmod(temppath, perms) atomic_rename(temppath, self.__filename) self.__show_msg(status + _("...done")) self.__modified = False self.__sync_modified_sensitivity() _logger.debug("autosave complete") return False def __handle_key_press_event(self, input_view, event): # <Control>Return is the most natural keybinding for save-and-close, but support # <Control>w for compat. This doesn't replicate all the complicated multiple-groups # handling that would goes on inside GTK+, but that's OK for a compatibility crutch if event.state & gtk.gdk.CONTROL_MASK != 0 and event.keyval in ( gtk.keysyms.w, gtk.keysyms.W): self.__handle_close() return True if event.keyval == gtk.keysyms.Escape: self.__handle_close() return True return False def __on_mark_set(self, buf, iter, mark): cursor = buf.get_insert() if cursor != mark: return self.__pos_status.pop(self.__pos_context) ln = iter.get_line() col = iter.get_line_offset() self.__pos_status.push(self.__pos_context, _('Ln %d, Col %d') % (ln, col)) def __handle_text_changed(self, text): _logger.debug("handling text changed") self.__modified = True self.__sync_modified_sensitivity() if not (self.__filename and self.__autosave): return charcount = text.get_char_count() # Don't autosave on deletions if charcount < self.__last_len: return self.__last_len = charcount if self.__save_text_id != 0: gobject.source_remove(self.__save_text_id) self.__save_text_id = gobject.timeout_add(15000, self.__idle_save_text, _("Autosaving")) @log_except(_logger) def __revert_cb(self, action): self.__handle_revert() def __handle_revert(self): self.input.set_property('text', self.__original_text) @log_except(_logger) def __save_cb(self, action): self.__do_save(_("Saving...")) @log_except(_logger) def __save_as_cb(self, action): chooser = gtk.FileChooserDialog(_("Save As..."), self, gtk.FILE_CHOOSER_ACTION_SAVE, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE, gtk.RESPONSE_OK)) chooser.set_default_response(gtk.RESPONSE_OK) response = chooser.run() filename = None if response == gtk.RESPONSE_OK: filename = chooser.get_filename() self.__filename = filename chooser.destroy() def __handle_delete_event(self, w, e): return self.__handle_close() @log_except(_logger) def __close_cb(self, action): self.__handle_close() def __sync_modified_sensitivity(self): self.__actiongroup.get_action('Save').set_sensitive(self.__modified) @log_except(_logger) def __handle_close(self): _logger.debug("got close") if not self.__modified: self.destroy() elif self.__filename and self.__autosave: self.__save_cb(None) self.destroy() else: dialog = gtk.MessageDialog( parent=self, buttons=gtk.BUTTONS_NONE, type=gtk.MESSAGE_QUESTION, message_format=_("Save changes before closing?")) dialog.add_button(_('Close without saving'), gtk.RESPONSE_REJECT) dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) dialog.add_button(gtk.STOCK_SAVE, gtk.RESPONSE_APPLY) dialog.set_default_response(gtk.RESPONSE_CANCEL) resp = dialog.run() dialog.destroy() if resp == gtk.RESPONSE_REJECT: self.destroy() elif resp == gtk.RESPONSE_CANCEL: pass elif resp == gtk.RESPONSE_APPLY: self.__save_cb(None) self.destroy() return True @log_except(_logger) def __undo_cb(self, action): self.input.undo() @log_except(_logger) def __redo_cb(self, action): self.input.redo() def __sync_undoredo(self): self.__actiongroup.get_action('Redo').set_sensitive( gtksourceview_avail and self.input.can_redo()) self.__actiongroup.get_action('Undo').set_sensitive( gtksourceview_avail and self.input.can_undo()) @log_except(_logger) def __search_cb(self, a): self.__searcharea.show() self.__searcharea.focus() @log_except(_logger) def __goto_line_cb(self, a): dlg = GotoLineDialog(self) line_num = dlg.run_get_line() dlg.destroy() if line_num is None: return iter = self.input.get_iter_at_line(line_num) self.input.place_cursor(iter) self.input_view.scroll_mark_onscreen(self.input.get_mark('insert')) @log_except(_logger) def __toggle_read_only_cb(self, a): active = a.get_active() self.input_view.set_editable(not active) def __create_ui(self): self.__actiongroup = ag = gtk.ActionGroup('WindowActions') actions = [ ('FileMenu', None, _('_File')), ('Save', gtk.STOCK_SAVE, _('_Save'), '<control>s', _('Save to current file'), self.__save_cb), ('SaveAs', gtk.STOCK_SAVE, _('Save _As'), '<control><shift>s', _('Save to a new file'), self.__save_as_cb), ('Revert', None, '_Revert', None, _('Revert to saved text'), self.__revert_cb), ('Close', gtk.STOCK_CLOSE, _('_Close'), '<control>Return', _('Save and close'), self.__close_cb), ('EditMenu', None, '_Edit'), ('Undo', gtk.STOCK_UNDO, _('_Undo'), '<control>z', _('Undo previous action'), self.__undo_cb), ('Redo', gtk.STOCK_REDO, _('_Redo'), '<control><shift>Z', _('Redo action'), self.__redo_cb), ('Find', gtk.STOCK_FIND, _('_Find'), '<control>f', _('Find text'), self.__search_cb), ('GotoLine', gtk.STOCK_JUMP_TO, _('_Go to Line'), '<control>l', _('Jump to line number'), self.__goto_line_cb), ('ToolsMenu', None, _('_Tools')), ('About', gtk.STOCK_ABOUT, _('_About'), None, _('About Hotwire'), self.__help_about_cb), ] toggle_actions = [ ('ReadOnly', None, _('Read _Only'), None, _('Toggle read-only mode'), self.__toggle_read_only_cb), ] ag.add_actions(actions) ag.add_toggle_actions(toggle_actions) self._ui = gtk.UIManager() self._ui.insert_action_group(ag, 0) self._ui.add_ui_from_string(self.__ui_string) self.add_accel_group(self._ui.get_accel_group()) def __help_about_cb(self, action): dialog = HotwireAboutDialog() dialog.run() dialog.destroy()