summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--grc/base/Block.py12
-rw-r--r--grc/gui/ActionHandler.py8
-rw-r--r--grc/gui/Actions.py5
-rw-r--r--grc/gui/Bars.py1
-rw-r--r--grc/gui/Block.py28
-rw-r--r--grc/gui/Colors.py1
-rw-r--r--grc/gui/FlowGraph.py8
-rw-r--r--grc/gui/Param.py53
-rw-r--r--grc/gui/PropsDialog.py8
-rw-r--r--grc/python/Param.py22
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