summaryrefslogtreecommitdiff
path: root/grc
diff options
context:
space:
mode:
Diffstat (limited to 'grc')
-rw-r--r--grc/base/Block.py13
-rw-r--r--grc/gui/ActionHandler.py40
-rw-r--r--grc/gui/Actions.py13
-rw-r--r--grc/gui/Bars.py4
-rw-r--r--grc/gui/Dialogs.py50
-rw-r--r--grc/gui/MainWindow.py27
-rw-r--r--grc/gui/Preferences.py6
-rw-r--r--grc/python/flow_graph.tmpl10
8 files changed, 123 insertions, 40 deletions
diff --git a/grc/base/Block.py b/grc/base/Block.py
index c440f00b6b..a14ffd92fc 100644
--- a/grc/base/Block.py
+++ b/grc/base/Block.py
@@ -141,6 +141,17 @@ class Block(Element):
and (self._key != "pad_source") \
and (self._key != "pad_sink"))
+ if is_not_virtual_or_pad:
+ self.get_params().append(self.get_parent().get_parent().Param(
+ block=self,
+ n=odict({'name': 'Block Alias',
+ 'key': 'alias',
+ 'type': 'string',
+ 'hide': 'part',
+ 'tab': ADVANCED_PARAM_TAB
+ })
+ ))
+
if (len(sources) or len(sinks)) and is_not_virtual_or_pad:
self.get_params().append(self.get_parent().get_parent().Param(
block=self,
@@ -434,5 +445,3 @@ class Block(Element):
elif len(bussrcs) > 0:
self.bussify({'name':'bus','type':'bus'}, 'source')
self.bussify({'name':'bus','type':'bus'}, 'source')
-
-
diff --git a/grc/gui/ActionHandler.py b/grc/gui/ActionHandler.py
index 1db333fc5a..6ad2d5576f 100644
--- a/grc/gui/ActionHandler.py
+++ b/grc/gui/ActionHandler.py
@@ -49,7 +49,7 @@ class ActionHandler:
ActionHandler constructor.
Create the main window, setup the message handler, import the preferences,
and connect all of the action handlers. Finally, enter the gtk main loop and block.
-
+
Args:
file_paths: a list of flow graph file passed from command line
platform: platform module
@@ -81,7 +81,7 @@ class ActionHandler:
* some keys are ignored by the accelerators like the direction keys,
* some keys are not registered to any accelerators but are still used.
When not in focus, gtk and the accelerators handle the the key press.
-
+
Returns:
false to let gtk handle the key action
"""
@@ -95,7 +95,7 @@ class ActionHandler:
Handle the delete event from the main window.
Generated by pressing X to close, alt+f4, or right click+close.
This method in turns calls the state handler to quit.
-
+
Returns:
true
"""
@@ -117,7 +117,7 @@ class ActionHandler:
Actions.FLOW_GRAPH_SCREEN_CAPTURE, Actions.HELP_WINDOW_DISPLAY,
Actions.TYPES_WINDOW_DISPLAY, Actions.TOGGLE_BLOCKS_WINDOW,
Actions.TOGGLE_REPORTS_WINDOW, Actions.TOGGLE_HIDE_DISABLED_BLOCKS,
- Actions.TOOLS_RUN_FDESIGN,
+ Actions.TOOLS_RUN_FDESIGN, Actions.TOGGLE_SCROLL_LOCK, Actions.CLEAR_REPORTS,
): action.set_sensitive(True)
if ParseXML.xml_failures:
Messages.send_xml_errors_if_any(ParseXML.xml_failures)
@@ -135,6 +135,7 @@ class ActionHandler:
self.main_window.btwin.search_entry.hide()
Actions.TOGGLE_REPORTS_WINDOW.set_active(Preferences.reports_window_visibility())
Actions.TOGGLE_BLOCKS_WINDOW.set_active(Preferences.blocks_window_visibility())
+ Actions.TOGGLE_SCROLL_LOCK.set_active(Preferences.scroll_lock())
elif action == Actions.APPLICATION_QUIT:
if self.main_window.close_pages():
gtk.main_quit()
@@ -174,14 +175,14 @@ class ActionHandler:
self.get_page().get_state_cache().save_new_state(self.get_flow_graph().export_data())
self.get_page().set_saved(False)
##################################################
- # Create heir block
+ # Create heir block
##################################################
elif action == Actions.BLOCK_CREATE_HIER:
# keeping track of coordinates for pasting later
coords = self.get_flow_graph().get_selected_blocks()[0].get_coordinate()
x,y = coords
- x_min = x
+ x_min = x
y_min = y
pads = [];
@@ -200,9 +201,9 @@ class ActionHandler:
# If a block parameter exists that is a parameter, create a parameter for it
if param.get_value() == flow_param.get_id():
params.append(param.get_value())
-
-
- # keep track of x,y mins for pasting later
+
+
+ # keep track of x,y mins for pasting later
(x,y) = block.get_coordinate()
if x < x_min:
x_min = x
@@ -214,8 +215,8 @@ class ActionHandler:
# Get id of connected blocks
source_id = connection.get_source().get_parent().get_id()
sink_id = connection.get_sink().get_parent().get_id()
-
- # If connected block is not in the list of selected blocks create a pad for it
+
+ # If connected block is not in the list of selected blocks create a pad for it
if self.get_flow_graph().get_block(source_id) not in self.get_flow_graph().get_selected_blocks():
pads.append({'key': connection.get_sink().get_key(), 'coord': connection.get_source().get_coordinate(), 'block_id' : block.get_id(), 'direction': 'source'})
@@ -241,7 +242,7 @@ class ActionHandler:
# Remove the default samp_rate variable block that is created
remove_me = self.get_flow_graph().get_block("samp_rate")
- self.get_flow_graph().remove_element(remove_me)
+ self.get_flow_graph().remove_element(remove_me)
# Add the param blocks along the top of the window
@@ -297,9 +298,9 @@ class ActionHandler:
# Connect the pad to the proper sinks
new_connection = self.get_flow_graph().connect(pad_source,sink)
- # update the new heir block flow graph
+ # update the new heir block flow graph
self.get_flow_graph().update()
-
+
##################################################
# Move/Rotate/Delete/Create
@@ -373,6 +374,13 @@ class ActionHandler:
else:
self.main_window.btwin.hide()
Preferences.blocks_window_visibility(visible)
+ elif action == Actions.TOGGLE_SCROLL_LOCK:
+ visible = action.get_active()
+ self.main_window.text_display.scroll_lock = visible
+ if visible:
+ self.main_window.text_display.scroll_to_end()
+ elif action == Actions.CLEAR_REPORTS:
+ self.main_window.text_display.clear()
elif action == Actions.TOGGLE_HIDE_DISABLED_BLOCKS:
Actions.NOTHING_SELECT()
##################################################
@@ -495,7 +503,7 @@ class ActionHandler:
self.get_flow_graph()._old_selected_port = None
self.get_flow_graph()._new_selected_port = None
Actions.ELEMENT_CREATE()
-
+
elif action == Actions.BUSSIFY_SINKS:
n = {'name':'bus', 'type':'bus'}
for b in self.get_flow_graph().get_selected_blocks():
@@ -563,7 +571,7 @@ class ExecFlowGraphThread(Thread):
def __init__ (self, action_handler):
"""
ExecFlowGraphThread constructor.
-
+
Args:
action_handler: an instance of an ActionHandler
"""
diff --git a/grc/gui/Actions.py b/grc/gui/Actions.py
index af07121f3a..3aa9e61472 100644
--- a/grc/gui/Actions.py
+++ b/grc/gui/Actions.py
@@ -33,10 +33,10 @@ def handle_key_press(event):
"""
Call the action associated with the key press event.
Both the key value and the mask must have a match.
-
+
Args:
event: a gtk key press event
-
+
Returns:
true if handled
"""
@@ -281,6 +281,10 @@ TOGGLE_BLOCKS_WINDOW = ToggleAction(
tooltip='Toggle visibility of the block tree widget',
keypresses=(gtk.keysyms.b, gtk.gdk.CONTROL_MASK),
)
+TOGGLE_SCROLL_LOCK = ToggleAction(
+ label='_Reports Scroll Lock',
+ tooltip='Toggle scroll lock for the report window',
+)
ABOUT_WINDOW_DISPLAY = Action(
label='_About',
tooltip='About this program',
@@ -345,6 +349,11 @@ FIND_BLOCKS = Action(
keypresses=(gtk.keysyms.f, gtk.gdk.CONTROL_MASK,
gtk.keysyms.slash, NO_MODS_MASK),
)
+CLEAR_REPORTS = Action(
+ label='_Clear Reports',
+ tooltip='Clear Reports',
+ stock_id=gtk.STOCK_CLEAR,
+)
OPEN_HIER = Action(
label='Open H_ier',
tooltip='Open the source of the selected hierarchical block',
diff --git a/grc/gui/Bars.py b/grc/gui/Bars.py
index da1b1469e1..11e35c992b 100644
--- a/grc/gui/Bars.py
+++ b/grc/gui/Bars.py
@@ -55,6 +55,7 @@ TOOLBAR_LIST = (
Actions.RELOAD_BLOCKS,
Actions.OPEN_HIER,
Actions.BUSSIFY_SOURCES,
+ Actions.CLEAR_REPORTS,
)
##The list of actions and categories for the menu bar.
@@ -91,7 +92,10 @@ MENU_BAR_LIST = (
]),
(gtk.Action('View', '_View', None, None), [
Actions.TOGGLE_BLOCKS_WINDOW,
+ None,
Actions.TOGGLE_REPORTS_WINDOW,
+ Actions.TOGGLE_SCROLL_LOCK,
+ Actions.CLEAR_REPORTS,
None,
Actions.ERRORS_WINDOW_DISPLAY,
Actions.FIND_BLOCKS,
diff --git a/grc/gui/Dialogs.py b/grc/gui/Dialogs.py
index 873bac9783..0ffba8e0e8 100644
--- a/grc/gui/Dialogs.py
+++ b/grc/gui/Dialogs.py
@@ -21,6 +21,7 @@ import pygtk
pygtk.require('2.0')
import gtk
import Utils
+import Actions
class TextDisplay(gtk.TextView):
"""A non editable gtk text view."""
@@ -28,7 +29,7 @@ class TextDisplay(gtk.TextView):
def __init__(self, text=''):
"""
TextDisplay constructor.
-
+
Args:
text: the text to display (string)
"""
@@ -40,11 +41,19 @@ class TextDisplay(gtk.TextView):
self.set_cursor_visible(False)
self.set_wrap_mode(gtk.WRAP_WORD_CHAR)
+ # Added for scroll locking
+ self.scroll_lock = True
+
+ # Add a signal for populating the popup menu
+ self.connect("populate-popup", self.populate_popup)
+
def insert(self, line):
# make backspaces work
line = self._consume_backspaces(line)
# add the remaining text to buffer
self.get_buffer().insert(self.get_buffer().get_end_iter(), line)
+ # Automatically scroll on insert
+ self.scroll_to_end()
def _consume_backspaces(self, line):
"""removes text from the buffer if line starts with \b*"""
@@ -61,19 +70,52 @@ class TextDisplay(gtk.TextView):
# return remaining text
return line[back_count:]
+ def scroll_to_end(self):
+ if self.scroll_lock:
+ buffer = self.get_buffer()
+ buffer.move_mark(buffer.get_insert(), buffer.get_end_iter())
+ self.scroll_to_mark(buffer.get_insert(), 0.0)
+
+ def clear(self):
+ buffer = self.get_buffer()
+ buffer.delete(buffer.get_start_iter(), buffer.get_end_iter())
+
+ # Callback functions to handle the scrolling lock and clear context menus options
+ # Action functions are set by the ActionHandler's init function
+ def clear_cb(self, menu_item, web_view):
+ Actions.CLEAR_REPORTS()
+
+ def scroll_back_cb(self, menu_item, web_view):
+ Actions.TOGGLE_SCROLL_LOCK()
+
+ def populate_popup(self, view, menu):
+ """Create a popup menu for the scroll lock and clear functions"""
+ menu.append(gtk.SeparatorMenuItem())
+
+ lock = gtk.CheckMenuItem("Scroll Lock")
+ menu.append(lock)
+ lock.set_active(self.scroll_lock)
+ lock.connect('activate', self.scroll_back_cb, view)
+
+ clear = gtk.ImageMenuItem(gtk.STOCK_CLEAR)
+ menu.append(clear)
+ clear.connect('activate', self.clear_cb, view)
+ menu.show_all()
+ return False
+
def MessageDialogHelper(type, buttons, title=None, markup=None):
"""
Create a modal message dialog and run it.
-
+
Args:
type: the type of message: gtk.MESSAGE_INFO, gtk.MESSAGE_WARNING, gtk.MESSAGE_QUESTION or gtk.MESSAGE_ERROR
buttons: the predefined set of buttons to use:
gtk.BUTTONS_NONE, gtk.BUTTONS_OK, gtk.BUTTONS_CLOSE, gtk.BUTTONS_CANCEL, gtk.BUTTONS_YES_NO, gtk.BUTTONS_OK_CANCEL
-
+
Args:
tittle: the title of the window (string)
markup: the message text with pango markup
-
+
Returns:
the gtk response from run()
"""
diff --git a/grc/gui/MainWindow.py b/grc/gui/MainWindow.py
index 067131ec96..f309d34a2e 100644
--- a/grc/gui/MainWindow.py
+++ b/grc/gui/MainWindow.py
@@ -121,7 +121,7 @@ class MainWindow(gtk.Window):
Handle the delete event from the main window.
Generated by pressing X to close, alt+f4, or right click+close.
This method in turns calls the state handler to quit.
-
+
Returns:
true
"""
@@ -133,7 +133,7 @@ class MainWindow(gtk.Window):
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
@@ -150,12 +150,11 @@ class MainWindow(gtk.Window):
def add_report_line(self, line):
"""
Place line at the end of the text buffer, then scroll its window all the way down.
-
+
Args:
line: the new text
"""
self.text_display.insert(line)
- self.text_display.scroll_mark_onscreen(self.text_display.get_buffer().get_insert())
############################################################
# Pages: create and close
@@ -165,7 +164,7 @@ class MainWindow(gtk.Window):
"""
Create a new notebook page.
Set the tab to be selected.
-
+
Args:
file_path: optional file to load into the flow graph
show: true if the page should be shown after loading
@@ -203,7 +202,7 @@ class MainWindow(gtk.Window):
def close_pages(self):
"""
Close all the pages in this notebook.
-
+
Returns:
true if all closed
"""
@@ -228,7 +227,7 @@ class MainWindow(gtk.Window):
Close the current page.
If the notebook becomes empty, and ensure is true,
call new page upon exit to ensure that at least one page exists.
-
+
Args:
ensure: boolean
"""
@@ -258,7 +257,7 @@ class MainWindow(gtk.Window):
Set the title of the main window.
Set the titles on the page tabs.
Show/hide the reports window.
-
+
Args:
title: the window title
"""
@@ -286,7 +285,7 @@ class MainWindow(gtk.Window):
def get_page(self):
"""
Get the selected page.
-
+
Returns:
the selected page
"""
@@ -295,7 +294,7 @@ class MainWindow(gtk.Window):
def get_flow_graph(self):
"""
Get the selected flow graph.
-
+
Returns:
the selected flow graph
"""
@@ -317,7 +316,7 @@ class MainWindow(gtk.Window):
def _set_page(self, page):
"""
Set the current page.
-
+
Args:
page: the page widget
"""
@@ -327,7 +326,7 @@ class MainWindow(gtk.Window):
def _save_changes(self):
"""
Save changes to flow graph?
-
+
Returns:
true if yes
"""
@@ -339,7 +338,7 @@ class MainWindow(gtk.Window):
def _get_files(self):
"""
Get the file names for all the pages, in order.
-
+
Returns:
list of file paths
"""
@@ -348,7 +347,7 @@ class MainWindow(gtk.Window):
def _get_pages(self):
"""
Get a list of all pages in the notebook.
-
+
Returns:
list of pages
"""
diff --git a/grc/gui/Preferences.py b/grc/gui/Preferences.py
index b15fb9738b..a6bd0d6603 100644
--- a/grc/gui/Preferences.py
+++ b/grc/gui/Preferences.py
@@ -95,3 +95,9 @@ def blocks_window_visibility(visible=None):
else:
try: return _config_parser.getboolean('main', 'blocks_window_visible')
except: return True
+
+def scroll_lock(visible=None):
+ if visible is not None: _config_parser.set('main', 'scroll_lock', visible)
+ else:
+ try: return _config_parser.getboolean('main', 'scroll_lock')
+ except: return True
diff --git a/grc/python/flow_graph.tmpl b/grc/python/flow_graph.tmpl
index e1b091612b..52582384aa 100644
--- a/grc/python/flow_graph.tmpl
+++ b/grc/python/flow_graph.tmpl
@@ -161,6 +161,9 @@ gr.io_signaturev($(len($io_sigs)), $(len($io_sigs)), [$(', '.join($size_strs))])
$indent($blk.get_make())
#else
self.$blk.get_id() = $indent($blk.get_make())
+ #if $blk.has_param('alias') and $blk.get_param('alias').get_evaluated()
+ (self.$blk.get_id()).set_block_alias("$blk.get_param('alias').get_evaluated()")
+ #end if
#if $blk.has_param('affinity') and $blk.get_param('affinity').get_evaluated()
(self.$blk.get_id()).set_processor_affinity($blk.get_param('affinity').get_evaluated())
#end if
@@ -329,7 +332,11 @@ if __name__ == '__main__':
tb.wait()
qapp.connect(qapp, Qt.SIGNAL("aboutToQuit()"), quitting)
#for $m in $monitors
- (tb.$m.get_id()).start()
+ if $m.has_param('en'):
+ if $m.get_param('en').get_value():
+ (tb.$m.get_id()).start()
+ else:
+ sys.stderr.write("Monitor '{0}' does not have an enable ('en') parameter.".format("tb.$m.get_id()"))
#end for
qapp.exec_()
tb = None #to clean up Qt widgets
@@ -360,4 +367,3 @@ if __name__ == '__main__':
tb.wait()
#end if
#end if
-