Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/notebook.py
diff options
context:
space:
mode:
Diffstat (limited to 'notebook.py')
-rw-r--r--notebook.py238
1 files changed, 238 insertions, 0 deletions
diff --git a/notebook.py b/notebook.py
new file mode 100644
index 0000000..23b0be3
--- /dev/null
+++ b/notebook.py
@@ -0,0 +1,238 @@
+from gi.repository import Gtk
+from gi.repository import Gdk
+from gi.repository import GObject
+from gi.repository import Vte
+from gi.repository import Pango
+from gi.repository import GtkSource
+from gettext import gettext as _
+from sugar3.graphics.icon import Icon
+from port.style import font_zoom
+from sugar3.graphics import style
+
+from sugar3.graphics.toolbutton import ToolButton
+
+
+SIZE_X = Gdk.Screen.width()
+SIZE_Y = Gdk.Screen.height()
+
+
+class TabLabel(Gtk.HBox):
+ __gsignals__ = {
+ 'tab-close': (GObject.SignalFlags.RUN_FIRST,
+ None,
+ ([GObject.TYPE_PYOBJECT])),
+ }
+
+ def __init__(self, child, label, tabs):
+ GObject.GObject.__init__(self)
+
+ self.child = child
+ self.label_text = label
+ self.tabs = tabs
+
+ self.label_box = Gtk.EventBox()
+ self._label = Gtk.Label(label=self.label_text)
+ self._label.set_alignment(0, 0.5)
+ self._label.show()
+
+ self.label_box.add(self._label)
+ self.label_box.connect("button-press-event", self._label_clicked)
+ self.label_box.show_all()
+ self.pack_start(self.label_box, True, True, 5)
+
+ self.label_entry = Gtk.Entry()
+ self.label_entry.connect("activate", self._label_entry_cb)
+ self.label_entry.connect("focus-out-event", self._label_entry_cb)
+ self.pack_start(self.label_entry, True, True, 0)
+
+ button = ToolButton("close-tab")
+ button.connect('clicked', self.__button_clicked_cb)
+ self.pack_start(button, False, True, 0)
+ button.show()
+ self._close_button = button
+
+ def set_text(self, title):
+ self._label.set_text(title)
+
+ def get_text(self):
+ return self._label.get_text()
+
+ def update_size(self, size):
+ self.set_size_request(size, -1)
+
+ def hide_close_button(self):
+ self._close_button.hide()
+
+ def show_close_button(self):
+ self._close_button.show()
+
+ def __button_clicked_cb(self, button):
+ self.emit('tab-close', self.child)
+
+ def _label_clicked(self, eventbox, data):
+ if self.tabs.page_num(self.child) is not self.tabs.get_current_page():
+ self.child.grab_focus()
+ else:
+ self.label_entry.set_text(self.label_text)
+ eventbox.hide()
+ self.label_entry.grab_focus()
+ self.label_entry.show()
+
+ def _label_entry_cb(self, entry, focus=None):
+ self.label_text = self.label_entry.get_text()
+ self.label_box.show_all()
+ self.label_entry.hide()
+ self._label.set_text(self.label_text)
+
+
+"""
+ AddNotebook
+ -----------
+ This subclass has a add button which emits tab-added on clicking the
+ button.
+"""
+
+
+class AddNotebook(Gtk.Notebook):
+ __gsignals__ = {
+ 'tab-added': (GObject.SignalFlags.RUN_FIRST,
+ None,
+ ([])),
+ }
+
+ def __init__(self):
+ Gtk.Notebook.__init__(self)
+
+ self._add_tab = ToolButton("gtk-add")
+ self._add_tab.connect("clicked", self._add_tab_cb)
+ self._add_tab.show()
+ self.set_action_widget(self._add_tab, Gtk.PackType.END)
+
+ def _add_tab_cb(self, button):
+ self.emit("tab-added")
+
+
+class SourceNotebook(AddNotebook):
+ def __init__(self, activity):
+ AddNotebook.__init__(self)
+ self.activity = activity
+ self.set_scrollable(True)
+
+ def add_tab(self, label=None, buffer_text=None):
+
+ # Set text_buffer
+ text_buffer = GtkSource.Buffer()
+ lang_manager = GtkSource.LanguageManager.get_default()
+ if hasattr(lang_manager, 'list_languages'):
+ langs = lang_manager.list_languages()
+ else:
+ lang_ids = lang_manager.get_language_ids()
+ langs = [lang_manager.get_language(lang_id)
+ for lang_id in lang_ids]
+ for lang in langs:
+ for m in lang.get_mime_types():
+ if m == "text/x-python":
+ text_buffer.set_language(lang)
+
+ if hasattr(text_buffer, 'set_highlight'):
+ text_buffer.set_highlight(True)
+ else:
+ text_buffer.set_highlight_syntax(True)
+
+ if buffer_text:
+ text_buffer.set_text(buffer_text)
+
+ # Set up SourceView
+ text_view = GtkSource.View()
+ text_view.set_buffer(text_buffer)
+ text_view.set_size_request(0, int(SIZE_Y * 0.5))
+ text_view.set_editable(True)
+ text_view.set_cursor_visible(True)
+ text_view.set_show_line_numbers(True)
+ text_view.set_wrap_mode(Gtk.WrapMode.CHAR)
+ text_view.set_insert_spaces_instead_of_tabs(True)
+ text_view.set_tab_width(2)
+ text_view.set_auto_indent(True)
+ text_view.modify_font(
+ Pango.FontDescription("Monospace " +
+ str(font_zoom(style.FONT_SIZE))))
+
+ codesw = Gtk.ScrolledWindow()
+ codesw.set_policy(Gtk.PolicyType.AUTOMATIC,
+ Gtk.PolicyType.AUTOMATIC)
+ codesw.add(text_view)
+
+ tabdex = self.get_n_pages() + 1
+ if label:
+ tablabel = TabLabel(codesw, label, self)
+ else:
+ tablabel = TabLabel(codesw,
+ _("New Source File %d" % tabdex),
+ self)
+ tablabel.connect("tab-close", self._tab_closed_cb)
+ codesw.show_all()
+ index = self.append_page(codesw,
+ tablabel)
+ self.props.page = index # Set new page as active tab
+
+ def get_text_buffer(self):
+ tab = self.get_nth_page(self.get_current_page()).get_children()
+ text_buffer = tab[0].get_buffer()
+ return text_buffer
+
+ def get_text_view(self):
+ tab = self.get_nth_page(self.get_current_page()).get_children()
+ text_view = tab[0]
+ return text_view
+
+ def _purify_file(self, label):
+ import unicodedata
+
+ if not label.endswith(".py"):
+ label = label + ".py"
+
+ label = label.replace(" ", "_")
+ if isinstance(label, unicode):
+ label = \
+ unicodedata.normalize('NFKD', label).encode('ascii', 'ignore')
+
+ return label
+
+ def get_all_data(self):
+ # Returns all the names of files and the buffer contents too.
+ names = []
+ contents = []
+ for i in range(0, self.get_n_pages()):
+ child = self.get_nth_page(i)
+ text_buffer = child.get_children()[0].get_buffer()
+ text = text_buffer.get_text(*text_buffer.get_bounds(),
+ include_hidden_chars=True)
+ contents.append(text)
+
+ label = self._purify_file(self.get_tab_label(child).get_text())
+
+ names.append(label)
+
+ return (names, contents)
+
+ def get_current_file_name(self):
+ child = self.get_nth_page(self.get_current_page())
+ label = self.get_tab_label(child).get_text()
+ label = self._purify_file(label)
+
+ return label
+
+ def child_exited_cb(self, *args):
+ """Called whenever a child exits. If there's a handler, runadd it."""
+ h, self.activity._child_exited_handler = \
+ self.activity._child_exited_handler, None
+ if h is not None:
+ h()
+
+ def _tab_closed_cb(self, notebook, child):
+ index = self.page_num(child)
+ self.remove_page(index)
+ try:
+ del self.activity.session_data[index]
+ except IndexError:
+ pass