summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--grc/gui/Block.py56
-rw-r--r--grc/gui/BlockTreeWindow.py57
-rw-r--r--grc/gui/Dialogs.py48
-rw-r--r--grc/gui/FileDialogs.py12
-rw-r--r--grc/gui/MainWindow.py69
-rw-r--r--grc/gui/Param.py68
-rw-r--r--grc/gui/Port.py10
-rw-r--r--grc/gui/PropsDialog.py12
-rw-r--r--grc/gui/Utils.py24
9 files changed, 136 insertions, 220 deletions
diff --git a/grc/gui/Block.py b/grc/gui/Block.py
index 57fb69c448..f8687be42f 100644
--- a/grc/gui/Block.py
+++ b/grc/gui/Block.py
@@ -32,28 +32,9 @@ from .Constants import (
)
from . Element import Element
from ..core.Param import num_to_str
-from ..core.utils import odict
from ..core.utils.complexity import calculate_flowgraph_complexity
from ..core.Block import Block as _Block
-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>"""
-
-# Includes the additional complexity markup if enabled
-COMMENT_COMPLEXITY_MARKUP_TMPL="""\
-#set $foreground = $block.get_enabled() and '#444' or '#888'
-#if $complexity
-<span foreground="#444" size="medium" font_desc="$font"><b>$encode($complexity)</b></span>#slurp
-#end if
-#if $complexity and $comment
-<span></span>
-#end if
-#if $comment
-<span foreground="$foreground" font_desc="$font">$encode($comment)</span>#slurp
-#end if
-"""
-
class Block(Element, _Block):
"""The graphical signal block."""
@@ -188,14 +169,16 @@ class Block(Element, _Block):
del self.layouts[:]
#create the main layout
layout = Gtk.DrawingArea().create_pango_layout('')
- self.layouts.append(layout)
- layout.set_markup(Utils.parse_template(BLOCK_MARKUP_TMPL, block=self, font=BLOCK_FONT))
+ layout.set_markup('<span foreground="{foreground}" font_desc="{font}"><b>{name}</b></span>'.format(
+ foreground='black' if self.is_valid() else 'red', font=BLOCK_FONT, name=Utils.encode(self.get_name())
+ ))
self.label_width, self.label_height = layout.get_pixel_size()
+ self.layouts.append(layout)
#display the params
if self.is_dummy_block:
- markups = [
- '<span foreground="black" font_desc="{font}"><b>key: </b>{key}</span>'.format(font=PARAM_FONT, key=self._key)
- ]
+ markups = ['<span foreground="black" font_desc="{font}"><b>key: </b>{key}</span>'.format(
+ font=PARAM_FONT, key=self._key
+ )]
else:
markups = [param.get_markup() for param in self.get_params() if param.get_hide() not in ('all', 'part')]
if markups:
@@ -237,20 +220,25 @@ class Block(Element, _Block):
self.create_comment_label()
def create_comment_label(self):
- comment = self.get_comment() # Returns None if there are no comments
- complexity = None
+ markups = []
- # Show the flowgraph complexity on the top block if enabled
+ # Show the flow graph complexity on the top block if enabled
if Actions.TOGGLE_SHOW_FLOWGRAPH_COMPLEXITY.get_active() and self.get_key() == "options":
complexity = calculate_flowgraph_complexity(self.get_parent())
- complexity = "Complexity: {}bal".format(num_to_str(complexity))
-
+ markups.append(
+ '<span foreground="#444" size="medium" font_desc="{font}">'
+ '<b>Complexity: {num}bal</b></span>'.format(num=num_to_str(complexity), font=BLOCK_FONT)
+ )
+ comment = self.get_comment() # Returns None if there are no comments
+ if comment:
+ if markups:
+ markups.append('<span></span>')
+
+ markups.append('<span foreground="{foreground}" font_desc="{font}">{comment}</span>'.format(
+ foreground='#444' if self.get_enabled() else '#888', font=BLOCK_FONT, comment=Utils.encode(comment)
+ ))
layout = Gtk.DrawingArea().create_pango_layout('')
- layout.set_markup(Utils.parse_template(COMMENT_COMPLEXITY_MARKUP_TMPL,
- block=self,
- comment=comment,
- complexity=complexity,
- font=BLOCK_FONT))
+ layout.set_markup(''.join(markups))
# Setup the pixel map. Make sure that layout not empty
width, height = layout.get_pixel_size()
diff --git a/grc/gui/BlockTreeWindow.py b/grc/gui/BlockTreeWindow.py
index a68d0938fc..e8de6e9277 100644
--- a/grc/gui/BlockTreeWindow.py
+++ b/grc/gui/BlockTreeWindow.py
@@ -26,36 +26,26 @@ from gi.repository import GObject
from . import Actions, Utils
from .Constants import DEFAULT_BLOCKS_WINDOW_WIDTH, DND_TARGETS
-NAME_INDEX = 0
-KEY_INDEX = 1
-DOC_INDEX = 2
-
-DOC_MARKUP_TMPL = """\
-#set $docs = []
-#if $doc.get('')
- #set $docs += $doc.pop('').splitlines() + ['']
-#end if
-#for b, d in $doc.iteritems()
- #set $docs += ['--- {0} ---'.format(b)] + d.splitlines() + ['']
-#end for
-#set $len_out = 0
-#for $n, $line in $enumerate($docs[:-1])
-#if $n
-
-#end if
-$encode($line)#slurp
-#set $len_out += $len($line)
-#if $n > 10 or $len_out > 500
-
-...#slurp
-#break
-#end if
-#end for
-#if $len_out == 0
-undocumented#slurp
-#end if"""
-
-CAT_MARKUP_TMPL = """Category: $cat"""
+NAME_INDEX, KEY_INDEX, DOC_INDEX = range(3)
+
+
+def _format_doc(doc):
+ docs = []
+ if doc.get(''):
+ docs += doc.pop('').splitlines() + ['']
+ for block_name, docstring in doc.iteritems():
+ docs.append('--- {0} ---'.format(block_name))
+ docs += docstring.splitlines()
+ docs.append('')
+ out = ''
+ for n, line in enumerate(docs[:-1]):
+ if n:
+ out += '\n'
+ out += Utils.encode(line)
+ if n > 10 or len(out) > 500:
+ out += '\n...'
+ break
+ return out or 'undocumented'
class BlockTreeWindow(Gtk.VBox):
@@ -159,7 +149,7 @@ class BlockTreeWindow(Gtk.VBox):
iter_ = treestore.insert_before(categories[sub_category[:-1]], None)
treestore.set_value(iter_, NAME_INDEX, cat_name)
treestore.set_value(iter_, KEY_INDEX, '')
- treestore.set_value(iter_, DOC_INDEX, Utils.parse_template(CAT_MARKUP_TMPL, cat=cat_name))
+ treestore.set_value(iter_, DOC_INDEX, 'Category: ' + Utils.encode(cat_name))
categories[sub_category] = iter_
# add block
if block is None:
@@ -167,7 +157,7 @@ class BlockTreeWindow(Gtk.VBox):
iter_ = treestore.insert_before(categories[category], None)
treestore.set_value(iter_, NAME_INDEX, block.get_name())
treestore.set_value(iter_, KEY_INDEX, block.get_key())
- treestore.set_value(iter_, DOC_INDEX, Utils.parse_template(DOC_MARKUP_TMPL, doc=block.get_doc()))
+ treestore.set_value(iter_, DOC_INDEX, _format_doc(block.get_doc()))
def update_docs(self):
"""Update the documentation column of every block"""
@@ -177,8 +167,7 @@ class BlockTreeWindow(Gtk.VBox):
return # category node, no doc string
key = model.get_value(iter_, KEY_INDEX)
block = self.platform.blocks[key]
- doc = Utils.parse_template(DOC_MARKUP_TMPL, doc=block.get_doc())
- model.set_value(iter_, DOC_INDEX, doc)
+ model.set_value(iter_, DOC_INDEX, _format_doc(block.get_doc()))
self.treestore.foreach(update_doc)
self.treestore_search.foreach(update_doc)
diff --git a/grc/gui/Dialogs.py b/grc/gui/Dialogs.py
index a7bc121e40..953373ee24 100644
--- a/grc/gui/Dialogs.py
+++ b/grc/gui/Dialogs.py
@@ -161,20 +161,16 @@ def MessageDialogHelper(type, buttons, title=None, markup=None, default_response
return response
-ERRORS_MARKUP_TMPL="""\
-#for $i, $err_msg in enumerate($errors)
-<b>Error $i:</b>
-$encode($err_msg.replace('\t', ' '))
-
-#end for"""
-
-
-def ErrorsDialog(flowgraph): MessageDialogHelper(
- type=Gtk.MessageType.ERROR,
- buttons=Gtk.ButtonsType.CLOSE,
- title='Flow Graph Errors',
- markup=Utils.parse_template(ERRORS_MARKUP_TMPL, errors=flowgraph.get_error_messages()),
-)
+def ErrorsDialog(flowgraph):
+ MessageDialogHelper(
+ type=Gtk.MessageType.ERROR,
+ buttons=Gtk.ButtonsType.CLOSE,
+ title='Flow Graph Errors',
+ markup='\n\n'.join(
+ '<b>Error {num}:</b>\n{msg}'.format(num=i, msg=Utils.encode(msg.replace('\t', ' ')))
+ for i, msg in enumerate(flowgraph.get_error_messages())
+ ),
+ )
class AboutDialog(Gtk.AboutDialog):
@@ -208,25 +204,21 @@ def HelpDialog(): MessageDialogHelper(
* See the menu for other keyboard shortcuts.""")
-COLORS_DIALOG_MARKUP_TMPL = """\
-<b>Color Mapping</b>
-
-#if $colors
- #set $max_len = max([len(color[0]) for color in $colors]) + 10
- #for $title, $color_spec in $colors
-<span background="$color_spec"><tt>$($encode($title).center($max_len))</tt></span>
- #end for
-#end if
-"""
-
def TypesDialog(platform):
+ colors = platform.get_colors()
+ max_len = 10 + max(len(name) for name, code in colors)
+
+ message = '\n'.join(
+ '<span background="{color}"><tt>{name}</tt></span>'
+ ''.format(color=color, name=Utils.encode(name).center(max_len))
+ for name, color in colors
+ )
MessageDialogHelper(
type=Gtk.MessageType.INFO,
buttons=Gtk.ButtonsType.CLOSE,
- title='Types',
- markup=Utils.parse_template(COLORS_DIALOG_MARKUP_TMPL,
- colors=platform.get_colors())
+ title='Types - Color Mapping',
+ markup=message
)
diff --git a/grc/gui/FileDialogs.py b/grc/gui/FileDialogs.py
index 479f13bbd7..63d4a397a8 100644
--- a/grc/gui/FileDialogs.py
+++ b/grc/gui/FileDialogs.py
@@ -39,13 +39,6 @@ SAVE_CONSOLE = 'save console'
SAVE_IMAGE = 'save image'
OPEN_QSS_THEME = 'open qss theme'
-FILE_OVERWRITE_MARKUP_TMPL="""\
-File <b>$encode($filename)</b> Exists!\nWould you like to overwrite the existing file?"""
-
-FILE_DNE_MARKUP_TMPL="""\
-File <b>$encode($filename)</b> Does not Exist!"""
-
-
# File Filters
def get_flow_graph_files_filter():
@@ -179,7 +172,8 @@ class FileDialog(FileDialogHelper):
if path.exists(filename): #ask the user to confirm overwrite
if MessageDialogHelper(
Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO, 'Confirm Overwrite!',
- Utils.parse_template(FILE_OVERWRITE_MARKUP_TMPL, filename=filename),
+ 'File <b>{filename}</b> Exists!\nWould you like to overwrite the existing file?'
+ ''.format(filename=Utils.encode(filename)),
) == Gtk.ResponseType.NO: return self.get_rectified_filename()
return filename
#############################################
@@ -191,7 +185,7 @@ class FileDialog(FileDialogHelper):
if not path.exists(filename): #show a warning and re-run
MessageDialogHelper(
Gtk.MessageType.WARNING, Gtk.ButtonsType.CLOSE, 'Cannot Open!',
- Utils.parse_template(FILE_DNE_MARKUP_TMPL, filename=filename),
+ 'File <b>{filename}</b> Does not Exist!'.format(filename=Utils.encode(filename)),
)
return self.get_rectified_filename()
return filenames
diff --git a/grc/gui/MainWindow.py b/grc/gui/MainWindow.py
index 95a5c89867..751e0d9b3f 100644
--- a/grc/gui/MainWindow.py
+++ b/grc/gui/MainWindow.py
@@ -36,34 +36,6 @@ from .NotebookPage import NotebookPage
from ..core import Messages
-
-MAIN_WINDOW_TITLE_TMPL = """\
-#if not $saved
-*#slurp
-#end if
-#if $basename
-$basename#slurp
-#else
-$new_flowgraph_title#slurp
-#end if
-#if $read_only
- (read only)#slurp
-#end if
-#if $dirname
- - $dirname#slurp
-#end if
- - $platform_name#slurp
-"""
-
-PAGE_TITLE_MARKUP_TMPL = """\
-#set $foreground = $saved and 'black' or 'red'
-<span foreground="$foreground">$encode($title or $new_flowgraph_title)</span>#slurp
-#if $read_only
- (ro)#slurp
-#end if
-"""
-
-
############################################################
# Main window
############################################################
@@ -351,32 +323,27 @@ class MainWindow(Gtk.Window):
Set the title of the main window.
Set the titles on the page tabs.
Show/hide the console window.
+ """
+ page = self.get_page()
- Args:
- title: the window title
- """
- Gtk.Window.set_title(self, Utils.parse_template(MAIN_WINDOW_TITLE_TMPL,
- basename=os.path.basename(self.get_page().get_file_path()),
- dirname=os.path.dirname(self.get_page().get_file_path()),
- new_flowgraph_title=NEW_FLOGRAPH_TITLE,
- read_only=self.get_page().get_read_only(),
- saved=self.get_page().get_saved(),
- platform_name=self._platform.config.name,
- )
- )
- #set tab titles
- for page in self.get_pages(): page.set_markup(
- Utils.parse_template(PAGE_TITLE_MARKUP_TMPL,
- #get filename and strip out file extension
- title=os.path.splitext(os.path.basename(page.get_file_path()))[0],
- read_only=page.get_read_only(), saved=page.get_saved(),
- new_flowgraph_title=NEW_FLOGRAPH_TITLE,
- )
- )
- #show/hide notebook tabs
+ basename = os.path.basename(page.get_file_path())
+ dirname = os.path.dirname(page.get_file_path())
+ Gtk.Window.set_title(self, ''.join((
+ '*' if not page.get_saved() else '', basename if basename else NEW_FLOGRAPH_TITLE,
+ '(read only)' if page.get_read_only() else '', ' - ',
+ dirname if dirname else self._platform.config.name,
+ )))
+ # set tab titles
+ for page in self.get_pages():
+ file_name = os.path.splitext(os.path.basename(page.get_file_path()))[0]
+ page.set_markup('<span foreground="{foreground}">{title}{ro}</span>'.format(
+ foreground='black' if page.get_saved() else 'red', ro=' (ro)' if page.get_read_only() else '',
+ title=Utils.encode(file_name or NEW_FLOGRAPH_TITLE),
+ ))
+ # show/hide notebook tabs
self.notebook.set_show_tabs(len(self.get_pages()) > 1)
- # Need to update the variable window when changing
+ # Need to update the variable window when changing
self.vars.update_gui()
def update_pages(self):
diff --git a/grc/gui/Param.py b/grc/gui/Param.py
index fe5da8ba84..a0ca6b66c3 100644
--- a/grc/gui/Param.py
+++ b/grc/gui/Param.py
@@ -63,22 +63,39 @@ class InputParam(Gtk.HBox):
"""
Set the markup, color, tooltip, show/hide.
"""
- #set the markup
- has_cb = \
- hasattr(self.param.get_parent(), 'get_callbacks') and \
- filter(lambda c: self.param.get_key() in c, self.param.get_parent()._callbacks)
- self.set_markup(Utils.parse_template(PARAM_LABEL_MARKUP_TMPL,
- param=self.param, has_cb=has_cb,
- modified=self._have_pending_changes))
- #set the color
+ param = self.param
+
+ has_callback = \
+ hasattr(param.get_parent(), 'get_callbacks') and \
+ any(param.get_key() in callback for callback in param.get_parent()._callbacks)
+
+ self.set_markup('<span underline="{line}" foreground="{color}" font_desc="Sans 9">{label}</span>'.format(
+ line='low' if has_callback else 'none',
+ color='blue' if self._have_pending_changes else
+ 'black' if param.is_valid() else
+ 'red',
+ label=Utils.encode(self.param.get_name())
+ ))
self.set_color(self.param.get_color())
- #set the tooltip
- self.set_tooltip_text(
- Utils.parse_template(TIP_MARKUP_TMPL, param=self.param).strip(),
- )
- #show/hide
- if self.param.get_hide() == 'all': self.hide_all()
- else: self.show_all()
+
+ errors = param.get_error_messages()
+ tooltip_lines = ['Key: ' + param.get_key(), 'Type: ' + param.get_type()]
+ if param.is_valid():
+ value = str(param.get_evaluated())
+ if len(value) > 100:
+ value = '{}...{}'.format(value[:50], value[-50:])
+ tooltip_lines.append('Value: ' + value)
+ elif len(errors) == 1:
+ tooltip_lines.append('Error: ' + errors[0])
+ elif len(errors) > 1:
+ tooltip_lines.append('Error:')
+ tooltip_lines.extend(' * ' + msg for msg in errors)
+ self.set_tooltip_text('\n'.join(tooltip_lines))
+
+ if self.param.get_hide() == 'all':
+ self.hide_all()
+ else:
+ self.show_all()
def _mark_changed(self, *args):
"""
@@ -135,13 +152,13 @@ class EntryParam(InputParam):
need_status_color = self.label not in self.get_children()
text_color = (
Colors.PARAM_ENTRY_TEXT_COLOR if not need_status_color else
- gtk.gdk.color_parse('blue') if self._have_pending_changes else
- gtk.gdk.color_parse('red') if not self.param.is_valid() else
+ Gtk.gdk.color_parse('blue') if self._have_pending_changes else
+ Gtk.gdk.color_parse('red') if not self.param.is_valid() else
Colors.PARAM_ENTRY_TEXT_COLOR)
base_color = (
Colors.BLOCK_DISABLED_COLOR
if need_status_color and not self.param.get_parent().get_enabled()
- else gtk.gdk.color_parse(color)
+ else Gtk.gdk.color_parse(color)
)
self._input.modify_base(Gtk.StateType.NORMAL, base_color)
self._input.modify_text(Gtk.StateType.NORMAL, text_color)
@@ -361,15 +378,6 @@ class FileParam(EntryParam):
file_dialog.destroy() #destroy the dialog
-PARAM_MARKUP_TMPL="""\
-#set $foreground = $param.is_valid() and 'black' or 'red'
-<span foreground="$foreground" font_desc="$font"><b>$encode($param.get_name()): </b>$encode(repr($param).replace('\\n',' '))</span>"""
-
-PARAM_LABEL_MARKUP_TMPL="""\
-#set $foreground = $modified and 'blue' or $param.is_valid() and 'black' or 'red'
-#set $underline = $has_cb and 'low' or 'none'
-<span underline="$underline" foreground="$foreground" font_desc="Sans 9">$encode($param.get_name())</span>"""
-
TIP_MARKUP_TMPL="""\
########################################
#def truncate(string)
@@ -440,5 +448,7 @@ class Param(Element, _Param):
Returns:
a pango markup string
"""
- return Utils.parse_template(PARAM_MARKUP_TMPL,
- param=self, font=Constants.PARAM_FONT)
+ return '<span foreground="{color}" font_desc="{font}"><b>{label}:</b> {value}</span>'.format(
+ color='black' if self.is_valid() else 'red', font=Constants.PARAM_FONT,
+ label=Utils.encode(self.get_name()), value=Utils.encode(repr(self).replace('\n', ' '))
+ )
diff --git a/grc/gui/Port.py b/grc/gui/Port.py
index eb15f6c788..fb1cd678cd 100644
--- a/grc/gui/Port.py
+++ b/grc/gui/Port.py
@@ -25,16 +25,14 @@ from gi.repository import Gtk, PangoCairo
from . import Actions, Colors, Utils
from .Constants import (
PORT_SEPARATION, PORT_SPACING, CONNECTOR_EXTENSION_MINIMAL,
- CONNECTOR_EXTENSION_INCREMENT, PORT_LABEL_PADDING, PORT_MIN_WIDTH, PORT_LABEL_HIDDEN_WIDTH, PORT_FONT
+ CONNECTOR_EXTENSION_INCREMENT, PORT_LABEL_PADDING, PORT_MIN_WIDTH,
+ PORT_LABEL_HIDDEN_WIDTH, PORT_FONT
)
from .Element import Element
from ..core.Constants import DEFAULT_DOMAIN, GR_MESSAGE_DOMAIN
from ..core.Port import Port as _Port
-PORT_MARKUP_TMPL="""\
-<span foreground="black" font_desc="$font">$encode($port.get_name())</span>"""
-
class Port(_Port, Element):
"""The graphical port."""
@@ -117,7 +115,9 @@ class Port(_Port, Element):
def create_labels(self):
"""Create the labels for the socket."""
- self.layout.set_markup(Utils.parse_template(PORT_MARKUP_TMPL, port=self, font=PORT_FONT))
+ self.layout.set_markup("""<span foreground="black" font_desc="{font}">{name}</span>""".format(
+ name=Utils.encode(self.get_name()), font=PORT_FONT
+ ))
def draw(self, widget, cr):
"""
diff --git a/grc/gui/PropsDialog.py b/grc/gui/PropsDialog.py
index 8367f8740a..d6f3cb4efe 100644
--- a/grc/gui/PropsDialog.py
+++ b/grc/gui/PropsDialog.py
@@ -29,10 +29,6 @@ from Constants import MIN_DIALOG_WIDTH, MIN_DIALOG_HEIGHT, FONT_SIZE
import Utils
from gi.repository import Pango
-TAB_LABEL_MARKUP_TMPL="""\
-#set $foreground = $valid and 'black' or 'red'
-<span foreground="$foreground">$encode($tab)</span>"""
-
def get_title_label(title):
"""
@@ -46,7 +42,7 @@ def get_title_label(title):
a gtk object
"""
label = Gtk.Label()
- label.set_markup('\n<b><span underline="low">%s</span>:</b>\n'%title)
+ label.set_markup('\n<b><span underline="low">{title}</span>:</b>\n'.format(title))
hbox = Gtk.HBox()
hbox.pack_start(label, False, False, padding=11)
return hbox
@@ -192,7 +188,11 @@ class PropsDialog(Gtk.Dialog):
box_all_valid = box_all_valid and param.is_valid()
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))
+ label.set_markup(
+ '<span foreground="{color}">{name}</span>'.format(
+ color='black' if box_all_valid else 'red', name=Utils.encode(tab)
+ )
+ )
# show params box with new params
vbox.show_all()
# update the errors box
diff --git a/grc/gui/Utils.py b/grc/gui/Utils.py
index 054af57c51..e5d69bcf54 100644
--- a/grc/gui/Utils.py
+++ b/grc/gui/Utils.py
@@ -25,8 +25,6 @@ from gi.repository import GdkPixbuf
from gi.repository import GObject
from gi.repository import GLib
-from Cheetah.Template import Template
-
from Constants import POSSIBLE_ROTATIONS, CANVAS_GRID_SIZE
@@ -104,28 +102,6 @@ def encode(value):
return GLib.markup_escape_text(valid_utf8)
-class TemplateParser(object):
- def __init__(self):
- self.cache = {}
-
- def __call__(self, tmpl_str, **kwargs):
- """
- Parse the template string with the given args.
- Pass in the xml encode method for pango escape chars.
-
- Args:
- tmpl_str: the template as a string
-
- Returns:
- a string of the parsed template
- """
- kwargs['encode'] = encode
- template = self.cache.setdefault(tmpl_str, Template.compile(tmpl_str))
- return str(template(namespaces=kwargs))
-
-parse_template = TemplateParser()
-
-
def align_to_grid(coor, mode=round):
def align(value):
return int(mode(value / (1.0 * CANVAS_GRID_SIZE)) * CANVAS_GRID_SIZE)