diff options
Diffstat (limited to 'notebook.py')
-rw-r--r-- | notebook.py | 238 |
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 |