From 966312ba98d729177238f4663d789a789663eb2e Mon Sep 17 00:00:00 2001 From: root Date: Sat, 30 Oct 2010 19:36:14 +0000 Subject: start working on release 7, include all new files, breakpoints still need work --- (limited to 'editor_gui.py') diff --git a/editor_gui.py b/editor_gui.py new file mode 100644 index 0000000..a0637ef --- /dev/null +++ b/editor_gui.py @@ -0,0 +1,396 @@ +#!/usr/bin/env python +# Copyright (C) 2009, George Hunt +# Copyright (C) 2009, One Laptop Per Child +# +# 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 + +from __future__ import with_statement + +#major packages +import os, shutil, sys +import gtk +from gettext import gettext as _ + +#sugar stuff +from sugar.graphics.toolbutton import ToolButton +import sugar.graphics.toolbutton + +#application stuff +from terminal import Terminal +from editor import GtkSourceview2Editor, S_WHERE +import pydebug + +#import logging +from pydebug_logging import _logger, log_environment + +class EditorGui(GtkSourceview2Editor): + def __init__(self,activity): + self._activity = activity + + GtkSourceview2Editor.__init__(self,activity) + + #set the default contents for edit,override fixed font size + self.font_size = activity.debug_dict.get('font_size',8) + self.find_window = None + + self.editbar = gtk.Toolbar() + self.last_filename = None + editopen = ToolButton() + editopen.set_stock_id('gtk-new') + editopen.set_icon_widget(None) + editopen.set_tooltip(_('New File')) + editopen.connect('clicked', self._new_file_cb) + editopen.add_accelerator('clicked',activity.accelerator,ord('N'),gtk.gdk.CONTROL_MASK,gtk.ACCEL_VISIBLE) + #editopen.props.accelerator = 'O' + editopen.show() + self.editbar.insert(editopen, -1) + + editfile = ToolButton() + editfile.set_stock_id('gtk-open') + editfile.set_icon_widget(None) + editfile.set_tooltip(_('Open File')) + editfile.connect('clicked', self._read_file_cb) + editfile.add_accelerator('clicked',activity.accelerator,ord('O'),gtk.gdk.CONTROL_MASK,gtk.ACCEL_VISIBLE) + #editfile.props.accelerator = 'O' + editfile.show() + self.editbar.insert(editfile, -1) + + editsave = ToolButton() + editsave.set_stock_id('gtk-save') + editsave.set_icon_widget(None) + editsave.set_tooltip(_('Save File')) + editsave.add_accelerator('clicked',activity.accelerator,ord('S'),gtk.gdk.CONTROL_MASK,gtk.ACCEL_VISIBLE) + #editsave.props.accelerator = 'S' + editsave.connect('clicked', self.save_cb) + editsave.show() + self.editbar.insert(editsave, -1) + + editsaveas = ToolButton() + editsaveas.set_stock_id('gtk-save-as') + editsaveas.set_icon_widget(None) + editsaveas.set_tooltip(_('Save As')) + #editsaveas.props.accelerator = 'S' + editsaveas.connect('clicked', self.save_file_cb) + editsaveas.show() + self.editbar.insert(editsaveas, -1) + + + """ + editjournal = ToolButton(tooltip=_('Open Journal')) + client = gconf.client_get_default() + color = XoColor(client.get_string('/desktop/sugar/user/color')) + journal_icon = Icon(icon_name='document-save', xo_color=color) + editjournal.set_icon_widget(journal_icon) + editjournal.connect('clicked', self._show_journal_object_picker_cb) + #editjournal.props.accelerator = 'J' + editjournal.show() + self.editbar.insert(editjournal, -1) + """ + + separator = gtk.SeparatorToolItem() + separator.set_draw(True) + separator.show() + self.editbar.insert(separator, -1) + + editundo = ToolButton('undo') + editundo.set_tooltip(_('Undo')) + editundo.connect('clicked', self.undo) + editundo.add_accelerator('clicked',activity.accelerator,ord('Z'),gtk.gdk.CONTROL_MASK,gtk.ACCEL_VISIBLE) + #editundo.props.accelerator = 'Z' + editundo.show() + self.editbar.insert(editundo, -1) + + editredo = ToolButton('redo') + editredo.set_tooltip(_('Redo')) + editredo.connect('clicked', self.redo) + editredo.add_accelerator('clicked',activity.accelerator,ord('Y'),gtk.gdk.CONTROL_MASK,gtk.ACCEL_VISIBLE) + #editredo.props.accelerator = 'Y' + editredo.show() + self.editbar.insert(editredo, -1) + + separator = gtk.SeparatorToolItem() + separator.set_draw(True) + separator.show() + self.editbar.insert(separator, -1) + + editcut = ToolButton() + editcut.set_stock_id('gtk-cut') + editcut.set_icon_widget(None) + editcut.set_tooltip(_('Cut')) + self.edit_cut_handler_id = editcut.connect('clicked', self.cut) + editcut.add_accelerator('clicked',activity.accelerator,ord('X'),gtk.gdk.CONTROL_MASK,gtk.ACCEL_VISIBLE) + #editcut.props.accelerator = 'X' + self.editbar.insert(editcut, -1) + editcut.show() + + editcopy = ToolButton('edit-copy') + editcopy.set_tooltip(_('Copy')) + self.edit_copy_handler_id = editcopy.connect('clicked', self.copy_to_clipboard_cb) + editcopy.add_accelerator('clicked',activity.accelerator,ord('C'),gtk.gdk.CONTROL_MASK,gtk.ACCEL_VISIBLE) + #editcopy.props.accelerator = 'C' + self.editbar.insert(editcopy, -1) + editcopy.show() + + editpaste = ToolButton('edit-paste') + editpaste.set_tooltip(_('Paste')) + self.edit_paste_handler_id = editpaste.connect('clicked', self.paste) + editpaste.add_accelerator('clicked',activity.accelerator,ord('V'),gtk.gdk.CONTROL_MASK,gtk.ACCEL_VISIBLE) + #editpaste.props.accelerator = 'V' + editpaste.show() + self.editbar.insert(editpaste, -1) + + separator = gtk.SeparatorToolItem() + separator.set_draw(True) + separator.show() + self.editbar.insert(separator, -1) + + editfind = ToolButton('viewmag1') + editfind.set_tooltip(_('Find and Replace')) + editfind.connect('clicked', self.show_find) + editfind.add_accelerator('clicked',activity.accelerator,ord('F'),gtk.gdk.CONTROL_MASK,gtk.ACCEL_VISIBLE) + #editfind.props.accelerator = 'F' + editfind.show() + self.editbar.insert(editfind, -1) + + separator = gtk.SeparatorToolItem() + separator.set_draw(True) + separator.show() + self.editbar.insert(separator, -1) + + self.zoomout = ToolButton('zoom-out') + self.zoomout.set_tooltip(_('Zoom out')) + self.zoomout.connect('clicked', self.__zoomout_clicked_cb) + self.editbar.insert(self.zoomout, -1) + self.zoomout.show() + + self.zoomin = ToolButton('zoom-in') + self.zoomin.set_tooltip(_('Zoom in')) + self.zoomin.connect('clicked', self.__zoomin_clicked_cb) + self.editbar.insert(self.zoomin, -1) + self.zoomin.show() + + self.editbar.show_all() + + + def get_editbar(self): + """return reference for placing on the Sugar main menu notebook""" + return self.editbar + + def _new_file_cb(self, widget): + """create a new empty file, add a sequence number if default exists""" + full_path = self._activity.util.non_conflicting(self._activity.child_path,'Unsaved_Document.py') + self.load_object(full_path,os.path.basename(full_path)) + + def _read_file_cb(self,widget): + """open up a file selector""" + _logger.debug('Reading a file into editor') + dialog = gtk.FileChooserDialog("Open..", + None, + gtk.FILE_CHOOSER_ACTION_OPEN, + (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, + gtk.STOCK_OPEN, gtk.RESPONSE_OK)) + dialog.set_default_response(gtk.RESPONSE_OK) + if self.last_filename == None: + self.last_filename = self._activity.child_path + if not self.last_filename: + self.last_filename = self.activity_playpen + if self.last_filename: + dialog.set_current_folder(os.path.dirname(self.last_filename)) + + filter = gtk.FileFilter() + filter.set_name("All files") + filter.add_pattern("*") + dialog.add_filter(filter) + + filter = gtk.FileFilter() + filter.set_name("Python") + filter.add_pattern("*.py") + dialog.add_filter(filter) + + filter = gtk.FileFilter() + filter.set_name("Activity") + filter.add_pattern("*.xo") + dialog.add_filter(filter) + + response = dialog.run() + if response == gtk.RESPONSE_OK: + _logger.debug(dialog.get_filename(), 'selected') + fname = dialog.get_filename() + self.last_filename = fname + self.load_object(fname,os.path.basename(fname)) + line = self.get_remembered_line_number(fname) + if line: + self.position_to(fname,line) + elif response == gtk.RESPONSE_CANCEL: + _logger.debug( 'File chooseer closed, no files selected') + dialog.destroy() + + def save_file_cb(self, button): + """ + impliments the SaveAs function + """ + chooser = gtk.FileChooserDialog(title=None,action=gtk.FILE_CHOOSER_ACTION_SAVE, + buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_SAVE, + gtk.RESPONSE_OK)) + file_path = self.get_full_path() + _logger.debug('Saving file %s'%(file_path)) + chooser.set_filename(file_path) + response = chooser.run() + new_fn = chooser.get_filename() + chooser.destroy() + if response == gtk.RESPONSE_CANCEL: + return + if response == gtk.RESPONSE_OK: + self.save_cb(None,new_fn) + + def save_cb(self,button,new_fn=None): + if new_fn: + full_path = new_fn + else: + full_path = self.get_full_path() + if os.path.basename(full_path).startswith('Unsaved_Document'): #force a choice to keep or change the name + #fd = open(full_path,'w') + #fd.close() + self.save_file_cb(None) + return + page = self._get_page() + if new_fn: + page.fullPath = new_fn + page.save(skip_md5 = True,new_file=new_fn) + else: + page.save() + self.clear_changed_star() + page.save_hash() + + def __zoomin_clicked_cb(self,button): + self.font_size += 1 + self.change_font_size(self.font_size) + self._activity.debug_dict['font_size'] = self.font_size + + def __zoomout_clicked_cb(self,botton): + self.font_size -= 1 + self.change_font_size(self.font_size) + self._activity.debug_dict['font_size'] = self.font_size + + ### following routines are copied from develop_app for use with editor + def _replace_cb(self, button=None): + ftext = self._search_entry.props.text + rtext = self._replace_entry.props.text + _logger.debug('replace %s with %s usiing options %r'%(ftext,rtext,self.s_opts)) + replaced, found = self.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.find_next(text, + SearchOptions(self.s_opts, + stay=True, + where=(self.s_opts.where if + self.s_opts.where != S_WHERE.multifile + else S_WHERE.file))): + #no multifile, or focus gets grabbed + 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.find_next(ftext, + SearchOptions(self.s_opts, + forward=False)): + self._replace_button.set_sensitive(True) + + def _findnext_cb(self, button=None): + ftext = self._search_entry.props.text + _logger.debug('find next %s'%ftext) + if ftext: + if self.find_next(ftext, self.s_opts): + self._replace_button.set_sensitive(True) + self.set_focus() + + + def show_find(self,button): + """find_window is defined in project.glade""" + if not self.find_window: + self._find_width = 400 + self._find_height = 300 + self.find_window = self.wTree.get_widget("find") + self.find_window.connect('destroy',self.close_find_window) + self.find_window.connect('delete_event',self.close_find_window) + self.find_connect() + self.find_window.set_title(_('FIND OR REPLACE')) + self.find_window.set_size_request(self._find_width,self._find_height) + self.find_window.set_decorated(False) + self.find_window.set_resizable(False) + self.find_window.set_modal(False) + self.find_window.connect('size_request',self._size_request_cb) + #if there is any selected text, put it in the find entry field, and grab focus + selected = self.get_selected() + _logger.debug('selected text is %s'%selected) + self._search_entry.props.text = selected + self._search_entry.grab_focus() + self.find_window.show() + + def _size_request_cb(self, widget, req): + x = gtk.gdk.screen_width() -self._find_width - 50 + self.find_window._width = req.width + self.find_window._height = req.height + self.find_window.move(x,150) + + def find_connect(self): + mdict = { + 'find_close_clicked_cb':self.close_find_window, + #'find_entry_changed_cb':self.find_entry_changed_cb, + #'replace_entry_changed_cb':self.replace_entry_changed_cb, + 'find_previous_clicked_cb':self._findprev_cb, + 'find_next_clicked_cb':self._findnext_cb, + 'find_entry_changed_cb':self._search_entry_changed_cb, + 'replace_entry_changed_cb':self._replace_entry_changed_cb, + 'replace_clicked_cb':self._replace_cb, + #'replace_all_clicked_cb':self._findprev_cb, + } + self.wTree.signal_autoconnect(mdict) + self._findnext = self.wTree.get_widget("find_next") + self._findprev = self.wTree.get_widget("find_previous") + self._search_entry = self.wTree.get_widget("find_entry") + self._replace_entry = self.wTree.get_widget("replace_entry") + self._replace_button = self.wTree.get_widget("replace") + #self.replace_all = self.wTree.get_widget("replace_all") + self.find_where = self.wTree.get_widget("find_where") + + + def close_find_window(self,button): + self.find_window.hide() + return True + + \ No newline at end of file -- cgit v0.9.1