diff options
author | Tim O'Shea <tim.oshea753@gmail.com> | 2013-12-09 17:23:29 -0500 |
---|---|---|
committer | Sebastian Koslowski <koslowski@kit.edu> | 2014-01-18 22:47:43 +0100 |
commit | a01b15acfb590abfbfb543544538c6dec08a1f40 (patch) | |
tree | ba77354913ae10ad38713779677b153138c1f11a | |
parent | 67aa043b837e38fc04d612ced68ff2e4558c06ea (diff) |
grc: adding a page that captures and stores some XML parsing errors
-rw-r--r-- | grc/base/ParseXML.py | 10 | ||||
-rw-r--r-- | grc/base/Platform.py | 2 | ||||
-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/CMakeLists.txt | 1 | ||||
-rw-r--r-- | grc/gui/ParseDialog.py | 102 |
7 files changed, 126 insertions, 3 deletions
diff --git a/grc/base/ParseXML.py b/grc/base/ParseXML.py index 56097395dd..d66edffb69 100644 --- a/grc/base/ParseXML.py +++ b/grc/base/ParseXML.py @@ -20,6 +20,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA from lxml import etree from . import odict +xml_failures = {}; + class XMLSyntaxError(Exception): def __init__(self, error_log): self._error_log = error_log @@ -38,11 +40,15 @@ def validate_dtd(xml_file, dtd_file=None): #perform parsing, use dtd validation if dtd file is not specified parser = etree.XMLParser(dtd_validation=not dtd_file) xml = etree.parse(xml_file, parser=parser) - if parser.error_log: raise XMLSyntaxError(parser.error_log) + if parser.error_log: + xml_failures[xml_file] = parser.error_log; + raise XMLSyntaxError(parser.error_log) #perform dtd validation if the dtd file is specified if not dtd_file: return dtd = etree.DTD(dtd_file) - if not dtd.validate(xml.getroot()): raise XMLSyntaxError(dtd.error_log) + if not dtd.validate(xml.getroot()): + xml_failures[xml_file] = dtd.error_log; + raise XMLSyntaxError(dtd.error_log) def from_file(xml_file): """ diff --git a/grc/base/Platform.py b/grc/base/Platform.py index 88cbf32b89..66266b1b71 100644 --- a/grc/base/Platform.py +++ b/grc/base/Platform.py @@ -99,6 +99,8 @@ class Platform(_Element): try: #try to add the xml file as a block tree ParseXML.validate_dtd(xml_file, BLOCK_TREE_DTD) self._block_tree_files.append(xml_file) + # remove the block DTD error, since iti s a valid block tree + ParseXML.xml_failures.pop(xml_file) except ParseXML.XMLSyntaxError, e: print >> sys.stderr, 'Warning: Block validation failed:\n\t%s\n\tIgnoring: %s'%(e, xml_file) except Exception, e: diff --git a/grc/gui/ActionHandler.py b/grc/gui/ActionHandler.py index a891298fa4..e5c382793f 100644 --- a/grc/gui/ActionHandler.py +++ b/grc/gui/ActionHandler.py @@ -31,6 +31,7 @@ import Messages from .. base import ParseXML from MainWindow import MainWindow from PropsDialog import PropsDialog +from ParseDialog import ParseDialog import Dialogs from FileDialogs import OpenFlowGraphFileDialog, SaveFlowGraphFileDialog, SaveImageFileDialog @@ -114,7 +115,7 @@ class ActionHandler: Actions.FLOW_GRAPH_CLOSE, Actions.ABOUT_WINDOW_DISPLAY, Actions.FLOW_GRAPH_SCREEN_CAPTURE, Actions.HELP_WINDOW_DISPLAY, Actions.TYPES_WINDOW_DISPLAY, Actions.TOGGLE_BLOCKS_WINDOW, - Actions.TOGGLE_REPORTS_WINDOW, + Actions.TOGGLE_REPORTS_WINDOW, Actions.PARSER_ERRORS, ): action.set_sensitive(True) if not self.init_file_paths: self.init_file_paths = Preferences.files_open() @@ -377,6 +378,11 @@ class ActionHandler: self.get_flow_graph().import_data(n) self.get_flow_graph().update() ################################################## + # View Parser Errors + ################################################## + elif action == Actions.PARSER_ERRORS: + ParseDialog(ParseXML.xml_failures).run() + ################################################## # Undo/Redo ################################################## elif action == Actions.FLOW_GRAPH_UNDO: diff --git a/grc/gui/Actions.py b/grc/gui/Actions.py index e96fb4d276..1776acb6ac 100644 --- a/grc/gui/Actions.py +++ b/grc/gui/Actions.py @@ -354,3 +354,8 @@ BUSSIFY_SINKS = Action( tooltip='Gang sink ports into a single bus port', stock_id=gtk.STOCK_JUMP_TO, ) +PARSER_ERRORS = Action( + label='_Parser Errors', + tooltip='View errors that occured while parsing XML files', + stock_id=gtk.STOCK_DIALOG_ERROR, +) diff --git a/grc/gui/Bars.py b/grc/gui/Bars.py index 0e2b29c4e3..4c98f65416 100644 --- a/grc/gui/Bars.py +++ b/grc/gui/Bars.py @@ -103,6 +103,7 @@ MENU_BAR_LIST = ( (gtk.Action('Help', '_Help', None, None), [ Actions.HELP_WINDOW_DISPLAY, Actions.TYPES_WINDOW_DISPLAY, + Actions.PARSER_ERRORS, None, Actions.ABOUT_WINDOW_DISPLAY, ]), diff --git a/grc/gui/CMakeLists.txt b/grc/gui/CMakeLists.txt index c2eb16e9fd..49aec8d557 100644 --- a/grc/gui/CMakeLists.txt +++ b/grc/gui/CMakeLists.txt @@ -39,6 +39,7 @@ GR_PYTHON_INSTALL(FILES MainWindow.py Messages.py NotebookPage.py + ParseDialog.py PropsDialog.py Preferences.py StateCache.py diff --git a/grc/gui/ParseDialog.py b/grc/gui/ParseDialog.py new file mode 100644 index 0000000000..93fa108e81 --- /dev/null +++ b/grc/gui/ParseDialog.py @@ -0,0 +1,102 @@ +""" +Copyright 2013 Free Software Foundation, Inc. +This file is part of GNU Radio + +GNU Radio Companion is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +GNU Radio Companion is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +""" + +import pygtk +pygtk.require('2.0') +import gtk, glib + +from Dialogs import TextDisplay +from Constants import MIN_DIALOG_WIDTH, MIN_DIALOG_HEIGHT + +def get_title_label(title): + """ + Get a title label for the params window. + The title will be bold, underlined, and left justified. + + Args: + title: the text of the title + + Returns: + a gtk object + """ + label = gtk.Label() + label.set_markup('\n<b><span underline="low">%s</span>:</b>\n'%title) + hbox = gtk.HBox() + hbox.pack_start(label, False, False, padding=11) + return hbox + +class ParseDialog(gtk.Dialog): + """ + A dialog for viewing parser errors + """ + + def __init__(self, errors): + """ + Properties dialog contructor. + + Args: + block: a block instance + """ + self._hash = 0 + LABEL_SPACING = 7 + gtk.Dialog.__init__(self, + title='Parser Errors', + buttons=(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT), + ) + + self._errors = errors; + + # set up data model + model = gtk.TreeStore(str) + for k in self._errors.keys(): + n = model.append(None, [str(k)]); + for e in self._errors[k]: + # http://lxml.de/api/lxml.etree._LogEntry-class.html + em = model.append(n, [ "(%s:%s:%s) %s %s %s"%(e.filename, e.line, e.column, e.level_name, e.domain_name, e.message) ] ) + try: + sf = open(e.filename,'r'); + lc = sf.readlines()[e.line].rstrip('\n'); + model.append(em, [ lc] ) + except: + model.append(em, ["could not access source file"] ) + + + view = gtk.TreeView(model) + tvcolumn = gtk.TreeViewColumn('XML Parser Errors by Filename') + view.append_column(tvcolumn) + cell = gtk.CellRendererText() + tvcolumn.pack_start(cell, True) + tvcolumn.add_attribute(cell, 'text', 0) + view.set_search_column(0) + tvcolumn.set_sort_column_id(0) + view.set_reorderable(True) + + self.vbox.add(view); + self.show_all() + + def run(self): + """ + Run the dialog and get its response. + + Returns: + true if the response was accept + """ + response = gtk.Dialog.run(self) + self.destroy() + return response == gtk.RESPONSE_ACCEPT |