Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/terminal_gui.py
diff options
context:
space:
mode:
Diffstat (limited to 'terminal_gui.py')
-rw-r--r--terminal_gui.py322
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&gtk.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&gtk.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&gtk.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()
+
+