diff options
Diffstat (limited to 'terminal_gui.py')
-rw-r--r-- | terminal_gui.py | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/terminal_gui.py b/terminal_gui.py new file mode 100644 index 0000000..0039298 --- /dev/null +++ b/terminal_gui.py @@ -0,0 +1,322 @@ +# Copyright (C) 2007, Eduardo Silva <edsiper@gmail.com>. +# Copyright (C) 2008, One Laptop Per Child +# Copyright (C) 2009, 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. +# +# 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 + +import os +import sys +#import simplejson +import pickle +import ConfigParser +import shutil +import gobject +from exceptions import * + +import logging +from gettext import gettext as _ + +import gtk +import vte +import pango + +from sugar.graphics.toolbutton import ToolButton +from sugar.activity.activity import Activity +import sugar.activity.activity as activity +from sugar import env +from help.help import Help + +# Attempt to import the new toolbar classes. If the import fails, +# fall back to the old toolbar style. +try: + from sugar.graphics.toolbarbox import ToolbarBox + from sugar.graphics.toolbarbox import ToolbarButton + from sugar.activity.widgets import ActivityToolbarButton + from sugar.activity.widgets import StopButton + NEW_TOOLBARS = True +except ImportError: + from sugar.activity.activity import ActivityToolbox + NEW_TOOLBARS = False +from terminal import TerminalBase + +logging.basicConfig() +_logger = logging.getLogger('vimtutor') +_logger.setLevel(logging.DEBUG) + +class TerminalActivity(TerminalBase, Activity): + + def __init__(self, vimtutor, handle): + create_jobject = True #not handle.object_id + Activity.__init__(self, handle, create_jobject) + TerminalBase.__init__(self, vimtutor, handle) + self.handle = handle + self._vimtutor = vimtutor + self.help_x11 = False + self.max_participants = 1 + self.accelerator = gtk.AccelGroup() + self.add_accel_group(self.accelerator) + + edit_toolbar = self._create_edit_toolbar() + edit_toolbar.show() + + view_toolbar = self._create_view_toolbar() + view_toolbar.show() + + self._delete_tab_toolbar = None + self._previous_tab_toolbar = None + self._next_tab_toolbar = None + tab_toolbar = self._create_tab_toolbar() + tab_toolbar.show() + + help_toolbar = self._create_help_toolbar() + help_toolbar.show() + self.help = Help(self) + + # Add a button that will be used to become root easily. + root_button = ToolButton('activity-become-root') + root_button.set_tooltip(_('Become root')) + root_button.connect('clicked', self.__become_root_cb) + root_button.show() + + if NEW_TOOLBARS: + toolbar_box = ToolbarBox() + + activity_button = ActivityToolbarButton(self) + toolbar_box.toolbar.insert(activity_button, 0) + #activity_button.page.keep.props.accelerator = '<Ctrl><Shift>S' + activity_button.show() + + edit_toolbar_button = ToolbarButton( + page=edit_toolbar, + icon_name='toolbar-edit') + toolbar_box.toolbar.insert(edit_toolbar_button, -1) + edit_toolbar_button.show() + + view_toolbar_button = ToolbarButton( + page=view_toolbar, + icon_name='toolbar-view') + toolbar_box.toolbar.insert(view_toolbar_button, -1) + view_toolbar_button.show() + + tab_toolbar_button = ToolbarButton( + page=tab_toolbar, + icon_name='toolbar-tab') + toolbar_box.toolbar.insert(tab_toolbar_button, -1) + tab_toolbar_button.show() + + toolbar_box.toolbar.insert(root_button, -1) + + separator = gtk.SeparatorToolItem() + separator.props.draw = False + separator.set_expand(True) + toolbar_box.toolbar.insert(separator, -1) + separator.show() + + stop_button = StopButton(self) + stop_button.add_accelerator('clicked', self.accelerator, ord('Q'), + gtk.gdk.SHIFT_MASK, gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) + #stop_button.props.accelerator = '<Ctrl><Shift>Q' + toolbar_box.toolbar.insert(stop_button, -1) + stop_button.show() + + self.set_toolbar_box(toolbar_box) + toolbar_box.show() + + else: + toolbox = ActivityToolbox(self) + toolbox.add_toolbar(_('Edit'), edit_toolbar) + toolbox.add_toolbar(_('View'), view_toolbar) + toolbox.add_toolbar(_('Tab'), tab_toolbar) + toolbox.add_toolbar(_('Help'), help_toolbar) + toolbox.connect_after('current_toolbar_changed', + self._toolbar_changed_cb) + self.HELP_INDEX = 4 + self.set_toolbox(toolbox) + toolbox.show() + + + self.set_canvas(self._notebook) + + def _create_edit_toolbar(self): + edit_toolbar = activity.EditToolbar() + edit_toolbar.undo.props.visible = False + edit_toolbar.redo.props.visible = False + edit_toolbar.separator.props.visible = False + edit_toolbar.copy.connect('clicked', self.__copy_cb) + #edit_toolbar.copy.props.accelerator = '<Ctrl><Shift>C' + edit_toolbar.copy.add_accelerator('clicked', self.accelerator, ord('C'), + gtk.gdk.SHIFT_MASK & gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) + edit_toolbar.paste.connect('clicked', self.__paste_cb) + #edit_toolbar.paste.props.accelerator = '<Ctrl><Shift>V' + edit_toolbar.paste.add_accelerator('clicked', self.accelerator, ord('V'), + gtk.gdk.SHIFT_MASK & gtk.gdk.CONTROL_MASK , gtk.ACCEL_VISIBLE) + return edit_toolbar + + def __copy_cb(self, button): + vt = self._notebook.get_nth_page(self._notebook.get_current_page()).vt + if vt.get_has_selection(): + vt.copy_clipboard() + + def __paste_cb(self, button): + vt = self._notebook.get_nth_page(self._notebook.get_current_page()).vt + vt.paste_clipboard() + + def _create_view_toolbar(self): + view_toolbar = gtk.Toolbar() + fullscreen_button = ToolButton('view-fullscreen') + fullscreen_button.set_tooltip(_("Fullscreen")) + #fullscreen_button.props.accelerator = '<Alt>Return' + fullscreen_button.connect('clicked', self.__fullscreen_cb) + view_toolbar.insert(fullscreen_button, -1) + fullscreen_button.show() + return view_toolbar + + def __fullscreen_cb(self, button): + self.fullscreen() + + def _create_tab_toolbar(self): + tab_toolbar = gtk.Toolbar() + new_tab_button = ToolButton('tab-add') + new_tab_button.set_tooltip(_("Open New Tab")) + #new_tab_button.props.accelerator = '<Ctrl><Shift>T' + #new_tab_button.add_accelerator('clicked', self.accelerator, ord('T'), + # gtk.gdk.SHIFT_MASK>k.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) + new_tab_button.connect('clicked', self.__open_tab_cb) + tab_toolbar.insert(new_tab_button, -1) + new_tab_button.show() + + self._delete_tab_button = ToolButton('tab-remove') + self._delete_tab_button.set_tooltip(_("Close Tab")) + #self._delete_tab_button.props.accelerator = '<Ctrl><Shift>X' + self._delete_tab_button.add_accelerator('clicked', self.accelerator, ord('X'), + gtk.gdk.SHIFT_MASK>k.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) + self._delete_tab_button.props.sensitive = False + self._delete_tab_button.connect('clicked', self.__close_tab_cb) + tab_toolbar.insert(self._delete_tab_button, -1) + self._delete_tab_button.show() + + self._previous_tab_button = ToolButton('tab-previous') + self._previous_tab_button.set_tooltip(_("Previous Tab")) + #self._previous_tab_button.props.accelerator = '<Ctrl><Shift>Left' + self._previous_tab_button.props.sensitive = False + #self._previous_tab_button.add_accelerator('clicked', self.accelerator, + #gtk.gdk.GDK_left, + #gtk.gdk.SHIFT_MASK>k.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) + self._previous_tab_button.connect('clicked', self.__prev_tab_cb) + tab_toolbar.insert(self._previous_tab_button, -1) + self._previous_tab_button.show() + + self._next_tab_button = ToolButton('tab-next') + self._next_tab_button.set_tooltip(_("Next Tab")) + #self._next_tab_button.props.accelerator = '<Ctrl><Shift>Right' + self._next_tab_button.props.sensitive = False + self._next_tab_button.connect('clicked', self.__next_tab_cb) + tab_toolbar.insert(self._next_tab_button, -1) + self._next_tab_button.show() + return tab_toolbar + + def __open_tab_cb(self, btn): + index = self._create_tab(None) + self._notebook.page = index + if self._notebook.get_n_pages() == 2: + self._delete_tab_button.props.sensitive = True + self._previous_tab_button.props.sensitive = True + self._next_tab_button.props.sensitive = True + + def __close_tab_cb(self, btn): + self._close_tab(self._notebook.props.page) + if self._notebook.get_n_pages() == 1: + self._delete_tab_button.props.sensitive = False + self._previous_tab_button.props.sensitive = False + self._next_tab_button.props.sensitive = False + + def __prev_tab_cb(self, btn): + if self._notebook.props.page == 0: + self._notebook.props.page = self._notebook.get_n_pages() - 1 + else: + self._notebook.props.page = self._notebook.props.page - 1 + vt = self._notebook.get_nth_page(self._notebook.get_current_page()).vt + vt.grab_focus() + + def __next_tab_cb(self, btn): + if self._notebook.props.page == self._notebook.get_n_pages() - 1: + self._notebook.props.page = 0 + else: + self._notebook.props.page = self._notebook.props.page + 1 + vt = self._notebook.get_nth_page(self._notebook.get_current_page()).vt + vt.grab_focus() + + def _close_tab(self, index): + self._notebook.remove_page(index) + if self._notebook.get_n_pages() == 0: + self.close() + + def tab_child_exited_cb(self, vt): + for i in range(self._notebook.get_n_pages()): + if self._notebook.get_nth_page(i).vt == vt: + self._close_tab(i) + return + + def tab_title_changed_cb(self, vt): + for i in range(self._notebook.get_n_pages()): + if self._notebook.get_nth_page(i).vt == vt: + label = self._notebook.get_nth_page(i).label + label.set_text(vt.get_window_title()) + return + + def drag_data_received_cb(self, widget, context, x, y, selection, + target, time): + widget.feed_child(selection.data) + context.finish(True, False, time) + return True + + def __become_root_cb(self, button): + vt = self._notebook.get_nth_page(self._notebook.get_current_page()).vt + vt.feed('\r\n') + vt.fork_command("/bin/su", ('/bin/su', '-')) + + + ################ Help routines ################ + def _create_help_toolbar(self): + help_toolbar = gtk.Toolbar() + return help_toolbar + + def _toolbar_changed_cb(self, widget, tab_no): + """top level menu clicked, check for help""" + if tab_no == self.HELP_INDEX: + self.help_selected() + gobject.idle_add(self.grab_vt_focus) + + def set_toolbar(self,tab): + self.toolbox.set_current_toolbar(tab) + + def grab_vt_focus(self): + vt = self._notebook.get_nth_page(self._notebook.get_current_page()).vt + vt.grab_focus() + + def help_selected(self): + """ + if help is not created in a gtk.mainwindow then create it + else just switch to that window + """ + if not self.help_x11: + screen = gtk.gdk.screen_get_default() + self.pdb_window = screen.get_root_window() + _logger.debug('xid for pydebug:%s'%self.pdb_window.xid) + self.help_x11 = self.help.realize_help() + else: + self.help.activate_help() + + |