Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
asn1-value-editor
Commits
ae300714
Commit
ae300714
authored
Jan 04, 2015
by
Maxime Perrotin
Browse files
Introduce undo command for the msc handler
parent
d1ab49e9
Changes
4
Hide whitespace changes
Inline
Side-by-side
asn1_value_editor/gui.py
View file @
ae300714
...
...
@@ -354,6 +354,7 @@ def gui():
{
'dll'
:
Signal
(
unicode
,
type
,
type
)})
encoder_backend
.
send_via_dll
=
DLLHandler
()
encoder_backend
.
send_via_dll
.
dll
.
connect
(
sdl
.
send_tc
)
editor
.
msc
.
connect
(
sdl
.
add_to_msc
)
else
:
editor
.
msc
.
connect
(
msc
.
addToMsc
)
...
...
asn1_value_editor/mscHandler.py
View file @
ae300714
...
...
@@ -5,7 +5,8 @@ from time import strftime
from
multiprocessing
import
Process
,
Pipe
from
PySide.QtGui
import
(
QFileDialog
,
QGraphicsView
,
QDockWidget
,
QMessageBox
,
QErrorMessage
,
QTableWidget
,
QTableWidgetItem
)
QErrorMessage
,
QTableWidget
,
QTableWidgetItem
,
QUndoCommand
)
from
PySide.QtCore
import
Slot
,
Qt
,
QFile
,
QTimer
from
PySide.QtUiTools
import
QUiLoader
...
...
@@ -13,7 +14,6 @@ from mscStreamingScene import MscStreamingScene
import
resources
CUR_DIR
=
os
.
path
.
dirname
(
os
.
path
.
realpath
(
__file__
))
#SCENARIO_DIALOG_FILE = os.path.join(CUR_DIR, 'logging.ui')
SCENARIO_DIALOG_FILE
=
':/logging.ui'
# Convenient type for handling MSC messages
...
...
@@ -21,6 +21,71 @@ SCENARIO_DIALOG_FILE = ':/logging.ui'
MSG
=
type
(
'MSG'
,
(),
{
'direction'
:
''
,
'label'
:
''
})
class
AddToMsc
(
QUndoCommand
):
''' Undo command to add something to the MSC (message, timer, box) '''
def
__init__
(
self
,
handler
,
direction
,
message
):
''' Init: prepare the message '''
super
(
AddToMsc
,
self
).
__init__
()
self
.
handler
=
handler
self
.
message
=
message
self
.
increase_factor
=
30
self
.
txt
=
MSG
()
self
.
txt
.
direction
=
direction
# Add a counter (unique Id) incremented for each message
# (eg. out MsgName,1(Param);) - to respect MSC syntax
split
=
message
.
strip
().
split
(
'('
,
1
)
if
len
(
split
)
>
1
:
self
.
txt
.
label
=
(
',%d('
%
handler
.
cnt_id
).
join
(
split
)
else
:
self
.
txt
.
label
=
split
[
0
]
+
',%d'
%
handler
.
cnt_id
# Create the graphical item
if
direction
in
(
'in'
,
'out'
):
if
direction
==
'out'
:
start_item
=
handler
.
gui_instance
end_item
=
handler
.
taste_instance
elif
direction
==
'in'
:
start_item
=
handler
.
taste_instance
end_item
=
handler
.
gui_instance
self
.
item
=
handler
.
msc_scene
.
addMessage
(
start_item
,
end_item
,
handler
.
next_y
,
label
=
message
)
elif
direction
==
'set'
:
self
.
item
=
handler
.
msc_scene
.
addSetTimer
(
handler
.
taste_instance
,
handler
.
next_y
,
message
)
elif
direction
==
'reset'
:
self
.
item
=
handler
.
msc_scene
.
addResetTimer
(
handler
.
taste_instance
,
handler
.
next_y
,
message
)
elif
direction
==
'timeout'
:
self
.
item
=
handler
.
msc_scene
.
addTimeout
(
handler
.
taste_instance
,
handler
.
next_y
,
message
)
elif
direction
==
'condition'
:
# Condition: single word with no space
self
.
item
=
handler
.
msc_scene
.
addCondition
(
handler
.
taste_instance
,
y
=
handler
.
next_y
,
label
=
condition
)
self
.
increase_factor
=
40
self
.
item
.
hide
()
# This is how to add a comment on the graph:
# comment = handler.msc_scene.addComment(msg)
#comment.setCommentText("Hello!")
def
undo
(
self
):
''' Undo: delete the item from the MSC '''
self
.
handler
.
cnt_id
-=
1
self
.
handler
.
msg
.
pop
()
self
.
handler
.
next_y
-=
self
.
increase_factor
self
.
item
.
hide
()
def
redo
(
self
):
''' Redo: add the item to the MSC '''
self
.
handler
.
cnt_id
+=
1
self
.
handler
.
msg
.
append
(
self
.
txt
)
self
.
handler
.
next_y
+=
self
.
increase_factor
self
.
item
.
show
()
class
mscHandler
(
object
):
'''
Class managing MSC operations
...
...
@@ -108,50 +173,63 @@ inst {fv};'''.format(fv=fv_name)]
else
:
self
.
dock
.
hide
()
@
Slot
(
unicode
,
unicode
)
def
addToMsc
(
self
,
direction
,
message
):
@
Slot
()
def
addToMsc
(
self
,
direction
,
message
,
undo_stack
=
None
):
''' Add a message to the MSC '''
if
not
self
.
running
:
self
.
log
.
debug
(
"MSC not running"
)
return
self
.
msc_started
=
True
msg
=
MSG
()
msg
.
direction
=
direction
# Add a counter (unique Id) incremented for each message
# (eg. out MsgName,1(Param);) - to respect MSC syntax
split
=
message
.
strip
().
split
(
'('
,
1
)
if
len
(
split
)
>
1
:
msg
.
label
=
(
',%d('
%
self
.
cnt_id
).
join
(
split
)
else
:
msg
.
label
=
split
[
0
]
+
',%d'
%
self
.
cnt_id
self
.
cnt_id
+=
1
self
.
msg
.
append
(
msg
)
# Draw the message on the MSC Scene
if
direction
in
(
'in'
,
'out'
):
if
direction
==
'out'
:
start_item
=
self
.
gui_instance
end_item
=
self
.
taste_instance
elif
direction
==
'in'
:
start_item
=
self
.
taste_instance
end_item
=
self
.
gui_instance
msg
=
self
.
msc_scene
.
addMessage
(
start_item
,
end_item
,
self
.
next_y
,
label
=
message
)
elif
direction
==
'set'
:
self
.
msc_scene
.
addSetTimer
(
self
.
taste_instance
,
self
.
next_y
,
message
)
elif
direction
==
'reset'
:
self
.
msc_scene
.
addResetTimer
(
self
.
taste_instance
,
self
.
next_y
,
message
)
elif
direction
==
'timeout'
:
self
.
msc_scene
.
addTimeout
(
self
.
taste_instance
,
self
.
next_y
,
message
)
# This is how to add a comment on the graph:
# comment = self.msc_scene.addComment(msg)
#comment.setCommentText("Hello!")
self
.
next_y
+=
30
undo_cmd
=
AddToMsc
(
self
,
direction
,
message
)
if
undo_stack
:
undo_stack
.
push
(
undo_cmd
)
# TODO: check that the redo() is called anyway
# msg = MSG()
# msg.direction = direction
# # Add a counter (unique Id) incremented for each message
# # (eg. out MsgName,1(Param);) - to respect MSC syntax
# split = message.strip().split('(', 1)
# if len(split) > 1:
# msg.label = (',%d(' % self.cnt_id).join(split)
# else:
# msg.label = split[0] + ',%d' % self.cnt_id
# self.cnt_id += 1
# self.msg.append(msg)
# # Draw the message on the MSC Scene
# if direction in ('in', 'out'):
# if direction == 'out':
# start_item = self.gui_instance
# end_item = self.taste_instance
# elif direction == 'in':
# start_item = self.taste_instance
# end_item = self.gui_instance
# msg = self.msc_scene.addMessage(
# start_item, end_item, self.next_y, label=message)
# self.next_y += 30
# elif direction == 'set':
# msg = self.msc_scene.addSetTimer(self.taste_instance,
# self.next_y,
# message)
# self.next_y += 30
# elif direction == 'reset':
# msg = self.msc_scene.addResetTimer(self.taste_instance,
# self.next_y,
# message)
# self.next_y += 30
# elif direction == 'timeout':
# msg = self.msc_scene.addTimeout(self.taste_instance,
# self.next_y,
# message)
# self.next_y += 30
# elif direction == 'condition':
# # Condition: single word with no space
# condbox = self.msc_scene.addCondition(self.taste_instance,
# y=self.next_y,
# label=condition)
# self.next_y += 40
# # This is how to add a comment on the graph:
# # comment = self.msc_scene.addComment(msg)
# #comment.setCommentText("Hello!")
@
Slot
(
unicode
)
def
addCondition
(
self
,
condition
):
...
...
asn1_value_editor/mscStreamingScene.py
View file @
ae300714
...
...
@@ -34,6 +34,7 @@ from mscgraphics import MscGraphInstance
from
mscgraphics
import
MscGraphBasicMSCScene
from
mscgraphics
import
MscGraphMessage
from
mscgraphics
import
MscGraphCondition
from
mscgraphics
import
MscGraphTimer
from
collections
import
deque
from
msccore
import
mscregexp
...
...
asn1_value_editor/sdlHandler.py
View file @
ae300714
...
...
@@ -77,7 +77,7 @@ class sdlHandler(QObject):
Class managing SDL models
'''
# signal sent whenever a paramless TM or TC event happens
msc
=
Signal
(
unicode
,
unicode
)
msc
=
Signal
(
unicode
,
unicode
,
QUndoStack
)
# Signal sent when the state of the SDL model changes
state_change
=
Signal
(
unicode
)
allowed_messages
=
Signal
(
list
)
...
...
@@ -226,16 +226,11 @@ class sdlHandler(QObject):
self
.
on_event
()
def
on_event
(
self
,
tc_name
=
None
,
param
=
None
):
''' Process signals indicating that a PI was called in the shared lib:
update global state, manage undo/redo, manage active buttons
This function does not trigger any undoable action, thus can
be called without restriction at any time, by anybody '''
if
not
ASN1
:
# The dataview must have been loaded to create ASN.1 native types
return
''' Update the list of global states and GUI after a TC has been sent
This function does not trigger any undoable action '''
complete_state
=
[]
# Read in the DLL the list of internal variables
for
var
,
(
sort
,
_
)
in
self
.
proc
.
variables
.
viewitems
():
# get internal variables, translate them to swig, and print them
typename
=
sort
.
ReferencedTypeName
.
replace
(
'-'
,
'_'
)
get_size
=
getattr
(
self
.
dll
,
"{}_size"
.
format
(
var
))
get_size
.
restype
=
ctypes
.
c_uint
...
...
@@ -258,9 +253,9 @@ class sdlHandler(QObject):
self
.
asn1_editor
.
updateVariable
(
as_pyside
,
root
=
self
.
tree_items
[
var
])
complete_state
.
append
(
asn1_instance
)
# not gser
# Add the SDL state to the
current
state
# Add the SDL state to the
new global
state
complete_state
.
append
(
self
.
current_sdl_state
)
# And save th
e current
state in
a
graph
# And save th
is new
state in
the
graph
, if it was not there yet
new_hash
=
hash
(
frozenset
(
complete_state
))
self
.
set_of_states
[
new_hash
]
=
complete_state
# Find the list of allowed TC based on the current state
...
...
@@ -273,9 +268,11 @@ class sdlHandler(QObject):
# Enable/disable the parameterless TC buttons accordingly
for
tc
,
button
in
self
.
buttons
.
viewitems
():
if
tc
in
self
.
proc
.
timers
:
# Ignore timers, they are handled differently
# Ignore timers, they are handled differently
, below
continue
button
.
setEnabled
(
tc
in
allowed_tc
)
if
tc_name
in
self
.
timers
:
self
.
buttons
[
name
].
setEnabled
(
False
)
# Emit the list of allowed TC for the GUI to update other buttons
self
.
allowed_messages
.
emit
(
allowed_tc
)
if
tc_name
:
...
...
@@ -304,52 +301,47 @@ class sdlHandler(QObject):
dock
.
show
()
return
dock
@
Slot
()
def
add_to_msc
(
self
,
direction
,
msg
):
''' Create an undo command and display message on the MSC diagram '''
self
.
msc
.
emit
(
direction
,
msg
,
self
.
undo_stack
)
@
Slot
()
def
send_tc
(
self
,
name
,
tc_func_ptr
,
param
=
None
):
''' Send a TC - Used either locally (parameterless TCs) or via
a signal sent by the B-mapper-generated backends '''
if
name
in
self
.
timers
:
self
.
buttons
[
name
].
setEnabled
(
False
)
self
.
msc
.
emit
(
'timeout'
,
name
)
el
se
:
self
.
add_to_msc
(
'timeout'
,
name
)
el
if
not
param
:
msg
=
'{tc}{arg}'
.
format
(
tc
=
name
,
arg
=
'({})'
.
format
(
param
.
GSER
())
if
param
else
''
)
self
.
msc
.
emit
(
'out'
,
msg
)
self
.
add_to_msc
(
'out'
,
msg
)
with
undo
.
UndoMacro
(
self
.
undo_stack
,
'Send TC'
):
undo_cmd
=
SendTC
(
self
,
tc_func_ptr
,
param
)
self
.
undo_stack
.
push
(
undo_cmd
)
self
.
check_state
()
# if param:
# # Cast the SWIG type (ASN.1 Native format) to a ctypes pointer
# try:
# swig_ptr = int(param._ptr)
# except TypeError:
# # when swig uses a proxy class, pointer is in _ptr.this
# swig_ptr = int(param._ptr.this)
# param_ptr = ctypes.cast(swig_ptr, ctypes.POINTER(ctypes.c_uint32))
# tc_func_ptr(param_ptr)
# else:
# tc_func_ptr()
# self.check_state()
# Update windows, highlight state, enable/disable buttons, etc.
self
.
on_event
(
tc_name
=
name
,
param
=
param
.
GSER
()
if
param
else
None
)
self
.
current_hash
=
self
.
on_event
(
tc_name
=
name
,
param
=
param
.
GSER
()
if
param
else
None
)
def
receive_tm
(
self
,
tm_name
):
''' Callback function when a paramless TM is received '''
self
.
msc
.
emit
(
'in'
,
tm_name
)
self
.
add_to_msc
(
'in'
,
tm_name
)
self
.
log_area
.
addItem
(
'Received event "{}"'
.
format
(
tm_name
))
def
set_timer
(
self
,
name
,
duration
):
''' Callback function when the SDL model sets a timer '''
self
.
msc
.
emit
(
'set'
,
'SET_{}
(
{}
)
'
.
format
(
name
,
duration
))
self
.
add_to_msc
(
'set'
,
'SET_{}
_
{}'
.
format
(
name
,
duration
))
self
.
log_area
.
addItem
(
'Received event "SET_{}({})"'
.
format
(
name
,
duration
))
self
.
buttons
[
name
].
setEnabled
(
True
)
def
reset_timer
(
self
,
name
):
''' Callback function when the SDL model resets a timer '''
self
.
msc
.
emit
(
'reset'
,
'RESET_{}'
.
format
(
name
))
self
.
add_to_msc
(
'reset'
,
'RESET_{}'
.
format
(
name
))
self
.
log_area
.
addItem
(
'Received event "RESET_{}"'
.
format
(
name
))
self
.
buttons
[
name
].
setEnabled
(
False
)
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment