diff options
-rw-r--r-- | grc/base/Block.py | 12 | ||||
-rw-r--r-- | grc/gui/ActionHandler.py | 8 | ||||
-rw-r--r-- | grc/gui/Actions.py | 5 | ||||
-rw-r--r-- | grc/gui/Bars.py | 1 | ||||
-rw-r--r-- | grc/gui/Block.py | 28 | ||||
-rw-r--r-- | grc/gui/Colors.py | 1 | ||||
-rw-r--r-- | grc/gui/FlowGraph.py | 8 | ||||
-rw-r--r-- | grc/gui/Param.py | 53 | ||||
-rw-r--r-- | grc/gui/PropsDialog.py | 8 | ||||
-rw-r--r-- | grc/python/Param.py | 22 |
10 files changed, 125 insertions, 21 deletions
diff --git a/grc/base/Block.py b/grc/base/Block.py index 128cc5ecbe..cadff12c0a 100644 --- a/grc/base/Block.py +++ b/grc/base/Block.py @@ -185,6 +185,17 @@ class Block(Element): }) )) + self.get_params().append(self.get_parent().get_parent().Param( + block=self, + n=odict({'name': 'Comment', + 'key': 'comment', + 'type': 'multiline', + 'hide': 'part', + 'value': '', + 'tab': ADVANCED_PARAM_TAB + }) + )) + def back_ofthe_bus(self, portlist): portlist.sort(key=lambda p: p._type == 'bus') @@ -226,6 +237,7 @@ class Block(Element): def get_children(self): return self.get_ports() + self.get_params() def get_children_gui(self): return self.get_ports_gui() + self.get_params() def get_block_wrapper_path(self): return self._block_wrapper_path + def get_comment(self): return self.get_param('comment').get_value() ############################################## # Access Params diff --git a/grc/gui/ActionHandler.py b/grc/gui/ActionHandler.py index 6dc088c36d..83ce5ff8ce 100644 --- a/grc/gui/ActionHandler.py +++ b/grc/gui/ActionHandler.py @@ -122,7 +122,8 @@ class ActionHandler: Actions.TOGGLE_REPORTS_WINDOW, Actions.TOGGLE_HIDE_DISABLED_BLOCKS, Actions.TOOLS_RUN_FDESIGN, Actions.TOGGLE_SCROLL_LOCK, Actions.CLEAR_REPORTS, Actions.SAVE_REPORTS, - Actions.TOGGLE_AUTO_HIDE_PORT_LABELS, Actions.TOGGLE_SNAP_TO_GRID + Actions.TOGGLE_AUTO_HIDE_PORT_LABELS, Actions.TOGGLE_SNAP_TO_GRID, + Actions.TOGGLE_SHOW_BLOCK_COMMENTS, ): action.set_sensitive(True) if ParseXML.xml_failures: Messages.send_xml_errors_if_any(ParseXML.xml_failures) @@ -143,7 +144,8 @@ class ActionHandler: Actions.TOGGLE_BLOCKS_WINDOW, Actions.TOGGLE_AUTO_HIDE_PORT_LABELS, Actions.TOGGLE_SCROLL_LOCK, - Actions.TOGGLE_SNAP_TO_GRID + Actions.TOGGLE_SNAP_TO_GRID, + Actions.TOGGLE_SHOW_BLOCK_COMMENTS, ): action.load_from_preferences() elif action == Actions.APPLICATION_QUIT: if self.main_window.close_pages(): @@ -401,6 +403,8 @@ class ActionHandler: page.get_flow_graph().create_shapes() elif action == Actions.TOGGLE_SNAP_TO_GRID: action.save_to_preferences() + elif action == Actions.TOGGLE_SHOW_BLOCK_COMMENTS: + action.save_to_preferences() ################################################## # Param Modifications ################################################## diff --git a/grc/gui/Actions.py b/grc/gui/Actions.py index 26c827f346..b2b3a76386 100644 --- a/grc/gui/Actions.py +++ b/grc/gui/Actions.py @@ -263,6 +263,11 @@ TOGGLE_AUTO_HIDE_PORT_LABELS = ToggleAction( tooltip='Automatically hide port labels', preference_name='auto_hide_port_labels' ) +TOGGLE_SHOW_BLOCK_COMMENTS = ToggleAction( + label='Show Block Comments', + tooltip="Show comment beneath each block", + preference_name='show_block_comments' +) BLOCK_CREATE_HIER = Action( label='C_reate Hier', tooltip='Create hier block from selected blocks', diff --git a/grc/gui/Bars.py b/grc/gui/Bars.py index 6ce614bc99..40ce20536c 100644 --- a/grc/gui/Bars.py +++ b/grc/gui/Bars.py @@ -99,6 +99,7 @@ MENU_BAR_LIST = ( Actions.TOGGLE_HIDE_DISABLED_BLOCKS, Actions.TOGGLE_AUTO_HIDE_PORT_LABELS, Actions.TOGGLE_SNAP_TO_GRID, + Actions.TOGGLE_SHOW_BLOCK_COMMENTS, None, Actions.ERRORS_WINDOW_DISPLAY, Actions.FIND_BLOCKS, diff --git a/grc/gui/Block.py b/grc/gui/Block.py index 11c1cafc97..60f19fc1a4 100644 --- a/grc/gui/Block.py +++ b/grc/gui/Block.py @@ -35,6 +35,9 @@ import pango BLOCK_MARKUP_TMPL="""\ #set $foreground = $block.is_valid() and 'black' or 'red' <span foreground="$foreground" font_desc="$font"><b>$encode($block.get_name())</b></span>""" +COMMENT_MARKUP_TMPL="""\ +#set $foreground = $block.get_enabled() and '#444' or '#888' +<span foreground="$foreground" font_desc="$font">$encode($block.get_comment())</span>""" class Block(Element): """The graphical signal block.""" @@ -68,6 +71,7 @@ class Block(Element): }) )) Element.__init__(self) + self._comment_pixmap = None def get_coordinate(self): """ @@ -203,6 +207,22 @@ class Block(Element): for ports in (self.get_sources_gui(), self.get_sinks_gui()) ] )) + self.create_comment_label() + + def create_comment_label(self): + comment = self.get_comment() + if comment: + layout = gtk.DrawingArea().create_pango_layout('') + layout.set_markup(Utils.parse_template(COMMENT_MARKUP_TMPL, block=self, font=BLOCK_FONT)) + width, height = layout.get_pixel_size() + pixmap = self.get_parent().new_pixmap(width, height) + gc = pixmap.new_gc() + gc.set_foreground(Colors.COMMENT_BACKGROUND_COLOR) + pixmap.draw_rectangle(gc, True, 0, 0, width, height) + pixmap.draw_layout(gc, 0, 0, layout) + self._comment_pixmap = pixmap + else: + self._comment_pixmap = None def draw(self, gc, window): """ @@ -243,3 +263,11 @@ class Block(Element): port_selected = port.what_is_selected(coor, coor_m) if port_selected: return port_selected return Element.what_is_selected(self, coor, coor_m) + + def draw_comment(self, gc, window): + if not self._comment_pixmap: + return + + x, y = self.get_coordinate() + window.draw_drawable(gc, self._comment_pixmap, 0, 0, x, + y + self.H + BLOCK_LABEL_PADDING, -1, -1) diff --git a/grc/gui/Colors.py b/grc/gui/Colors.py index 7430705cf8..f64106b03f 100644 --- a/grc/gui/Colors.py +++ b/grc/gui/Colors.py @@ -34,6 +34,7 @@ try: ENTRYENUM_CUSTOM_COLOR = get_color('#EEEEEE') #flow graph color constants FLOWGRAPH_BACKGROUND_COLOR = get_color('#FFF9FF') + COMMENT_BACKGROUND_COLOR = get_color('#F3F3F3') #block color constants BLOCK_ENABLED_COLOR = get_color('#F1ECFF') BLOCK_DISABLED_COLOR = get_color('#CCCCCC') diff --git a/grc/gui/FlowGraph.py b/grc/gui/FlowGraph.py index f8be2f6cc3..97f814f1bf 100644 --- a/grc/gui/FlowGraph.py +++ b/grc/gui/FlowGraph.py @@ -280,6 +280,11 @@ class FlowGraph(Element): #draw the background gc.set_foreground(Colors.FLOWGRAPH_BACKGROUND_COLOR) window.draw_rectangle(gc, True, 0, 0, W, H) + # draw comments first + if Actions.TOGGLE_SHOW_BLOCK_COMMENTS.get_active(): + for block in self.get_blocks(): + if block.get_enabled(): + block.draw_comment(gc, window) #draw multi select rectangle if self.mouse_pressed and (not self.get_selected_elements() or self.get_ctrl_mask()): #coordinates @@ -294,8 +299,9 @@ class FlowGraph(Element): gc.set_foreground(Colors.BORDER_COLOR) window.draw_rectangle(gc, False, x, y, w, h) #draw blocks on top of connections + hide_disabled_blocks = Actions.TOGGLE_HIDE_DISABLED_BLOCKS.get_active() for element in self.get_connections() + self.get_blocks(): - if Actions.TOGGLE_HIDE_DISABLED_BLOCKS.get_active() and not element.get_enabled(): + if hide_disabled_blocks and not element.get_enabled(): continue # skip hidden disabled blocks and connections element.draw(gc, window) #draw selected blocks on top of selected connections diff --git a/grc/gui/Param.py b/grc/gui/Param.py index 3ea1e4dbab..7933973837 100644 --- a/grc/gui/Param.py +++ b/grc/gui/Param.py @@ -26,8 +26,10 @@ import gtk import Colors import os + class InputParam(gtk.HBox): """The base class for an input parameter inside the input parameters dialog.""" + expand = False def __init__(self, param, changed_callback=None, editing_callback=None): gtk.HBox.__init__(self) @@ -123,6 +125,42 @@ class EntryParam(InputParam): except AttributeError: pass # no tooltips for old GTK + +class MultiLineEntryParam(InputParam): + """Provide an multi-line box for strings.""" + expand = True + + def __init__(self, *args, **kwargs): + InputParam.__init__(self, *args, **kwargs) + self._buffer = gtk.TextBuffer() + self._buffer.set_text(self.param.get_value()) + self._buffer.connect('changed', self._mark_changed) + + self._view = gtk.TextView(self._buffer) + self._view.connect('focus-out-event', self._apply_change) + self._view.connect('key-press-event', self._handle_key_press) + + self._sw = gtk.ScrolledWindow() + self._sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + self._sw.add_with_viewport(self._view) + + self.pack_start(self._sw, True) + + def get_text(self): + return self._buffer.get_text(self._buffer.get_start_iter(), + self._buffer.get_end_iter()).strip() + + def set_color(self, color): + self._view.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(color)) + self._view.modify_text(gtk.STATE_NORMAL, Colors.PARAM_ENTRY_TEXT_COLOR) + + def set_tooltip_text(self, text): + try: + self._view.set_tooltip_text(text) + except AttributeError: + pass # no tooltips for old GTK + + class EnumParam(InputParam): """Provide an entry box for Enum types with a drop down menu.""" @@ -248,6 +286,7 @@ Error: #end for #end if""" + class Param(Element): """The graphical parameter.""" @@ -264,15 +303,21 @@ class Param(Element): gtk input class """ if self.get_type() in ('file_open', 'file_save'): - return FileParam(self, *args, **kwargs) + input_widget = FileParam(self, *args, **kwargs) elif self.is_enum(): - return EnumParam(self, *args, **kwargs) + input_widget = EnumParam(self, *args, **kwargs) elif self.get_options(): - return EnumEntryParam(self, *args, **kwargs) + input_widget = EnumEntryParam(self, *args, **kwargs) + + elif self.get_type() == 'multiline': + input_widget = MultiLineEntryParam(self, *args, **kwargs) + + else: + input_widget = EntryParam(self, *args, **kwargs) - return EntryParam(self, *args, **kwargs) + return input_widget def get_markup(self): """ diff --git a/grc/gui/PropsDialog.py b/grc/gui/PropsDialog.py index 1045cfbbdc..083e42d026 100644 --- a/grc/gui/PropsDialog.py +++ b/grc/gui/PropsDialog.py @@ -169,7 +169,8 @@ class PropsDialog(gtk.Dialog): if param.get_hide() == 'all': continue box_all_valid = box_all_valid and param.is_valid() - vbox.pack_start(param.get_input(self._handle_changed, self._activate_apply), False) + input_widget = param.get_input(self._handle_changed, self._activate_apply) + vbox.pack_start(input_widget, input_widget.expand) label.set_markup(Utils.parse_template(TAB_LABEL_MARKUP_TMPL, valid=box_all_valid, tab=tab)) #show params box with new params vbox.show_all() @@ -191,7 +192,10 @@ class PropsDialog(gtk.Dialog): Returns: false to forward the keypress """ - if event.keyval == gtk.keysyms.Return and event.state & gtk.gdk.CONTROL_MASK == 0: + if (event.keyval == gtk.keysyms.Return and + event.state & gtk.gdk.CONTROL_MASK == 0 and + not isinstance(widget.get_focus(), gtk.TextView) + ): self.response(gtk.RESPONSE_ACCEPT) return True # handled here return False # forward the keypress diff --git a/grc/python/Param.py b/grc/python/Param.py index 827355d8d6..0e72fcbfb2 100644 --- a/grc/python/Param.py +++ b/grc/python/Param.py @@ -57,7 +57,7 @@ class Param(_Param, _GUIParam): 'complex', 'real', 'float', 'int', 'complex_vector', 'real_vector', 'float_vector', 'int_vector', 'hex', 'string', 'bool', - 'file_open', 'file_save', + 'file_open', 'file_save', 'multiline', 'id', 'stream_id', 'grid_pos', 'notebook', 'gui_hint', 'import', @@ -206,14 +206,6 @@ class Param(_Param, _GUIParam): self._lisitify_flag = False self._stringify_flag = False self._hostage_cells = list() - def eval_string(v): - try: - e = self.get_parent().get_parent().evaluate(v) - if isinstance(e, str): return e - raise Exception #want to stringify - except: - self._stringify_flag = True - return v t = self.get_type() v = self.get_value() ######################### @@ -280,9 +272,15 @@ class Param(_Param, _GUIParam): ######################### # String Types ######################### - elif t in ('string', 'file_open', 'file_save'): + elif t in ('string', 'file_open', 'file_save', 'multiline'): #do not check if file/directory exists, that is a runtime issue - e = eval_string(v) + try: + e = self.get_parent().get_parent().evaluate(v) + if not isinstance(e, str): + raise Exception() + except: + self._stringify_flag = True + e = v return str(e) ######################### # Unique ID Type @@ -413,7 +411,7 @@ class Param(_Param, _GUIParam): """ v = self.get_value() t = self.get_type() - if t in ('string', 'file_open', 'file_save'): #string types + if t in ('string', 'file_open', 'file_save', 'multiline'): #string types if not self._init: self.evaluate() if self._stringify_flag: return '"%s"'%v.replace('"', '\"') else: return v |