commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] [gnuradio] 10/15: grc: nicer block documentation toolt


From: git
Subject: [Commit-gnuradio] [gnuradio] 10/15: grc: nicer block documentation tooltip and properties dialog tab
Date: Wed, 10 Feb 2016 15:44:48 +0000 (UTC)

This is an automated email from the git hooks/post-receive script.

jcorgan pushed a commit to branch master
in repository gnuradio.

commit dec3bf564e5ca3b6fc103b3eb66a80e8abe8229b
Author: Sebastian Koslowski <address@hidden>
Date:   Fri Feb 5 11:43:26 2016 +0100

    grc: nicer block documentation tooltip and properties dialog tab
---
 grc/gui/BlockTreeWindow.py | 52 +++++++++++++++++++++++++++++++---------------
 grc/gui/PropsDialog.py     | 38 +++++++++++++++++++++++++++++++--
 grc/python/Block.py        |  7 +++++--
 grc/python/Platform.py     | 25 +++++++++++-----------
 grc/python/extract_docs.py |  2 +-
 5 files changed, 90 insertions(+), 34 deletions(-)

diff --git a/grc/gui/BlockTreeWindow.py b/grc/gui/BlockTreeWindow.py
index f696819..8a29120 100644
--- a/grc/gui/BlockTreeWindow.py
+++ b/grc/gui/BlockTreeWindow.py
@@ -30,12 +30,27 @@ KEY_INDEX = 1
 DOC_INDEX = 2
 
 DOC_MARKUP_TMPL = """\
-#if $doc
-#if len($doc) > 1000
-#set $doc = $doc[:1000] + '...'
+#set $docs = []
+#if $doc.get('')
+    #set $docs += $doc.pop('').splitlines() + ['']
 #end if
-$encode($doc)#slurp
-#else
+#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"""
 
