diff options
Diffstat (limited to 'grc/gui/Notebook.py')
-rw-r--r-- | grc/gui/Notebook.py | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/grc/gui/Notebook.py b/grc/gui/Notebook.py new file mode 100644 index 0000000000..21db913c0e --- /dev/null +++ b/grc/gui/Notebook.py @@ -0,0 +1,187 @@ +""" +Copyright 2008, 2009, 2011 Free Software Foundation, Inc. +This file is part of GNU Radio + +GNU Radio Companion 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. + +GNU Radio Companion 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 Street, Fifth Floor, Boston, MA 02110-1301, USA +""" + +from __future__ import absolute_import +import os +import logging + +from gi.repository import Gtk, Gdk, GObject + +from . import Actions +from .StateCache import StateCache +from .Constants import MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT +from .DrawingArea import DrawingArea + + +log = logging.getLogger(__name__) + + +class Notebook(Gtk.Notebook): + def __init__(self): + Gtk.Notebook.__init__(self) + log.debug("notebook()") + self.app = Gtk.Application.get_default() + self.current_page = None + + self.set_show_border(False) + self.set_scrollable(True) + self.connect('switch-page', self._handle_page_change) + + self.add_events(Gdk.EventMask.SCROLL_MASK) + self.connect('scroll-event', self._handle_scroll) + self._ignore_consecutive_scrolls = 0 + + def _handle_page_change(self, notebook, page, page_num): + """ + Handle a page change. When the user clicks on a new tab, + reload the flow graph to update the vars window and + call handle states (select nothing) to update the buttons. + + Args: + notebook: the notebook + page: new page + page_num: new page number + """ + self.current_page = self.get_nth_page(page_num) + Actions.PAGE_CHANGE() + + def _handle_scroll(self, widget, event): + # Not sure how to handle this at the moment. + natural = True + # Slow it down + if self._ignore_consecutive_scrolls == 0: + if event.direction in (Gdk.ScrollDirection.UP, Gdk.ScrollDirection.LEFT): + if natural: + self.prev_page() + else: + self.next_page() + elif event.direction in (Gdk.ScrollDirection.DOWN, Gdk.ScrollDirection.RIGHT): + if natural: + self.next_page() + else: + self.prev_page() + self._ignore_consecutive_scrolls = 3 + else: + self._ignore_consecutive_scrolls -= 1 + return False + + +class Page(Gtk.HBox): + """A page in the notebook.""" + + def __init__(self, main_window, flow_graph, file_path=''): + """ + Page constructor. + + Args: + main_window: main window + file_path: path to a flow graph file + """ + Gtk.HBox.__init__(self) + + self.main_window = main_window + self.flow_graph = flow_graph + self.file_path = file_path + + self.process = None + self.saved = True + + # import the file + initial_state = flow_graph.parent_platform.parse_flow_graph(file_path) + flow_graph.import_data(initial_state) + self.state_cache = StateCache(initial_state) + + # tab box to hold label and close button + self.label = Gtk.Label() + image = Gtk.Image.new_from_icon_name('window-close', Gtk.IconSize.MENU) + image_box = Gtk.HBox(homogeneous=False, spacing=0) + image_box.pack_start(image, True, False, 0) + button = Gtk.Button() + button.connect("clicked", self._handle_button) + button.set_relief(Gtk.ReliefStyle.NONE) + button.add(image_box) + + tab = self.tab = Gtk.HBox(homogeneous=False, spacing=0) + tab.pack_start(self.label, False, False, 0) + tab.pack_start(button, False, False, 0) + tab.show_all() + + # setup scroll window and drawing area + self.drawing_area = DrawingArea(flow_graph) + flow_graph.drawing_area = self.drawing_area + + self.scrolled_window = Gtk.ScrolledWindow() + self.scrolled_window.set_size_request(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT) + self.scrolled_window.set_policy(Gtk.PolicyType.ALWAYS, Gtk.PolicyType.ALWAYS) + self.scrolled_window.connect('key-press-event', self._handle_scroll_window_key_press) + + self.scrolled_window.add(self.drawing_area) + self.pack_start(self.scrolled_window, True, True, 0) + self.show_all() + + def _handle_scroll_window_key_press(self, widget, event): + is_ctrl_pg = ( + event.state & Gdk.ModifierType.CONTROL_MASK and + event.keyval in (Gdk.KEY_Page_Up, Gdk.KEY_Page_Down) + ) + if is_ctrl_pg: + return self.get_parent().event(event) + + def get_generator(self): + """ + Get the generator object for this flow graph. + + Returns: + generator + """ + platform = self.flow_graph.parent_platform + return platform.Generator(self.flow_graph, self.file_path) + + def _handle_button(self, button): + """ + The button was clicked. + Make the current page selected, then close. + + Args: + the: button + """ + self.main_window.page_to_be_closed = self + Actions.FLOW_GRAPH_CLOSE() + + def set_markup(self, markup): + """ + Set the markup in this label. + + Args: + markup: the new markup text + """ + self.label.set_markup(markup) + + def get_read_only(self): + """ + Get the read-only state of the file. + Always false for empty path. + + Returns: + true for read-only + """ + if not self.file_path: + return False + return (os.path.exists(self.file_path) and + not os.access(self.file_path, os.W_OK)) |