Commit 8208ca61 authored by Maxime Perrotin's avatar Maxime Perrotin
Browse files

Fixed png export from command line

parent a753d2c6
......@@ -252,11 +252,15 @@ class Channel(Connection):
def end_point(self):
''' Compute connection end point - redefined function '''
# Arrow always bumps at the screen edge
view = self.scene().views()[0]
view_pos = view.mapToScene(
try:
view = self.scene().views()[0]
view_pos = view.mapToScene(
view.viewport().geometry()).boundingRect().topLeft()
scene_pos_x = self.mapFromScene(view_pos).x()
return QPointF(scene_pos_x, self.start_point.y())
scene_pos_x = self.mapFromScene(view_pos).x()
return QPointF(scene_pos_x, self.start_point.y())
except IndexError:
# In case there is no view (e.g. Export PNG from cmd line)
return QPointF(self.start_point.x() - 50, self.start_point.y())
class Controlpoint(QGraphicsPathItem, object):
......
......@@ -47,6 +47,7 @@ def add_to_scene(item, scene):
if type(item) in scene.allowed_symbols:
scene.addItem(item)
else:
#print type(item), scene.allowed_symbols, scene.context
raise TypeError('This symbol does not fit the current scene')
......@@ -129,10 +130,10 @@ def _automaton(ast, scene):
new_state = render(state, scene=scene, states=ast.states,
terminators=ast.parent.terminators)
if new_state.nested_scene:
if str(new_state).lower() in nested_states:
if unicode(new_state).lower() in nested_states:
new_state.nested_scene = None
else:
nested_states.append(str(new_state).lower())
nested_states.append(unicode(new_state).lower())
except TypeError:
# Discard terminators (see _state function for explanation)
pass
......
......@@ -585,6 +585,8 @@ class Symbol(QObject, QGraphicsPathItem, object):
def __str__(self):
''' Print the text inside the symbol '''
import traceback
print traceback.print_stack()
raise TypeError('Use unicode() not str()')
#return str(self.text) or 'no_name'
......
......@@ -751,6 +751,9 @@ class Procedure(object):
self.comment = None
# Set of symbols contained in the procedure (type Automaton)
self.content = Automaton(parent=self)
# input/output signal lists - unused but for context information
self.input_signals = []
self.output_signals = []
class Process(object):
......
......@@ -1366,7 +1366,7 @@ def expression(root, context):
elif isinstance(expr, (ogAST.ExprMod, ogAST.ExprRem)):
attrs = {'Min': right.Min, 'Max': right.Max}
expr.exprType = type('Mod', (basic,), attrs)
except ValueError:
except (ValueError, AttributeError):
errors.append('Check that all your numerical data types have '
'a range constraint')
......@@ -2533,7 +2533,7 @@ def outputbody(root, context):
warnings.extend(warn)
elif child.type == lexer.TO:
pass
# TODO: better support of TO primitive
# TODO: better support of TO primitive
else:
warnings.append('Unsupported output body type:' +
str(child.type))
......@@ -3298,7 +3298,16 @@ def parseSingleElement(elem='', string=''):
assert(elem in ('input_part', 'output', 'decision', 'alternative_part',
'terminator_statement', 'label', 'task', 'procedure_call', 'end',
'text_area', 'state', 'start', 'procedure', 'floating_label',
'connect_part', 'process_definition'))
'connect_part', 'process_definition', 'proc_start', 'state_start'))
# Create a dummy context, needed to place context data
if elem == 'proc_start':
elem = 'start'
context = ogAST.Procedure()
elif elem == 'state_start':
elem = 'start'
context = ogAST.CompositeState()
else:
context = ogAST.Process()
LOG.debug('Parsing string: ' + string + ' with elem ' + elem)
parser = parser_init(string=string)
parser_ptr = getattr(parser, elem)
......@@ -3318,12 +3327,12 @@ def parseSingleElement(elem='', string=''):
root = r.tree
root.token_stream = parser.getTokenStream()
backend_ptr = eval(elem)
# Create a dummy process, needed to place context data
context = ogAST.Process()
try:
t, semantic_errors, warnings = backend_ptr(
root=root, parent=None, context=context)
except AttributeError:
except AttributeError as err:
print str(err)
print (traceback.format_exc())
# Syntax checker has no visibility on variables and types
# so we have to discard exceptions sent by e.g. find_variable
pass
......
......@@ -633,9 +633,9 @@ class SDL_Scene(QtGui.QGraphicsScene, object):
Clipboard.copy(self.selected_symbols())
except TypeError as error_msg:
try:
self.messages_window.addItem(str(error_msg))
self.messages_window.addItem(unicode(error_msg))
except AttributeError:
LOG.error(str(error_msg))
LOG.error(unicode(error_msg))
raise
def cut_selected_symbols(self):
......@@ -662,7 +662,11 @@ class SDL_Scene(QtGui.QGraphicsScene, object):
try:
new_items = Clipboard.paste(parent_item, self)
except TypeError as error_msg:
self.messages_window.addItem(str(error_msg))
LOG.error(str(error_msg))
try:
self.messages_window.addItem(str(error_msg))
except AttributeError:
pass
else:
self.undo_stack.beginMacro('Paste')
for item in new_items:
......@@ -685,28 +689,6 @@ class SDL_Scene(QtGui.QGraphicsScene, object):
self.undo_stack.endMacro()
self.refresh()
# def get_pr_string(self):
# ''' Parse the graphical items and returns a PR string '''
# pr_data = deque()
# for each in self.processes:
# pr_data.append(each.PR())
#
# for item in chain(self.texts, self.procs, self.start):
# pr_data.append(item.PR())
# for item in self.floating_labels:
# pr_data.append(item.PR_floating())
# composite = set(self.composite_states.keys())
# for item in self.states:
# if item.is_composite():
# try:
# composite.remove(unicode(item).lower())
# pr_data.appendleft(item.parse_composite_state())
# except KeyError:
# pass
# pr_data.append(item.PR_state())
#
# return list(pr_data)
def sdl_to_statechart(self):
''' Create a graphviz representation of the SDL model '''
pr_raw = Pr.parse_scene(self)
......@@ -723,7 +705,7 @@ class SDL_Scene(QtGui.QGraphicsScene, object):
def export_branch_to_picture(self, symbol, filename, doc_format):
''' Save a symbol and its followers to a file '''
temp_scene = SDL_Scene()
temp_scene = SDL_Scene(context=self.context)
temp_scene.messages_window = self.messages_window
self.clearSelection()
symbol.select()
......@@ -746,7 +728,10 @@ class SDL_Scene(QtGui.QGraphicsScene, object):
# Save in multiple files
index = 0
for item in self.floating_symb:
self.export_branch_to_picture(item, filename + str(index),
LOG.info('Saving {ext} file: {name}.{ext}'
.format(ext=doc_format, name=filename + '-' + str(index)))
self.export_branch_to_picture(item,
filename + '-' + str(index),
doc_format)
index += 1
......@@ -756,12 +741,15 @@ class SDL_Scene(QtGui.QGraphicsScene, object):
self.clearSelection()
self.clear_focus()
# Copy in a different scene to get the smallest rectangle
other_scene = SDL_Scene()
other_scene = SDL_Scene(context=self.context)
other_scene.messages_window = self.messages_window
other_scene.setBackgroundBrush(QtGui.QBrush())
for each in self.floating_symb:
each.select()
self.copy_selected_symbols()
try:
self.copy_selected_symbols()
except AttributeError as err:
LOG.error(str(err))
other_scene.paste_symbols()
each.select(False)
rect = other_scene.sceneRect()
......@@ -1796,9 +1784,9 @@ def parse(files):
LOG.info('Checking ' + str(files))
ast, warnings, errors = ogParser.parse_pr(files=files)
LOG.info(
'Parsing complete. Summary, found %d warnings and %d errors' % (len(warnings), len(errors))
)
LOG.info('Parsing complete. '
'Summary, found {} warnings and {} errors'
.format(len(warnings), len(errors)))
for warning in warnings:
LOG.warning(warning[0])
for error in errors:
......@@ -1828,11 +1816,14 @@ def generate(process, options):
LOG.error('LLVM IR generation failed')
def export(process, options):
def export(ast, options):
''' Export process '''
# Qt must be initialized before using SDL_Scene
init_qt()
# Initialize the clipboard
Clipboard.CLIPBOARD = SDL_Scene(context='clipboard')
export_fmt = []
if options.png:
export_fmt.append('png')
......@@ -1843,15 +1834,43 @@ def export(process, options):
if not export_fmt:
return
process, = ast.processes
try:
syst, = ast.systems
block, = syst.blocks
if block.processes[0].referenced:
LOG.debug('Process is referenced, fixing')
block.processes = [process]
except ValueError:
# No System/Block hierarchy, creating single block
block = ogAST.Block()
block.processes = [process]
name = process.processName
scene = SDL_Scene(context='process')
scene.render_everything(process)
scene = SDL_Scene(context='block')
scene.render_everything(block)
# Update connections, placements:
scene.refresh()
for doc_fmt in export_fmt:
LOG.info('Saving {ext} file: {name}.{ext}'.format(ext=doc_fmt, name=name))
scene.export_img(name, doc_format=doc_fmt, split=options.split)
scenes = [scene]
def find_nested_scenes(top):
''' Find all scenes (procedures, states, processes...) '''
for each in top.visible_symb:
if each.nested_scene:
yield each.nested_scene
for deep in find_nested_scenes(each.nested_scene):
yield deep
for each in find_nested_scenes(scene):
if any(each.visible_symb):
scenes.append(each)
for idx, diagram in enumerate(scenes):
for doc_fmt in export_fmt:
LOG.info('Saving {ext} file: {name}.{ext}'
.format(ext=doc_fmt, name=name+str(idx)))
diagram.export_img(name+str(idx),
doc_format=doc_fmt,
split=options.split)
def cli(options):
......@@ -1867,7 +1886,7 @@ def cli(options):
return 1
if options.png or options.pdf or options.svg:
export(ast.processes[0], options)
export(ast, options)
if options.toAda or options.llvm:
if not errors:
......@@ -1879,7 +1898,7 @@ def cli(options):
def init_qt():
''' Initialize QT '''
''' Initialize Qt '''
app = QtGui.QApplication.instance()
if app is None:
app = QtGui.QApplication(sys.argv)
......
......@@ -846,6 +846,7 @@ class ProcedureStart(Start):
# Define reserved keywords for the syntax highlighter
blackbold = SDL_BLACKBOLD
redbold = SDL_REDBOLD
common_name = 'proc_start'
def set_shape(self, width, height):
''' Compute the polygon to fit in width, height '''
......@@ -863,6 +864,7 @@ class StateStart(Start):
''' Composite states can have several named START symbols '''
has_text_area = True
is_singleton = False
common_name = 'state_start'
def __unicode__(self):
''' Return the state entry point '''
......
......@@ -11,8 +11,12 @@ test-ada:
#gnatbind -n trafficlight.ali
#gnatlink -o testcase test.o trafficlight.ali -lgnat -lm
test-export:
../../../opengeode.py --png --pdf --svg trafficlight.pr system_structure.pr
../../../opengeode.py --png --pdf --svg --split trafficlight.pr system_structure.pr
coverage:
coverage run -p ../../../opengeode.py trafficlight.pr system_structure.pr --toAda
clean:
rm -rf *.adb *.ads *.pyc runSpark.sh spark.idx *.o *.ali gnat.cfg examiner bin *.wrn *.gpr test
rm -rf *.adb *.ads *.pyc runSpark.sh spark.idx *.o *.ali gnat.cfg examiner bin *.wrn *.gpr *.pdf *.svg *.png test
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment