summaryrefslogtreecommitdiff
path: root/grc
diff options
context:
space:
mode:
Diffstat (limited to 'grc')
-rw-r--r--grc/gui/ActionHandler.py9
-rw-r--r--grc/gui/Actions.py5
-rw-r--r--grc/gui/Bars.py124
-rw-r--r--grc/gui/MainWindow.py10
-rw-r--r--grc/gui/Preferences.py35
5 files changed, 139 insertions, 44 deletions
diff --git a/grc/gui/ActionHandler.py b/grc/gui/ActionHandler.py
index a2c48a7c52..ebf701553d 100644
--- a/grc/gui/ActionHandler.py
+++ b/grc/gui/ActionHandler.py
@@ -480,10 +480,14 @@ class ActionHandler:
self.get_flow_graph()._options_block.get_param('generate_options').set_value(args[0])
self.get_flow_graph().update()
elif action == Actions.FLOW_GRAPH_OPEN:
- file_paths = OpenFlowGraphFileDialog(self.get_page().get_file_path()).run()
+ file_paths = args if args else OpenFlowGraphFileDialog(self.get_page().get_file_path()).run()
if file_paths: #open a new page for each file, show only the first
for i,file_path in enumerate(file_paths):
self.main_window.new_page(file_path, show=(i==0))
+ Preferences.files_recent_add(file_path)
+ self.main_window.tool_bar.refresh_submenus()
+ self.main_window.menu_bar.refresh_submenus()
+
elif action == Actions.FLOW_GRAPH_OPEN_QSS_THEME:
file_paths = OpenQSSFileDialog(GR_PREFIX + '/share/gnuradio/themes/').run()
if file_paths:
@@ -513,6 +517,9 @@ class ActionHandler:
if file_path is not None:
self.get_page().set_file_path(file_path)
Actions.FLOW_GRAPH_SAVE()
+ Preferences.files_recent_add(file_path)
+ self.main_window.tool_bar.refresh_submenus()
+ self.main_window.menu_bar.refresh_submenus()
elif action == Actions.FLOW_GRAPH_SCREEN_CAPTURE:
file_path = SaveImageFileDialog(self.get_page().get_file_path()).run()
if file_path is not None:
diff --git a/grc/gui/Actions.py b/grc/gui/Actions.py
index c3ae6c971f..d646722df1 100644
--- a/grc/gui/Actions.py
+++ b/grc/gui/Actions.py
@@ -183,6 +183,11 @@ FLOW_GRAPH_OPEN = Action(
stock_id=gtk.STOCK_OPEN,
keypresses=(gtk.keysyms.o, gtk.gdk.CONTROL_MASK),
)
+FLOW_GRAPH_OPEN_RECENT = Action(
+ label='Open _Recent',
+ tooltip='Open a recently used flow graph',
+ stock_id=gtk.STOCK_OPEN,
+)
FLOW_GRAPH_SAVE = Action(
label='_Save',
tooltip='Save the current flow graph',
diff --git a/grc/gui/Bars.py b/grc/gui/Bars.py
index 2ab5b2a712..8a04b1c8f7 100644
--- a/grc/gui/Bars.py
+++ b/grc/gui/Bars.py
@@ -1,5 +1,5 @@
"""
-Copyright 2007, 2008, 2009 Free Software Foundation, Inc.
+Copyright 2007, 2008, 2009, 2015 Free Software Foundation, Inc.
This file is part of GNU Radio
GNU Radio Companion is free software; you can redistribute it and/or
@@ -26,8 +26,8 @@ from . import Actions
# The list of actions for the toolbar.
TOOLBAR_LIST = (
- Actions.FLOW_GRAPH_NEW,
- Actions.FLOW_GRAPH_OPEN,
+ (Actions.FLOW_GRAPH_NEW, 'flow_graph_new'),
+ (Actions.FLOW_GRAPH_OPEN, 'flow_graph_recent'),
Actions.FLOW_GRAPH_SAVE,
Actions.FLOW_GRAPH_CLOSE,
None,
@@ -64,6 +64,7 @@ MENU_BAR_LIST = (
(gtk.Action('File', '_File', None, None), [
'flow_graph_new',
Actions.FLOW_GRAPH_OPEN,
+ 'flow_graph_recent',
None,
Actions.FLOW_GRAPH_SAVE,
Actions.FLOW_GRAPH_SAVE_AS,
@@ -155,24 +156,90 @@ CONTEXT_MENU_LIST = [
]
-class Toolbar(gtk.Toolbar):
+class SubMenuCreator(object):
+
+ def __init__(self, generate_modes, action_handler_callback):
+ self.generate_modes = generate_modes
+ self.action_handler_callback = action_handler_callback
+ self.submenus = []
+
+ def create_submenu(self, action_tuple, item):
+ func = getattr(self, '_fill_' + action_tuple[1] + "_submenu")
+ self.submenus.append((action_tuple[0], func, item))
+ self.refresh_submenus()
+
+ def refresh_submenus(self):
+ for action, func, item in self.submenus:
+ try:
+ item.set_property("menu", func(action))
+ except TypeError:
+ item.set_property("submenu", func(action))
+ item.set_property('sensitive', True)
+
+ def callback_adaptor(self, item, action_key):
+ action, key = action_key
+ self.action_handler_callback(action, key)
+
+ def _fill_flow_graph_new_submenu(self, action):
+ """Sub menu to create flow-graph with pre-set generate mode"""
+ menu = gtk.Menu()
+ for key, name, default in self.generate_modes:
+ if default:
+ item = Actions.FLOW_GRAPH_NEW.create_menu_item()
+ item.set_label(name)
+ else:
+ item = gtk.MenuItem(name)
+ item.connect('activate', self.callback_adaptor, (action, key))
+ menu.append(item)
+ menu.show_all()
+ return menu
+
+ def _fill_flow_graph_recent_submenu(self, action):
+ """menu showing recent flow-graphs"""
+ import Preferences
+ menu = gtk.Menu()
+ recent_files = Preferences.files_recent()
+ if len(recent_files) > 0:
+ for i, file_name in enumerate(recent_files):
+ item = gtk.MenuItem("%d. %s" % (i+1, file_name))
+ item.connect('activate', self.callback_adaptor,
+ (action, file_name))
+ menu.append(item)
+ menu.show_all()
+ return menu
+ return None
+
+
+class Toolbar(gtk.Toolbar, SubMenuCreator):
"""The gtk toolbar with actions added from the toolbar list."""
- def __init__(self):
+ def __init__(self, generate_modes, action_handler_callback):
"""
Parse the list of action names in the toolbar list.
- Look up the action for each name in the action list and add it to the toolbar.
+ Look up the action for each name in the action list and add it to the
+ toolbar.
"""
gtk.Toolbar.__init__(self)
self.set_style(gtk.TOOLBAR_ICONS)
+ SubMenuCreator.__init__(self, generate_modes, action_handler_callback)
+
for action in TOOLBAR_LIST:
- if action: # add a tool item
+ if isinstance(action, tuple) and isinstance(action[1], str):
+ # create a button with a sub-menu
+ action[0].set_tool_item_type(gtk.MenuToolButton)
+ item = action[0].create_tool_item()
+ self.create_submenu(action, item)
+ self.refresh_submenus()
+
+ elif action is None:
+ item = gtk.SeparatorToolItem()
+
+ else:
+ action.set_tool_item_type(gtk.ToolButton)
item = action.create_tool_item()
# this reset of the tooltip property is required
# (after creating the tool item) for the tooltip to show
action.set_property('tooltip', action.get_property('tooltip'))
- else:
- item = gtk.SeparatorToolItem()
self.add(item)
@@ -202,42 +269,37 @@ class MenuHelperMixin(object):
return main
-class MenuBar(gtk.MenuBar, MenuHelperMixin):
+class MenuBar(gtk.MenuBar, MenuHelperMixin, SubMenuCreator):
"""The gtk menu bar with actions added from the menu bar list."""
def __init__(self, generate_modes, action_handler_callback):
"""
Parse the list of submenus from the menubar list.
For each submenu, get a list of action names.
- Look up the action for each name in the action list and add it to the submenu.
- Add the submenu to the menu bar.
+ Look up the action for each name in the action list and add it to the
+ submenu. Add the submenu to the menu bar.
"""
gtk.MenuBar.__init__(self)
- self.generate_modes = generate_modes
- self.action_handler_callback = action_handler_callback
+ SubMenuCreator.__init__(self, generate_modes, action_handler_callback)
for main_action, actions in MENU_BAR_LIST:
self.append(self._make_sub_menu(main_action, actions))
def create_flow_graph_new(self):
- """Sub menu to create flow-graph with pre-set generate mode"""
-
- def callback_adaptor(item, key):
- """Sets original FLOW_GRAPH_NEW action as source"""
- self.action_handler_callback(Actions.FLOW_GRAPH_NEW, key)
-
- sub_menu = gtk.Menu()
- for key, name, default in self.generate_modes:
- if default:
- item = Actions.FLOW_GRAPH_NEW.create_menu_item()
- item.set_label(name)
- else:
- item = gtk.MenuItem(name)
- item.connect('activate', callback_adaptor, key)
- sub_menu.append(item)
- sub_menu.show_all()
main = gtk.ImageMenuItem(gtk.STOCK_NEW)
main.set_label(Actions.FLOW_GRAPH_NEW.get_label())
- main.set_submenu(sub_menu)
+ func = self._fill_flow_graph_new_submenu
+ self.submenus.append((Actions.FLOW_GRAPH_NEW, func, main))
+ self.refresh_submenus()
+ return main
+
+ def create_flow_graph_recent(self):
+ main = gtk.ImageMenuItem(gtk.STOCK_OPEN)
+ main.set_label(Actions.FLOW_GRAPH_OPEN_RECENT.get_label())
+ func = self._fill_flow_graph_recent_submenu
+ self.submenus.append((Actions.FLOW_GRAPH_OPEN, func, main))
+ self.refresh_submenus()
+ if main.get_submenu() is None:
+ main.set_property('sensitive', False)
return main
diff --git a/grc/gui/MainWindow.py b/grc/gui/MainWindow.py
index f658a85062..08cef11639 100644
--- a/grc/gui/MainWindow.py
+++ b/grc/gui/MainWindow.py
@@ -76,6 +76,8 @@ class MainWindow(gtk.Window):
generate_modes = [
(o.get_key(), o.get_name(), o.get_key() == generate_mode_default)
for o in gen_opts.get_options()]
+ # load preferences
+ Preferences.load(platform)
#setup window
gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
vbox = gtk.VBox()
@@ -83,9 +85,10 @@ class MainWindow(gtk.Window):
self.add(vbox)
#create the menu bar and toolbar
self.add_accel_group(Actions.get_accel_group())
- menu_bar = Bars.MenuBar(generate_modes, action_handler_callback)
- vbox.pack_start(menu_bar, False)
- vbox.pack_start(Bars.Toolbar(), False)
+ self.menu_bar = Bars.MenuBar(generate_modes, action_handler_callback)
+ vbox.pack_start(self.menu_bar, False)
+ self.tool_bar = Bars.Toolbar(generate_modes, action_handler_callback )
+ vbox.pack_start(self.tool_bar, False)
vbox.pack_start(self.hpaned)
#create the notebook
self.notebook = gtk.Notebook()
@@ -110,7 +113,6 @@ class MainWindow(gtk.Window):
self.reports_scrolled_window.set_size_request(-1, DEFAULT_REPORTS_WINDOW_WIDTH)
self.flow_graph_vpaned.pack2(self.reports_scrolled_window, False) #dont allow resize
#load preferences and show the main window
- Preferences.load(platform)
self.resize(*Preferences.main_window_size())
self.flow_graph_vpaned.set_position(Preferences.reports_window_position())
self.hpaned.set_position(Preferences.blocks_window_position())
diff --git a/grc/gui/Preferences.py b/grc/gui/Preferences.py
index a5a7fa91b5..54dab38282 100644
--- a/grc/gui/Preferences.py
+++ b/grc/gui/Preferences.py
@@ -41,8 +41,11 @@ def load(platform):
global _platform
_platform = platform
# create sections
- _config_parser.add_section('main')
- _config_parser.add_section('files_open')
+ for section in ['main', 'files_open', 'files_recent']:
+ try:
+ _config_parser.add_section(section)
+ except Exception, e:
+ print e
try:
_config_parser.read(_platform.get_prefs_file())
except Exception as err:
@@ -91,21 +94,37 @@ def file_open(filename=None):
return entry('file_open', filename, default='')
-def files_open(files=None):
+def files_lists(key, files=None):
if files is not None:
- _config_parser.remove_section('files_open') # clear section
- _config_parser.add_section('files_open')
+ _config_parser.remove_section(key) # clear section
+ _config_parser.add_section(key)
for i, filename in enumerate(files):
- _config_parser.set('files_open', 'file_open_%d' % i, filename)
+ _config_parser.set(key, '%s_%d' % (key, i), filename)
else:
try:
- files = [value for name, value in _config_parser.items('files_open')
- if name.startswith('file_open_')]
+ files = [value for name, value in _config_parser.items(key)
+ if name.startswith('%s_' % key)]
except ConfigParser.Error:
files = []
return files
+def files_open(files=None):
+ return files_lists('files_open', files)
+
+def files_recent(files=None):
+ return files_lists('files_recent', files)
+
+def files_recent_add(file_name):
+ import os
+ # double check file_name
+ if os.path.exists(file_name):
+ recent_files = files_recent()
+ if file_name in recent_files:
+ recent_files.remove(file_name) # attempt removal
+ recent_files.insert(0, file_name) # insert at start
+ files_recent(recent_files[:10]) # keep up to 10 files
+
def reports_window_position(pos=None):
return entry('reports_window_position', pos, default=-1) or 1