Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
OpenGEODE
Commits
1c5933ff
Commit
1c5933ff
authored
May 06, 2014
by
Maxime Perrotin
Browse files
Fixed segfaults due to pyside bugs
parent
736a6fb7
Changes
9
Expand all
Hide whitespace changes
Inline
Side-by-side
Connectors.py
View file @
1c5933ff
...
...
@@ -19,6 +19,7 @@ import os
import
sys
import
math
import
logging
from
collections
import
namedtuple
from
PySide.QtCore
import
Qt
,
QPointF
,
QLineF
...
...
@@ -39,8 +40,9 @@ class Connection(QGraphicsPathItem, object):
super
(
Connection
,
self
).
__init__
(
parent
)
self
.
parent
=
parent
self
.
child
=
child
self
.
start_point
=
QPointF
(
0
,
0
)
self
.
end_point
=
QPointF
(
0
,
0
)
self
.
_start_point
=
None
self
.
_end_point
=
None
self
.
_middle_points
=
[]
pen
=
QPen
()
pen
.
setColor
(
Qt
.
blue
)
pen
.
setCosmetic
(
False
)
...
...
@@ -50,6 +52,34 @@ class Connection(QGraphicsPathItem, object):
# Activate cache mode to boost rendering by calling paint less often
self
.
setCacheMode
(
QGraphicsItem
.
DeviceCoordinateCache
)
@
property
def
start_point
(
self
):
''' Compute connection origin - redefine in subclasses '''
return
self
.
_start_point
or
QPointF
(
0
,
0
)
@
property
def
end_point
(
self
):
''' Compute connection end point - redefine in subclasses '''
return
self
.
_end_point
or
QPointF
(
0
,
0
)
@
property
def
middle_points
(
self
):
''' Compute connection intermediate points - redefine in subclasses '''
return
self
.
_middle_points
def
arrow
(
self
,
path
=
None
):
''' Compute the two points of an arrow head - vertical by default '''
endp
=
self
.
end_point
return
(
QPointF
(
endp
.
x
()
-
5
,
endp
.
y
()
-
5
),
QPointF
(
endp
.
x
()
+
5
,
endp
.
y
()
-
5
))
def
draw_arrow_head
(
self
,
shape
):
''' Generic function to draw any arrow head - don't redefine '''
arrowhead
=
self
.
arrow
(
shape
)
shape
.
lineTo
(
arrowhead
[
0
])
shape
.
moveTo
(
self
.
end_point
)
shape
.
lineTo
(
arrowhead
[
1
])
def
__str__
(
self
):
''' Print connection information for debug purpose'''
return
'Connection: parent = {p}, child = {c}'
.
format
(
...
...
@@ -57,112 +87,108 @@ class Connection(QGraphicsPathItem, object):
def
reshape
(
self
):
''' Update the connection or arrow shape '''
new_shape
=
QPainterPath
()
self
.
setPath
(
new_shape
)
return
shape
=
QPainterPath
()
shape
.
moveTo
(
self
.
start_point
)
for
point
in
self
.
middle_points
:
shape
.
lineTo
(
point
)
shape
.
lineTo
(
self
.
end_point
)
# If required draw an arrow head (e.g. in SDL NEXTSTATE and JOIN)
if
self
.
child
.
arrow_head
:
self
.
draw_arrow_head
(
shape
)
self
.
setPath
(
shape
)
class
RakeConnection
(
Connection
):
''' Fork-like connection, e.g. between a state and an input symbol '''
def
reshape
(
self
):
''' Update the connection or arrow shape '''
new_shape
=
QPainterPath
()
@
property
def
start_point
(
self
):
''' Compute connection origin - redefined function '''
parent_rect
=
self
.
parentItem
().
boundingRect
()
# Define connection start point
self
.
start_point
=
\
QPointF
(
parent_rect
.
width
()
/
2
,
parent_rect
.
height
())
# Define connection end point
self
.
end_point
=
self
.
child
.
pos
()
# Move to start point and draw the connection
new_shape
.
moveTo
(
self
.
start_point
)
self
.
end_point
.
setX
(
self
.
child
.
pos
().
x
()
+
self
.
child
.
boundingRect
().
width
()
/
2
)
new_shape
.
lineTo
(
self
.
start_point
.
x
(),
self
.
start_point
.
y
()
+
10
)
new_shape
.
lineTo
(
self
.
end_point
.
x
(),
self
.
start_point
.
y
()
+
10
)
new_shape
.
lineTo
(
self
.
end_point
)
self
.
setPath
(
new_shape
)
return
QPointF
(
parent_rect
.
width
()
/
2
,
parent_rect
.
height
())
@
property
def
end_point
(
self
):
''' Compute connection end point - redefined function '''
coord
=
self
.
child
.
pos
()
coord
.
setX
(
coord
.
x
()
+
self
.
child
.
boundingRect
().
width
()
/
2
)
return
coord
@
property
def
middle_points
(
self
):
''' Compute connection intermediate points - redefined function '''
yield
QPointF
(
self
.
start_point
.
x
(),
self
.
start_point
.
y
()
+
10
)
yield
QPointF
(
self
.
end_point
.
x
(),
self
.
start_point
.
y
()
+
10
)
class
JoinConnection
(
Connection
):
''' Inverted fork-like connection, to join to a common point '''
def
reshape
(
self
):
''' Update the connection
or arrow shape '''
new_shape
=
QPainterPath
()
''' Update the connection
shape - redefined: if the last element
of a branch is e.g. a nextstate, don't join the connection point '''
if
self
.
parentItem
().
terminal_symbol
:
self
.
setPath
(
new_shape
)
return
parent_rect
=
self
.
parentItem
().
boundingRect
()
# Define connection start point
if
hasattr
(
self
.
parentItem
(),
'connectionPoint'
):
self
.
start_point
=
self
.
parentItem
().
connectionPoint
self
.
setPath
(
QPainterPath
())
else
:
self
.
start_point
=
\
QPointF
(
parent_rect
.
width
()
/
2
,
parent_rect
.
height
())
# Define connection end point
connection_point_scene
=
\
self
.
child
.
mapToScene
(
self
.
child
.
connectionPoint
)
connection_point_local
=
\
self
.
mapFromScene
(
connection_point_scene
)
self
.
end_point
=
connection_point_local
# Move to start point and draw the connection
new_shape
.
moveTo
(
self
.
start_point
)
new_shape
.
lineTo
(
self
.
start_point
.
x
(),
self
.
end_point
.
y
()
-
10
)
new_shape
.
lineTo
(
self
.
end_point
.
x
(),
self
.
end_point
.
y
()
-
10
)
new_shape
.
lineTo
(
self
.
end_point
)
self
.
setPath
(
new_shape
)
super
(
JoinConnection
,
self
).
reshape
()
@
property
def
start_point
(
self
):
''' Compute connection origin - redefined function '''
parent_rect
=
self
.
parentItem
().
boundingRect
()
return
getattr
(
self
.
parentItem
(),
'connectionPoint'
,
QPointF
(
parent_rect
.
width
()
/
2
,
parent_rect
.
height
()))
@
property
def
end_point
(
self
):
''' Compute connection end point - redefined function '''
point_scene
=
self
.
child
.
mapToScene
(
self
.
child
.
connectionPoint
)
return
self
.
mapFromScene
(
point_scene
)
@
property
def
middle_points
(
self
):
''' Compute connection intermediate points - redefined function '''
yield
QPointF
(
self
.
start_point
.
x
(),
self
.
end_point
.
y
()
-
10
)
yield
QPointF
(
self
.
end_point
.
x
(),
self
.
end_point
.
y
()
-
10
)
class
VerticalConnection
(
Connection
):
''' Vertical line with or without arrow '''
def
reshape
(
self
):
''' Connection shape: vertical line '''
new_shape
=
QPainterPath
()
if
self
.
parentItem
().
terminal_symbol
:
self
.
setPath
(
new_shape
)
return
@
property
def
start_point
(
self
):
''' Compute connection origin - redefined function '''
parent_rect
=
self
.
parentItem
().
boundingRect
()
# Define connection start point
if
hasattr
(
self
.
parentItem
(),
'connectionPoint'
):
self
.
start_point
=
self
.
parentItem
().
connectionPoint
else
:
self
.
start_point
=
QPointF
(
parent_rect
.
width
()
/
2
,
parent_rect
.
height
())
# Define connection end point
self
.
end_point
=
self
.
child
.
pos
()
self
.
end_point
.
setX
(
self
.
start_point
.
x
())
# Move to start point and draw the connection
new_shape
.
moveTo
(
self
.
start_point
)
new_shape
.
lineTo
(
self
.
end_point
)
# If required draw an arrow head (e.g. in SDL NEXTSTATE and JOIN)
if
self
.
child
.
arrow_head
:
new_shape
.
lineTo
(
self
.
end_point
.
x
()
-
5
,
self
.
end_point
.
y
()
-
5
)
new_shape
.
moveTo
(
self
.
end_point
)
new_shape
.
lineTo
(
self
.
end_point
.
x
()
+
5
,
self
.
end_point
.
y
()
-
5
)
self
.
setPath
(
new_shape
)
return
getattr
(
self
.
parentItem
(),
'connectionPoint'
,
QPointF
(
parent_rect
.
width
()
/
2
,
parent_rect
.
height
()))
@
property
def
end_point
(
self
):
''' Compute connection end point - redefined function '''
point
=
self
.
child
.
pos
()
point
.
setX
(
self
.
start_point
.
x
())
return
point
class
CommentConnection
(
Connection
):
''' Class handling connection to comment symbols, fixed at the right
of a symbol '''
def
reshape
(
self
):
''' Set the connection shape '''
new_shape
=
QPainterPath
()
@
property
def
start_point
(
self
):
''' Compute connection origin - redefined function '''
parent_rect
=
self
.
parentItem
().
boundingRect
()
# Define connection start point
self
.
start_point
=
\
QPointF
(
parent_rect
.
width
(),
parent_rect
.
height
()
/
2
)
# Define connection end point
return
QPointF
(
parent_rect
.
width
(),
parent_rect
.
height
()
/
2
)
@
property
def
end_point
(
self
):
''' Compute connection end point - redefined function '''
if
self
.
child
.
on_the_right
:
self
.
end_point
=
QPointF
(
self
.
child
.
x
(),
self
.
child
.
y
()
+
self
.
child
.
boundingRect
().
height
()
/
2
)
return
QPointF
(
self
.
child
.
x
(),
self
.
child
.
y
()
+
self
.
child
.
boundingRect
().
height
()
/
2
)
else
:
self
.
end_point
=
QPointF
(
self
.
child
.
x
()
+
self
.
child
.
boundingRect
().
width
(),
self
.
child
.
y
()
+
self
.
child
.
boundingRect
().
height
()
/
2
)
# Move to start point and draw the connection
new_shape
.
moveTo
(
self
.
start_point
)
return
QPointF
(
self
.
child
.
x
()
+
self
.
child
.
boundingRect
().
width
(),
self
.
child
.
y
()
+
self
.
child
.
boundingRect
().
height
()
/
2
)
@
property
def
middle_points
(
self
):
''' Compute connection intermediate points - redefined function '''
# Make sure the connection does not overlap the comment item
if
(
self
.
child
.
on_the_right
or
(
not
self
.
child
.
on_the_right
and
...
...
@@ -171,11 +197,8 @@ class CommentConnection(Connection):
go_to_point
=
self
.
start_point
.
x
()
+
5
else
:
go_to_point
=
self
.
end_point
.
x
()
+
5
new_shape
.
lineTo
(
go_to_point
,
self
.
start_point
.
y
())
new_shape
.
lineTo
(
go_to_point
,
self
.
end_point
.
y
())
new_shape
.
lineTo
(
self
.
end_point
.
x
(),
self
.
end_point
.
y
())
new_shape
.
lineTo
(
self
.
end_point
)
self
.
setPath
(
new_shape
)
yield
QPointF
(
go_to_point
,
self
.
start_point
.
y
())
yield
QPointF
(
go_to_point
,
self
.
end_point
.
y
())
class
Channel
(
Connection
):
...
...
@@ -278,13 +301,10 @@ class Edge(Connection):
super
(
Edge
,
self
).
__init__
(
edge
[
'source'
],
edge
[
'target'
])
self
.
edge
=
edge
self
.
graph
=
graph
# Set connection points as not visible, by default
self
.
bezier_visible
=
False
# Initialize control point coordinates
# Start and End points are optional - graphviz decision
self
.
start_point
=
(
self
.
mapFromScene
(
*
self
.
edge
[
'start'
])
if
self
.
edge
.
get
(
'start'
)
else
None
)
self
.
end_point
=
(
self
.
mapFromScene
(
*
self
.
edge
[
'end'
])
if
self
.
edge
.
get
(
'end'
)
else
None
)
self
.
bezier
=
[
self
.
mapFromScene
(
*
self
.
edge
[
'spline'
][
0
])]
# Bezier control points (groups of three points):
assert
(
len
(
self
.
edge
[
'spline'
])
%
3
==
1
)
...
...
@@ -292,8 +312,6 @@ class Edge(Connection):
self
.
bezier
.
append
([
Controlpoint
(
self
.
mapFromScene
(
*
self
.
edge
[
'spline'
][
i
+
j
]),
self
)
for
j
in
range
(
3
)])
# Set connection points as not visible, by default
self
.
bezier_visible
=
False
# Create connection points at start and end of the edge
self
.
source_connection
=
Connectionpoint
(
...
...
@@ -304,6 +322,19 @@ class Edge(Connection):
self
.
child
.
movable_points
.
append
(
self
.
end_connection
)
self
.
reshape
()
@
property
def
start_point
(
self
):
''' Compute connection origin - redefine in subclasses '''
# Start point is optional - graphviz decision
return
self
.
mapFromScene
(
*
self
.
edge
[
'start'
])
\
if
self
.
edge
.
get
(
'start'
)
else
None
@
property
def
end_point
(
self
):
''' Compute connection end point - redefine in subclasses '''
return
self
.
mapFromScene
(
*
self
.
edge
[
'end'
])
\
if
self
.
edge
.
get
(
'end'
)
else
None
def
bezier_set_visible
(
self
,
visible
=
True
):
''' Display or hide the edge control points '''
self
.
bezier_visible
=
visible
...
...
@@ -325,6 +356,25 @@ class Edge(Connection):
''' On a mouse click, display the control points '''
self
.
bezier_set_visible
(
True
)
def
arrow
(
self
,
path
):
''' Compute the two points of the arrow head with the right angle '''
length
=
path
.
length
()
percent
=
path
.
percentAtLength
(
length
-
10.0
)
src
=
path
.
pointAtPercent
(
percent
)
end_point
=
path
.
currentPosition
()
line
=
QLineF
(
src
,
end_point
)
angle
=
math
.
acos
(
line
.
dx
()
/
line
.
length
())
if
line
.
dy
()
>=
0
:
angle
=
math
.
pi
*
2
-
angle
arrow_size
=
10.0
arrow_p1
=
end_point
+
QPointF
(
math
.
sin
(
angle
-
math
.
pi
/
3
)
*
arrow_size
,
math
.
cos
(
angle
-
math
.
pi
/
3
)
*
arrow_size
)
arrow_p2
=
end_point
+
QPointF
(
math
.
sin
(
angle
-
math
.
pi
+
math
.
pi
/
3
)
*
arrow_size
,
math
.
cos
(
angle
-
math
.
pi
+
math
.
pi
/
3
)
*
arrow_size
)
return
(
arrow_p1
,
arrow_p2
)
# pylint: disable=R0914
def
reshape
(
self
):
''' Update the shape of the edge (redefined function) '''
...
...
@@ -343,27 +393,11 @@ class Edge(Connection):
if
self
.
end_point
:
path
.
lineTo
(
self
.
end_connection
.
center
)
# Draw the arrow head
length
=
path
.
length
()
percent
=
path
.
percentAtLength
(
length
-
10.0
)
src
=
path
.
pointAtPercent
(
percent
)
#angle = path.angleAtPercent(percent)
#print angle
end_point
=
path
.
currentPosition
()
line
=
QLineF
(
src
,
end_point
)
angle
=
math
.
acos
(
line
.
dx
()
/
line
.
length
())
if
line
.
dy
()
>=
0
:
angle
=
math
.
pi
*
2
-
angle
arrow_size
=
10.0
arrow_p1
=
end_point
+
QPointF
(
math
.
sin
(
angle
-
math
.
pi
/
3
)
*
arrow_size
,
math
.
cos
(
angle
-
math
.
pi
/
3
)
*
arrow_size
)
arrow_p2
=
end_point
+
QPointF
(
math
.
sin
(
angle
-
math
.
pi
+
math
.
pi
/
3
)
*
arrow_size
,
math
.
cos
(
angle
-
math
.
pi
+
math
.
pi
/
3
)
*
arrow_size
)
path
.
lineTo
(
arrow_p1
)
path
.
lineTo
(
end_point
)
path
.
lineTo
(
arrow_p2
)
arrowhead
=
self
.
arrow
(
path
)
path
.
lineTo
(
arrowhead
[
0
])
path
.
moveTo
(
end_point
)
path
.
lineTo
(
arrowhead
[
1
])
path
.
moveTo
(
end_point
)
try
:
# Add the transition label, if any (none for the START edge)
...
...
@@ -403,6 +437,3 @@ class Edge(Connection):
for
sub1
in
self
.
bezier
[
1
:]
for
point
in
sub1
]
painter
.
drawPolyline
([
self
.
source_connection
.
center
]
+
points_flat
+
[
self
.
end_connection
.
center
])
__init__.py
View file @
1c5933ff
...
...
@@ -7,6 +7,6 @@
defined language, and generate Ada code from the models.
"""
__version__
=
"0.99"
__version__
=
"0.99
1
"
from
opengeode
import
opengeode
genericSymbols.py
View file @
1c5933ff
...
...
@@ -857,7 +857,6 @@ class Symbol(QObject, QGraphicsPathItem, object):
'''
# Save current position to be able to revert move
self
.
coord
=
self
.
pos
()
#event_pos = event.pos()
rect
=
self
.
boundingRect
()
self
.
height
=
rect
.
height
()
if
self
.
grabber
.
resize_mode
!=
''
:
...
...
@@ -873,7 +872,7 @@ class Symbol(QObject, QGraphicsPathItem, object):
def
mouse_move
(
self
,
event
):
''' Handle resizing of items - moving is handled in subclass '''
self
.
updateConnectionPoints
()
# If any, update movable end points of connections
# If any, update movable end points of connections
for
point
in
self
.
movable_points
:
point
.
edge
.
end_connection
.
update_position
()
if
self
.
mode
==
'Resize'
:
...
...
icons.py
View file @
1c5933ff
...
...
@@ -2,7 +2,7 @@
# Resource object code
#
# Created: Mon
Apr 28 21:41:51
2014
# Created: Mon
May 5 22:01:46
2014
# by: The Resource Compiler for PySide (Qt v4.8.6)
#
# WARNING! All changes made in this file will be lost!
opengeode.py
View file @
1c5933ff
...
...
@@ -86,7 +86,7 @@ except ImportError:
pass
__all__
=
[
'opengeode'
]
__version__
=
'0.99'
__version__
=
'0.99
1
'
if
hasattr
(
sys
,
'frozen'
):
# Detect if we are running on Windows (py2exe-generated)
...
...
@@ -961,7 +961,9 @@ class SDL_Scene(QtGui.QGraphicsScene, object):
item
.
select
()
except
AttributeError
:
pass
self
.
removeItem
(
self
.
select_rect
)
#self.removeItem(self.select_rect)
# XXX stop with removeItem, it provokes segfault
self
.
select_rect
.
hide
()
self
.
mode
=
'idle'
super
(
SDL_Scene
,
self
).
mouseReleaseEvent
(
event
)
...
...
@@ -1095,6 +1097,8 @@ class SDL_Scene(QtGui.QGraphicsScene, object):
class
SDL_View
(
QtGui
.
QGraphicsView
,
object
):
''' Main graphic view used to display the SDL scene and handle zoom '''
# signal to ask the main application that a new scene is needed
need_new_scene
=
QtCore
.
Signal
()
def
__init__
(
self
,
scene
):
''' Create the SDL view holding the scene '''
super
(
SDL_View
,
self
).
__init__
(
scene
)
...
...
@@ -1194,7 +1198,9 @@ class SDL_View(QtGui.QGraphicsView, object):
scene_rect
.
setWidth
(
max
(
scene_rect
.
width
(),
view_size
.
width
()))
scene_rect
.
setHeight
(
max
(
scene_rect
.
height
(),
view_size
.
height
()))
if
self
.
phantom_rect
and
self
.
phantom_rect
in
self
.
scene
().
items
():
self
.
scene
().
removeItem
(
self
.
phantom_rect
)
#self.scene().removeItem(self.phantom_rect)
# XXX stop with removeItem, it provokes segfault
self
.
phantom_rect
.
hide
()
self
.
phantom_rect
=
self
.
scene
().
addRect
(
scene_rect
,
pen
=
QtGui
.
QPen
(
QtGui
.
QColor
(
0
,
0
,
0
,
0
)))
# Hide the rectangle so that it does not collide with the symbols
...
...
@@ -1318,7 +1324,10 @@ class SDL_View(QtGui.QGraphicsView, object):
# Adjust scrollbars if diagram got bigger due to a move
if
self
.
scene
().
context
!=
'statechart'
:
# Make sure scene size remains OK when adding/moving symbols
self
.
refresh
()
# Avoid doing it when editing texts - it would prevent text
# selection or cursor move
if
not
isinstance
(
self
.
scene
().
focusItem
(),
EditableText
):
self
.
refresh
()
super
(
SDL_View
,
self
).
mouseReleaseEvent
(
evt
)
def
save_as
(
self
):
...
...
@@ -1419,46 +1428,54 @@ class SDL_View(QtGui.QGraphicsView, object):
def
open_diagram
(
self
):
''' Load one or several .pr file and display the state machine '''
if
self
.
new_diagram
():
filenames
,
_
=
QtGui
.
QFileDialog
.
getOpenFileNames
(
self
,
"Open model(s)"
,
"."
,
"SDL model (*.pr)"
)
if
not
filenames
:
return
else
:
self
.
load_file
(
filenames
)
if
not
self
.
new_diagram
():
return
filenames
,
_
=
QtGui
.
QFileDialog
.
getOpenFileNames
(
self
,
"Open model(s)"
,
"."
,
"SDL model (*.pr)"
)
if
not
filenames
:
return
else
:
self
.
load_file
(
filenames
)
def
isModelClean
(
self
):
''' Check recursively if anything has changed in any scene '''
if
self
.
parent_scene
:
scene
=
self
.
parent_scene
[
0
][
0
]
else
:
scene
=
self
.
scene
()
for
each
in
chain
([
scene
],
scene
.
all_nested_scenes
):
if
not
each
.
undo_stack
.
isClean
():
return
False
return
True
def
propose_to_save
(
self
):
''' Display a dialog to let the user save his diagram '''
msg_box
=
QtGui
.
QMessageBox
(
self
)
msg_box
.
setWindowTitle
(
'OpenGEODE'
)
msg_box
.
setText
(
"The model has been modified."
)
msg_box
.
setInformativeText
(
"Do you want to save your changes?"
)
msg_box
.
setStandardButtons
(
QtGui
.
QMessageBox
.
Save
|
QtGui
.
QMessageBox
.
Discard
|
QtGui
.
QMessageBox
.
Cancel
)
msg_box
.
setDefaultButton
(
QtGui
.
QMessageBox
.
Save
)
ret
=
msg_box
.
exec_
()
if
ret
==
QtGui
.
QMessageBox
.
Save
:
if
not
self
.
save_diagram
():
return
False
elif
ret
==
QtGui
.
QMessageBox
.
Cancel
:
return
False
return
True
def
new_diagram
(
self
):
''' If model state is clean, reset current diagram '''
# FIXME: incomplete check of the cleanliness of the model
# - must check all subscenes
if
self
.
scene
().
undo_stack
.
isClean
():
is_clean
=
True
while
self
.
parent_scene
:
self
.
go_up
()
if
not
self
.
scene
().
undo_stack
.
isClean
():
is_clean
=
False
else
:
is_clean
=
False
if
not
is_clean
:
if
not
self
.
isModelClean
():
# If changes occured since last save, pop up a window
msg_box
=
QtGui
.
QMessageBox
(
self
)
msg_box
.
setWindowTitle
(
'OpenGEODE'
)
msg_box
.
setText
(
"The model has been modified."
)
msg_box
.
setInformativeText
(
"Do you want to save your changes?"
)
msg_box
.
setStandardButtons
(
QtGui
.
QMessageBox
.
Save
|
QtGui
.
QMessageBox
.
Discard
|
QtGui
.
QMessageBox
.
Cancel
)
msg_box
.
setDefaultButton
(
QtGui
.
QMessageBox
.
Save
)
ret
=
msg_box
.
exec_
()
if
ret
==
QtGui
.
QMessageBox
.
Save
:
if
not
self
.
save_diagram
():
return
False
elif
ret
==
QtGui
.
QMessageBox
.
Discard
:
pass
elif
ret
==
QtGui
.
QMessageBox
.
Cancel
:
if
not
self
.
propose_to_save
():
return
False
self
.
scene
().
undo_stack
.
clear
()
self
.
scene
().
clear
()
self
.
need_new_scene
.
emit
()
self
.
parent_scene
=
[]
#self.scene().undo_stack.clear()
#self.scene().clear()
G_SYMBOLS
.
clear
()
self
.
scene
().
process_name
=
''
self
.
filename
=
None
...
...
@@ -1549,10 +1566,21 @@ class OG_MainWindow(QtGui.QMainWindow, object):
self
.
datatypes_scene
=
None
self
.
asn1_area
=
None
def
new_scene
(
self
):
''' Create a new, clean SDL scene. This function is necessary because
it is not possible to use QGraphicsScene.clear(), because of Pyside
bugs with deletion of items on application exit '''
self
.
scene
=
SDL_Scene
(
context
=
'block'
)
if
self
.
view
:
self
.
scene
.
messages_window
=
self
.
view
.
messages_window
self
.
view
.
setScene
(
self
.
scene
)
self
.
view
.
refresh
()
def
start
(
self
,
file_name
):
''' Initializes all objects to start the application '''
# Create a graphic scene: the main canvas
self
.
scene
=
SDL_Scene
(
context
=
'block'
)
self
.
new_scene
(
)
# Find SDL_View widget
self
.
view
=
self
.
findChild
(
SDL_View
,
'graphicsView'
)
self
.
view
.
setScene
(
self
.
scene
)
...
...
@@ -1579,6 +1607,9 @@ class OG_MainWindow(QtGui.QMainWindow, object):
ada_action
.
activated
.
connect
(
self
.
view
.
generate_ada
)
png_action
.
activated
.
connect
(
self
.
view
.
save_png
)
# Connect signal to let the view request a new scene
self
.
view
.
need_new_scene
.
connect
(
self
.
new_scene
)
# Add a toolbar widget (not in .ui file due to pyside bugs)
toolbar
=
Sdl_toolbar
(
self
)
...
...
@@ -1688,11 +1719,11 @@ class OG_MainWindow(QtGui.QMainWindow, object):
_
,
pattern
,
new
,
_
=
search
.
match
(
command
).
groups
()
LOG
.
debug
(
'Replacing {this} with {that}'
.
format
(
this
=
pattern
,
that
=
new
))
self
.
scene
.
search
(
pattern
,
replace_with
=
new
)
self
.
view
.
scene
()
.
search
(
pattern
,
replace_with
=
new
)
except
AttributeError
:
if
command
.
startswith
(
'/'
)
and
len
(
command
)
>
1
:
LOG
.
debug
(
'Searching for '
+
command
[
1
:])
self
.
scene
.
search
(
command
[
1
:])
self
.
view
.
scene
()
.
search
(
command
[
1
:])
else
:
saveclose
=
re
.
compile
(
r
':(w)?(q)?(!)?'
)
try
:
...
...
@@ -1702,7 +1733,7 @@ class OG_MainWindow(QtGui.QMainWindow, object):
if
not
saved
and
not
force
and
close_app
:
return
if
force
and
close_app
:
self
.
scene
.
undo_stack
.
clear
()
self
.
view
.
scene
()
.
undo_stack
.
clear
()
if
close_app
:
self
.
close
()
except
AttributeError
:
...
...
@@ -1712,7 +1743,11 @@ class OG_MainWindow(QtGui.QMainWindow, object):
def
keyPressEvent
(
self
,
key_event
):
''' Handle keyboard: Statechart rendering '''
if
key_event
.
key
()
==
Qt
.
Key_F4
and
graphviz
:
graph
=
self
.
scene
.
sdl_to_statechart
()
if
self
.
view
.
parent_scene
:
scene
=
self
.
view
.
parent_scene
[
0
][
0
]
else
:
scene
=
self
.
view
.
scene
()
graph
=
scene
.
sdl_to_statechart
()
try
:
Statechart
.
render_statechart
(
self
.
statechart_scene
,
graph
)
except
(
IOError
,
TypeError
)
as
err
:
...
...
@@ -1730,16 +1765,17 @@ class OG_MainWindow(QtGui.QMainWindow, object):
# pylint: disable=C0103
def
closeEvent
(
self
,
event
):
''' Close main application '''
if
self
.
view
.
new_diagram
():
# Clear the list of top-level symbols to avoid possible exit-crash
# due to pyside badly handling items that are not part of any scene