Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSayamindu Dasgupta <sayamindu@gmail.com>2009-09-06 20:01:32 (GMT)
committer Sayamindu Dasgupta <sayamindu@gmail.com>2009-09-06 20:01:32 (GMT)
commitbf81c2c834c7d7d9632a93bfb009ae05f35811dc (patch)
treeb067d7322c064f29cda06cf0af5c0ad5166eb462
parentfa71f5f4915871b710981dbe6a8cc25ba3d7e329 (diff)
parent164f4d993adf30f4e2a6c4b95f072252875aa85f (diff)
Merge branch 'master' of git://git.sugarlabs.org/terminal/toolbars
-rw-r--r--icons/tab-add.svg12
-rw-r--r--icons/tab-next.svg12
-rw-r--r--icons/tab-previous.svg12
-rw-r--r--icons/tab-remove.svg12
-rw-r--r--icons/toolbar-tab.svg12
-rw-r--r--terminal.py420
6 files changed, 301 insertions, 179 deletions
diff --git a/icons/tab-add.svg b/icons/tab-add.svg
new file mode 100644
index 0000000..c1457bd
--- /dev/null
+++ b/icons/tab-add.svg
@@ -0,0 +1,12 @@
+<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'[
+ <!ENTITY stroke_color "#010101">
+ <!ENTITY fill_color "#FFFFFF">
+]><svg enable-background="new 0 0 55.125 55" height="55px" version="1.1" viewBox="0 0 55.125 55" width="55.125px" x="0px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" y="0px">
+<g display="block" id="tab-add">
+ <g transform="scale(.80)">
+ <g transform="translate(6.5, 6.5)">
+ <path d="M0,50 l55,0 l0,-15 l-5,0 l0,-25 q0,-5 -5,-5 l-35,0 q-5,0 -5,5 l0,25 l-5,0z M30.768,38.767c-0.002,1.774-1.438,3.216-3.214,3.214c-0.889,0.001-1.693-0.359-2.275-0.941c-0.582-0.581-0.94-1.385-0.94-2.27 l0-8.146h-8.146c-0.886-0.001-1.689-0.359-2.271-0.94c-0.582-0.583-0.942-1.388-0.942-2.276c0-1.773,1.439-3.213,3.217-3.211h8.143 v-8.143c-0.003-1.776,1.438-3.217,3.212-3.217c1.774,0,3.218,1.438,3.215,3.215l0.001,8.145l8.146,0.001 c1.775-0.005,3.212,1.438,3.213,3.213c0.002,1.775-1.441,3.214-3.215,3.215h-8.143V38.767z" fill="&fill_color;"/>
+ </g>
+ </g>
+</g>
+</svg> \ No newline at end of file
diff --git a/icons/tab-next.svg b/icons/tab-next.svg
new file mode 100644
index 0000000..9b29d8d
--- /dev/null
+++ b/icons/tab-next.svg
@@ -0,0 +1,12 @@
+<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'[
+ <!ENTITY stroke_color "#010101">
+ <!ENTITY fill_color "#FFFFFF">
+]><svg enable-background="new 0 0 55.125 55" height="55px" version="1.1" viewBox="0 0 55.125 55" width="55.125px" x="0px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" y="0px">
+<g display="block" id="tab-next">
+ <g transform="scale(.80)">
+ <g transform="translate(6.5, 6.5)">
+ <path d="M0,50 l55,0 l0,-15 l-5,0 l0,-25 q0,-5 -5,-5 l-35,0 q-5,0 -5,5 l0,25 l-5,0z M20.733,17.551l19.629,9.965L20.733,37.758V17.551z" fill="&fill_color;"/>
+ </g>
+ </g>
+</g>
+</svg> \ No newline at end of file
diff --git a/icons/tab-previous.svg b/icons/tab-previous.svg
new file mode 100644
index 0000000..6861c30
--- /dev/null
+++ b/icons/tab-previous.svg
@@ -0,0 +1,12 @@
+<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'[
+ <!ENTITY stroke_color "#010101">
+ <!ENTITY fill_color "#FFFFFF">
+]><svg enable-background="new 0 0 55.125 55" height="55px" version="1.1" viewBox="0 0 55.125 55" width="55.125px" x="0px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" y="0px">
+<g display="block" id="tab-previous">
+ <g transform="scale(.80)">
+ <g transform="translate(6.5, 6.5)">
+ <path d="M0,50 l55,0 l0,-15 l-5,0 l0,-25 q0,-5 -5,-5 l-35,0 q-5,0 -5,5 l0,25 l-5,0z M34.267,37.449l-19.629-9.965l19.629-10.242V37.449z" fill="&fill_color;"/>
+ </g>
+ </g>
+</g>
+</svg> \ No newline at end of file
diff --git a/icons/tab-remove.svg b/icons/tab-remove.svg
new file mode 100644
index 0000000..8521c5b
--- /dev/null
+++ b/icons/tab-remove.svg
@@ -0,0 +1,12 @@
+<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'[
+ <!ENTITY stroke_color "#010101">
+ <!ENTITY fill_color "#FFFFFF">
+]><svg enable-background="new 0 0 55.125 55" height="55px" version="1.1" viewBox="0 0 55.125 55" width="55.125px" x="0px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" y="0px">
+<g display="block" id="tab-remove">
+ <g transform="scale(.80)">
+ <g transform="translate(6.5, 6.5)">
+ <path d="M0,50 l55,0 l0,-15 l-5,0 l0,-25 q0,-5 -5,-5 l-35,0 q-5,0 -5,5 l0,25 l-5,0z M16.192,30.623c-0.886-0.001-1.689-0.359-2.271-0.94c-0.582-0.583-0.942-1.388-0.942-2.276c0-1.773,1.439-3.213,3.217-3.211 l22.716,0c1.775-0.005,3.212,1.438,3.213,3.213c0.002,1.775-1.441,3.214-3.215,3.215L16.192,30.623z" fill="&fill_color;"/>
+ </g>
+ </g>
+</g>
+</svg> \ No newline at end of file
diff --git a/icons/toolbar-tab.svg b/icons/toolbar-tab.svg
new file mode 100644
index 0000000..4d69921
--- /dev/null
+++ b/icons/toolbar-tab.svg
@@ -0,0 +1,12 @@
+<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'[
+ <!ENTITY stroke_color "#010101">
+ <!ENTITY fill_color "#FFFFFF">
+]><svg enable-background="new 0 0 55.125 55" height="55px" version="1.1" viewBox="0 0 55.125 55" width="55.125px" x="0px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" y="0px">
+<g display="block" id="toolbar-tab">
+ <g transform="scale(.80)">
+ <g transform="translate(6.5, 6.5)">
+ <path d="M0,42 l55,0 l0,-12 l-5,0 l0,-17 q0,-5 -5,-5 l-10,0 q5,0 5,5 l0,16 l10,0 l0,1 l-13,0 l0,-17 q0,-5 -5,-5 l-22,0 q-5,0 -5,5 l0,17 l-5,0z" fill="&fill_color;"/>
+ </g>
+ </g>
+</g>
+</svg> \ No newline at end of file
diff --git a/terminal.py b/terminal.py
index cc0a868..d00be08 100644
--- a/terminal.py
+++ b/terminal.py
@@ -1,5 +1,6 @@
# 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
@@ -15,180 +16,241 @@
# 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, os.path, simplejson, ConfigParser
-
-from gettext import gettext as _
-
-# Initialize logging.
+import os
+import simplejson
+import ConfigParser
import logging
-log = logging.getLogger('Terminal')
-log.setLevel(logging.DEBUG)
-logging.basicConfig()
+from gettext import gettext as _
import gtk
import vte
import pango
-import sugar.graphics.toolbutton
-import sugar.activity.activity
-import sugar.env
+from sugar.graphics.toolbutton import ToolButton
+from sugar.graphics.toolbarbox import ToolbarBox
+from sugar.graphics.toolbarbox import ToolbarButton
+from sugar.activity.widgets import ActivityToolbarButton
+from sugar.activity.widgets import StopButton
+from sugar.activity import activity
+from sugar import env
MASKED_ENVIRONMENT = [
'DBUS_SESSION_BUS_ADDRESS',
- 'PPID'
-]
+ 'PPID']
+
+log = logging.getLogger('Terminal')
+log.setLevel(logging.DEBUG)
+logging.basicConfig()
-class TerminalActivity(sugar.activity.activity.Activity):
+
+class TerminalActivity(activity.Activity):
def __init__(self, handle):
- sugar.activity.activity.Activity.__init__(self, handle)
-
- self.data_file = None
-
- self.set_title(_('Terminal Activity'))
-
- # Non-working attempt to hide the Escape key from Sugar.
- #self.connect('key-press-event', self._key_press_cb)
-
- toolbox = sugar.activity.activity.ActivityToolbox(self)
-
- editbar = sugar.activity.activity.EditToolbar()
- toolbox.add_toolbar(_('Edit'), editbar)
- editbar.show()
- editbar.undo.props.visible = False
- editbar.redo.props.visible = False
- editbar.separator.props.visible = False
- editbar.copy.connect('clicked', self._copy_cb)
- editbar.copy.props.accelerator = '<Ctrl><Shift>C'
- editbar.paste.connect('clicked', self._paste_cb)
- editbar.paste.props.accelerator = '<Ctrl><Shift>V'
-
- newtabbtn = sugar.graphics.toolbutton.ToolButton('list-add')
- newtabbtn.set_tooltip(_("Open New Tab"))
- newtabbtn.props.accelerator = '<Ctrl><Shift>T'
- newtabbtn.connect('clicked', self._open_tab_cb)
-
- deltabbtn = sugar.graphics.toolbutton.ToolButton('list-remove')
- deltabbtn.set_tooltip(_("Close Tab"))
- deltabbtn.props.accelerator = '<Ctrl><Shift>X'
- deltabbtn.connect('clicked', self._close_tab_cb)
-
- tabsep = gtk.SeparatorToolItem()
- tabsep.set_expand(True)
- tabsep.set_draw(False)
+ activity.Activity.__init__(self, handle)
+
+ self.max_participants = 1
+
+ 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 = self._create_edit_toolbar()
+ edit_toolbar_button = ToolbarButton(
+ page=edit_toolbar,
+ icon_name='toolbar-edit')
+ edit_toolbar.show()
+ toolbar_box.toolbar.insert(edit_toolbar_button, -1)
+ edit_toolbar_button.show()
+
+ view_toolbar = self._create_view_toolbar()
+ view_toolbar_button = ToolbarButton(
+ page=view_toolbar,
+ icon_name='toolbar-view')
+ view_toolbar.show()
+ toolbar_box.toolbar.insert(view_toolbar_button, -1)
+ view_toolbar_button.show()
+
+ self._delete_tab_toolbar = None
+ self._previous_tab_toolbar = None
+ self._next_tab_toolbar = None
+ tab_toolbar = self._create_tab_toolbar()
+ tab_toolbar_button = ToolbarButton(
+ page=tab_toolbar,
+ icon_name='toolbar-tab')
+ tab_toolbar.show()
+ toolbar_box.toolbar.insert(tab_toolbar_button, -1)
+ tab_toolbar_button.show()
# Add a button that will be used to become root easily.
- rootbtn = sugar.graphics.toolbutton.ToolButton('activity-become-root')
- rootbtn.set_tooltip(_('Become root'))
- rootbtn.connect('clicked', self._become_root_cb)
-
- prevtabbtn = sugar.graphics.toolbutton.ToolButton('go-previous')
- prevtabbtn.set_tooltip(_("Previous Tab"))
- prevtabbtn.props.accelerator = '<Ctrl><Shift>Left'
- prevtabbtn.connect('clicked', self._prev_tab_cb)
-
- nexttabbtn = sugar.graphics.toolbutton.ToolButton('go-next')
- nexttabbtn.set_tooltip(_("Next Tab"))
- nexttabbtn.props.accelerator = '<Ctrl><Shift>Right'
- nexttabbtn.connect('clicked', self._next_tab_cb)
-
- tabbar = gtk.Toolbar()
- tabbar.insert(newtabbtn, -1)
- tabbar.insert(deltabbtn, -1)
- tabbar.insert(tabsep, -1)
- tabbar.insert(rootbtn, -1)
- tabbar.insert(prevtabbtn, -1)
- tabbar.insert(nexttabbtn, -1)
- tabbar.show_all()
-
- toolbox.add_toolbar(_('Tab'), tabbar)
-
- activity_toolbar = toolbox.get_activity_toolbar()
- activity_toolbar.share.props.visible = False
- activity_toolbar.keep.props.visible = False
- activity_toolbar.keep.props.accelerator = '<Ctrl><Shift>S'
- activity_toolbar.stop.props.accelerator = '<Ctrl><Shift>Q'
-
- fullscreenbtn = sugar.graphics.toolbutton.ToolButton('view-fullscreen')
- fullscreenbtn.set_tooltip(_("Fullscreen"))
- fullscreenbtn.props.accelerator = '<Alt>Enter'
- fullscreenbtn.connect('clicked', self._fullscreen_cb)
- activity_toolbar.insert(fullscreenbtn, 2)
- fullscreenbtn.show()
-
- self.set_toolbox(toolbox)
- toolbox.show()
-
- self.notebook = gtk.Notebook()
- self.notebook.set_property("tab-pos", gtk.POS_BOTTOM)
- self.notebook.set_scrollable(True)
- self.notebook.show()
-
- self.set_canvas(self.notebook)
+ root_button = ToolButton('activity-become-root')
+ root_button.set_tooltip(_('Become root'))
+ root_button.connect('clicked', self.__become_root_cb)
+ toolbar_box.toolbar.insert(root_button, -1)
+ root_button.show()
+
+ 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.props.accelerator = '<Ctrl><Shift>Q'
+ toolbar_box.toolbar.insert(stop_button, -1)
+ stop_button.show()
+
+ self.set_toolbar_box(toolbar_box)
+ toolbar_box.show()
+
+ self._notebook = gtk.Notebook()
+ self._notebook.set_property("tab-pos", gtk.POS_TOP)
+ self._notebook.set_scrollable(True)
+ self._notebook.show()
+
+ self.set_canvas(self._notebook)
self._create_tab(None)
- def _open_tab_cb(self, btn):
- index = self._create_tab(None)
- self.notebook.page = index
+ 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.paste.connect('clicked', self.__paste_cb)
+ edit_toolbar.paste.props.accelerator = '<Ctrl><Shift>V'
+ 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 _close_tab_cb(self, btn):
- self._close_tab(self.notebook.props.page)
+ 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>Enter'
+ 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 _prev_tab_cb(self, btn):
- if self.notebook.props.page == 0:
- self.notebook.props.page = self.notebook.get_n_pages() - 1
+ def _create_tab_toolbar(self):
+ tab_toolbar = gtk.Toolbar()
+ new_tab_button = ToolButton('tab-add')
+ new_tab_button.set_tooltip(_("Add New Tab"))
+ new_tab_button.props.accelerator = '<Ctrl><Shift>T'
+ 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(_("Remove Tab"))
+ self._delete_tab_button.props.accelerator = '<Ctrl><Shift>X'
+ 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.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
+ 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
+ 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
+ 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._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:
+
+ 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
+
+ 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):
+
+ 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 _create_tab(self, tab_state):
vt = vte.Terminal()
- vt.connect("child-exited", self._tab_child_exited_cb)
- vt.connect("window-title-changed", self._tab_title_changed_cb)
+ vt.connect("child-exited", self.__tab_child_exited_cb)
+ vt.connect("window-title-changed", self.__tab_title_changed_cb)
vt.drag_dest_set(gtk.DEST_DEFAULT_MOTION|gtk.DEST_DEFAULT_DROP,
[('text/plain', 0, 0), ('STRING', 0, 1)],
gtk.gdk.ACTION_DEFAULT|
gtk.gdk.ACTION_COPY)
- vt.connect('drag_data_received', self._drag_data_received_cb)
-
+ vt.connect('drag_data_received', self.__drag_data_received_cb)
+
self._configure_vt(vt)
vt.show()
-
+
label = gtk.Label()
scrollbar = gtk.VScrollbar(vt.get_adjustment())
@@ -200,13 +262,14 @@ class TerminalActivity(sugar.activity.activity.Activity):
box.vt = vt
box.label = label
-
- index = self.notebook.append_page(box, label)
- self.notebook.show_all()
- # Uncomment this to only show the tab bar when there is at least one tab.
- # I think it's useful to always see it, since it displays the 'window title'.
- #self.notebook.props.show_tabs = self.notebook.get_n_pages() > 1
+ index = self._notebook.append_page(box, label)
+ self._notebook.show_all()
+
+ # Uncomment this to only show the tab bar when there is at least
+ # one tab. I think it's useful to always see it, since it displays
+ # the 'window title'.
+ # self._notebook.props.show_tabs = self._notebook.get_n_pages() > 1
# Launch the default shell in the HOME directory.
os.chdir(os.environ["HOME"])
@@ -214,19 +277,20 @@ class TerminalActivity(sugar.activity.activity.Activity):
if tab_state:
# Restore the environment.
# This is currently not enabled.
- env = tab_state['env']
+ environment = tab_state['env']
filtered_env = []
- for e in env:
+ for e in environment:
var, sep, value = e.partition('=')
if var not in MASKED_ENVIRONMENT:
filtered_env.append(var + sep + value)
- # TODO: Make the shell restore these environment variables, then clear out TERMINAL_ENV.
- #os.environ['TERMINAL_ENV'] = '\n'.join(filtered_env)
-
+ # TODO: Make the shell restore these environment variables,
+ # then clear out TERMINAL_ENV.
+ # os.environ['TERMINAL_ENV'] = '\n'.join(filtered_env)
+
# Restore the working directory.
- if tab_state.has_key('cwd'):
+ if 'cwd' in tab_state:
os.chdir(tab_state['cwd'])
# Restore the scrollback buffer.
@@ -235,33 +299,23 @@ class TerminalActivity(sugar.activity.activity.Activity):
box.pid = vt.fork_command()
- self.notebook.props.page = index
+ self._notebook.props.page = index
vt.grab_focus()
return index
- 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 _become_root_cb(self, button):
- vt = self.notebook.get_nth_page(self.notebook.get_current_page()).vt
+ 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', '-'))
- def _fullscreen_cb(self, btn):
- self.fullscreen()
-
- def _key_press_cb(self, window, event):
+ def __key_press_cb(self, window, event):
# Escape keypresses are routed directly to the vte and then dropped.
- # This hack prevents Sugar from hijacking them and canceling fullscreen mode.
+ # This hack prevents Sugar from hijacking them and canceling
+ # fullscreen mode.
if gtk.gdk.keyval_name(event.keyval) == 'Escape':
- vt = self.notebook.get_nth_page(self.notebook.get_current_page()).vt
+ current_page = self._notebook.get_current_page()
+ vt = self._notebook.get_nth_page(current_page).vt
vt.event(event)
return True
@@ -279,44 +333,51 @@ class TerminalActivity(sugar.activity.activity.Activity):
data_file = file_path
# Clean out any existing tabs.
- while self.notebook.get_n_pages():
- self.notebook.remove_page(0)
+ while self._notebook.get_n_pages():
+ self._notebook.remove_page(0)
# Create new tabs from saved state.
for tab_state in data['tabs']:
self._create_tab(tab_state)
# Restore active tab.
- self.notebook.props.page = data['current-tab']
+ self._notebook.props.page = data['current-tab']
# Create a blank one if this state had no terminals.
- if self.notebook.get_n_pages() == 0:
+ if self._notebook.get_n_pages() == 0:
self._create_tab(None)
+ if self._notebook.get_n_pages() > 1:
+ self._delete_tab_button.props.sensitive = True
+ self._previous_tab_button.props.sensitive = True
+ self._next_tab_button.props.sensitive = True
+
def write_file(self, file_path):
if not self.metadata['mime_type']:
self.metadata['mime_type'] = 'text/plain'
data = {}
- data['current-tab'] = self.notebook.get_current_page()
+ data['current-tab'] = self._notebook.get_current_page()
data['tabs'] = []
- for i in range(self.notebook.get_n_pages()):
- page = self.notebook.get_nth_page(i)
+ for i in range(self._notebook.get_n_pages()):
+ page = self._notebook.get_nth_page(i)
def selected_cb(terminal, c, row, cb_data):
return 1
- (scrollback_text, attrs) = page.vt.get_text(selected_cb, 1)
+ (scrollback_text, attributes_) = page.vt.get_text(selected_cb, 1)
scrollback_lines = scrollback_text.split('\n')
- # Note- this currently gets the child's initial environment rather than the current
- # environment, making it not very useful.
- environment = open('/proc/%d/environ' % page.pid, 'r').read().split('\0')
+ # Note- this currently gets the child's initial environment
+ # rather than the current environment, making it not very useful.
+ environment = open('/proc/%d/environ' %
+ page.pid, 'r').read().split('\0')
cwd = os.readlink('/proc/%d/cwd' % page.pid)
- tab_state = { 'env': environment, 'cwd': cwd, 'scrollback': scrollback_lines }
+ tab_state = {'env': environment, 'cwd': cwd,
+ 'scrollback': scrollback_lines}
data['tabs'].append(tab_state)
@@ -324,7 +385,7 @@ class TerminalActivity(sugar.activity.activity.Activity):
text = simplejson.dumps(data)
fd.write(text)
fd.close()
-
+
def _get_conf(self, conf, var, default):
if conf.has_option('terminal', var):
if isinstance(default, bool):
@@ -340,39 +401,40 @@ class TerminalActivity(sugar.activity.activity.Activity):
def _configure_vt(self, vt):
conf = ConfigParser.ConfigParser()
- conf_file = os.path.join(sugar.env.get_profile_path(), 'terminalrc')
-
+ conf_file = os.path.join(env.get_profile_path(), 'terminalrc')
+
if os.path.isfile(conf_file):
f = open(conf_file, 'r')
conf.readfp(f)
f.close()
else:
conf.add_section('terminal')
-
+
font = self._get_conf(conf, 'font', 'Monospace')
vt.set_font(pango.FontDescription(font))
fg_color = self._get_conf(conf, 'fg_color', '#000000')
bg_color = self._get_conf(conf, 'bg_color', '#FFFFFF')
- vt.set_colors(gtk.gdk.color_parse(fg_color), gtk.gdk.color_parse(bg_color), [])
+ vt.set_colors(gtk.gdk.color_parse(fg_color),
+ gtk.gdk.color_parse(bg_color), [])
blink = self._get_conf(conf, 'cursor_blink', False)
vt.set_cursor_blinks(blink)
bell = self._get_conf(conf, 'bell', False)
vt.set_audible_bell(bell)
-
+
scrollback_lines = self._get_conf(conf, 'scrollback_lines', 1000)
vt.set_scrollback_lines(scrollback_lines)
vt.set_allow_bold(True)
-
+
scroll_key = self._get_conf(conf, 'scroll_on_keystroke', True)
vt.set_scroll_on_keystroke(scroll_key)
scroll_output = self._get_conf(conf, 'scroll_on_output', False)
vt.set_scroll_on_output(scroll_output)
-
+
emulation = self._get_conf(conf, 'emulation', 'xterm')
vt.set_emulation(emulation)