diff options
Diffstat (limited to 'grc')
-rw-r--r-- | grc/base/Block.py | 13 | ||||
-rw-r--r-- | grc/gui/ActionHandler.py | 40 | ||||
-rw-r--r-- | grc/gui/Actions.py | 13 | ||||
-rw-r--r-- | grc/gui/Bars.py | 4 | ||||
-rw-r--r-- | grc/gui/Dialogs.py | 50 | ||||
-rw-r--r-- | grc/gui/MainWindow.py | 27 | ||||
-rw-r--r-- | grc/gui/Preferences.py | 6 | ||||
-rw-r--r-- | grc/python/flow_graph.tmpl | 10 |
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 - |