@@ -129,8 +144,10 @@ class BlockTreeWindow(gtk.VBox):
             category: the category list or path string
             block: the block object or None
         """
-        if treestore is None: treestore = self.treestore
-        if categories is None: categories = self._categories
+        if treestore is None:
+            treestore = self.treestore
+        if categories is None:
+            categories = self._categories
 
         if isinstance(category, (str, unicode)): category = category.split('/')
         category = tuple(filter(lambda x: x, category))  # tuple is hashable
@@ -138,17 +155,18 @@ class BlockTreeWindow(gtk.VBox):
         for i, cat_name in enumerate(category):
             sub_category = category[:i+1]
             if sub_category not in categories:
-                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))
-                categories[sub_category] = iter
+                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))
+                categories[sub_category] = iter_
         # add block
-        if block is None: return
-        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()))
+        if block is None:
+            return
+        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()))
 
     def update_docs(self):
         """Update the documentation column of every block"""
diff --git a/grc/gui/PropsDialog.py b/grc/gui/PropsDialog.py
index bf7d31d..7c66a77 100644
--- a/grc/gui/PropsDialog.py
+++ b/grc/gui/PropsDialog.py
@@ -97,7 +97,8 @@ class PropsDialog(gtk.Dialog):
             self._params_boxes.append((tab, label, vbox))
 
         # Docs for the block
-        self._docs_text_display = SimpleTextDisplay()
+        self._docs_text_display = doc_view = SimpleTextDisplay()
+        doc_view.get_buffer().create_tag('b', weight=pango.WEIGHT_BOLD)
         self._docs_box = gtk.ScrolledWindow()
         self._docs_box.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
         self._docs_box.add_with_viewport(self._docs_text_display)
@@ -200,10 +201,43 @@ class PropsDialog(gtk.Dialog):
         messages = '\n\n'.join(self._block.get_error_messages())
         self._error_messages_text_display.set_text(messages)
         # update the docs box
-        self._docs_text_display.set_text(self._block.get_doc())
+        self._update_docs_page()
         # update the generated code
         self._update_generated_code_page()
 
+    def _update_docs_page(self):
+        """Show documentation from XML and try to display best matching 
docstring"""
+        buffer = self._docs_text_display.get_buffer()
+        buffer.delete(buffer.get_start_iter(), buffer.get_end_iter())
+        pos = buffer.get_end_iter()
+
+        docstrings = self._block.get_doc()
+        if not docstrings:
+            return
+
+        # show documentation string from block xml
+        from_xml = docstrings.pop('', '')
+        for line in from_xml.splitlines():
+            if line.lstrip() == line and line.endswith(':'):
+                buffer.insert_with_tags_by_name(pos, line + '\n', 'b')
+            else:
+                buffer.insert(pos, line + '\n')
+        if from_xml:
+            buffer.insert(pos, '\n')
+
+        # if given the current parameters an exact match can be made
+        block_constructor = self._block.get_make().rsplit('.', 2)[-1]
+        block_class = block_constructor.partition('(')[0].strip()
+        if block_class in docstrings:
+            docstrings = {block_class: docstrings[block_class]}
+
+        # show docstring(s) extracted from python sources
+        for cls_name, docstring in docstrings.iteritems():
+            buffer.insert_with_tags_by_name(pos, cls_name + '\n', 'b')
+            buffer.insert(pos, docstring + '\n\n')
+        pos.backward_chars(2)
+        buffer.delete(pos, buffer.get_end_iter())
+
     def _update_generated_code_page(self):
         if not self._code_text_display:
             return  # user disabled code preview
diff --git a/grc/python/Block.py b/grc/python/Block.py
index f5c994d..f43b006 100644
--- a/grc/python/Block.py
+++ b/grc/python/Block.py
@@ -185,8 +185,11 @@ class Block(_Block, _GUIBlock):
 
     def get_doc(self):
         platform = self.get_parent().get_parent()
-        extracted_docs = platform.block_docstrings.get(self._key, '')
-        return (self._doc + '\n\n' + extracted_docs).strip()
+        documentation = platform.block_docstrings.get(self._key, {})
+        from_xml = self._doc.strip()
+        if from_xml:
+            documentation[''] = from_xml
+        return documentation
 
     def get_category(self):
         return _Block.get_category(self)
diff --git a/grc/python/Platform.py b/grc/python/Platform.py
index 1d93276..5932818 100644
--- a/grc/python/Platform.py
+++ b/grc/python/Platform.py
@@ -38,8 +38,6 @@ from .Constants import (
     PREFS_FILE, PREFS_FILE_OLD, CORE_TYPES
 )
 
-COLORS = [(name, color) for name, key, sizeof, color in CORE_TYPES]
-
 
 class Platform(_Platform, _GUIPlatform):
     def __init__(self):
@@ -52,17 +50,11 @@ class Platform(_Platform, _GUIPlatform):
         if not os.path.exists(os.path.dirname(PREFS_FILE)):
             os.mkdir(os.path.dirname(PREFS_FILE))
 
-        self.block_docstrings = block_docstrings = dict()
-        self.block_docstrings_loaded_callback = lambda: None
-
-        def setter(key, docs):
-            block_docstrings[key] = '\n\n'.join(
-                '--- {0} ---\n{1}\n'.format(b, d.replace('\n\n', '\n'))
-                for b, d in docs.iteritems() if d is not None
-            )
+        self.block_docstrings = {}
+        self.block_docstrings_loaded_callback = lambda: None  # dummy to be 
replaced by BlockTreeWindow
 
         self._docstring_extractor = extract_docs.SubprocessLoader(
-            callback_query_result=setter,
+            callback_query_result=self._save_docstring_extraction_result,
             callback_finished=lambda: self.block_docstrings_loaded_callback()
         )
 
@@ -78,7 +70,7 @@ class Platform(_Platform, _GUIPlatform):
             block_dtd=BLOCK_DTD,
             default_flow_graph=DEFAULT_FLOW_GRAPH,
             generator=Generator,
-            colors=COLORS,
+            colors=[(name, color) for name, key, sizeof, color in CORE_TYPES],
         )
         self._move_old_pref_file()
         _GUIPlatform.__init__(
@@ -87,6 +79,15 @@ class Platform(_Platform, _GUIPlatform):
         )
         self._auto_hier_block_generate_chain = set()
 
+    def _save_docstring_extraction_result(self, key, docstrings):
+        docs = {}
+        for match, docstring in docstrings.iteritems():
+            if not docstring or match.endswith('_sptr'):
+                continue
+            docstring = docstring.replace('\n\n', '\n').strip()
+            docs[match] = docstring
+        self.block_docstrings[key] = docs
+
     @staticmethod
     def _move_old_pref_file():
         if PREFS_FILE == PREFS_FILE_OLD:
diff --git a/grc/python/extract_docs.py b/grc/python/extract_docs.py
index d8dc4f4..7c149ce 100644
--- a/grc/python/extract_docs.py
+++ b/grc/python/extract_docs.py
@@ -70,7 +70,7 @@ def docstring_guess_from_key(key):
     )
     for match in filter(pattern.match, dir(module)):
         try:
-            doc_strings[match] = getattr(module, match).__doc__.strip()
+            doc_strings[match] = getattr(module, match).__doc__
         except AttributeError:
             continue
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]