Commit 038e2778 authored by Maxime Perrotin's avatar Maxime Perrotin

Improve copy/rename of states with nesting content

When a state is copy-pasted, and then renamed, the tool now checks if
the copied state was nested. If so it makes a deep copy of the nested
state at the time when it is renamed. This way the nested content is not
lost and does not refer to the same nested state.
parent 42c0c4bc
......@@ -170,6 +170,11 @@ def paste_floating_objects(scene):
procedures = (i for i in item_list if isinstance(i, ogAST.Procedure))
processes = (i for i in item_list if isinstance(i, ogAST.Process))
for state in states:
# nesting is not copied, because the nested content is a scene
# that is just referenced.. content must be actually copied
# to a new scene only if a state is renamed (this will preserve
# the nesting content of the original state)
# First check if state has already been pasted
new_item = Renderer.render(state, scene=CLIPBOARD,
......@@ -5148,7 +5148,7 @@ def parseSingleElement(elem='', string='', context=None):
'terminator_statement', 'label', 'task', 'procedure_call', 'end',
'text_area', 'state', 'start', 'procedure', 'floating_label',
'connect_part', 'process_definition', 'proc_start', 'state_start',
'signalroute', 'stop_if', 'continuous_signal'))
'signalroute', 'stop_if', 'continuous_signal', 'composite_state'))
# Create a dummy context, needed to place context data
if elem == 'proc_start':
elem = 'start'
......@@ -21,6 +21,9 @@ import logging
from PySide.QtGui import QUndoCommand
from PySide.QtCore import QPropertyAnimation, QEasingCurve, QAbstractAnimation
import Pr
import ogParser
LOG = logging.getLogger(__name__)
......@@ -49,13 +52,71 @@ class ReplaceText(QUndoCommand):
self.text = text_id
self.old_text = old_text
self.new_text = new_text
self.scene = self.text.parent.scene()
self.count_instances_old, self.count_instances_new = 1, -1
for each in self.scene.states:
# count the number of instances of the states in the scene
# the text is already renamed, values are initialized to -1 and 1
state_name = unicode(each).lower()
if self.old_text.lower() == state_name:
self.count_instances_old += 1
if self.new_text.lower() == state_name:
self.count_instances_new += 1
def undo(self):
if self.text.parent in self.scene.states:
# Rename the nested state if relevant
self.scene.composite_states[self.old_text.lower()] = \
except KeyError as err:
def redo(self):
if self.text.parent in self.scene.states:
# renaming a state in case of a nested state:
# 1) if renamed state already exists, do nothing special
# 2) if renamed state is a new state:
# a. if this was the only instance of the state, just rename
# the list of composite state to reflect the new state name
# b. otherwise, parse the composite state, create a new scene
# and render the same content in the new scene, then
# update the list of composite states with the new copy
if self.count_instances_new != 0:
# case 1: do nothing, state is already initialized
if self.count_instances_old == 1:
# case 2a. rename the list of composite states
self.scene.composite_states[self.new_text.lower()] = \
except KeyError:
# case 2b: create a new scene and really copy the state
state = self.text.parent
if state.is_composite():
# Parse the scene of the nested state:
sub_state = u'\n'.join(Pr.generate(state,
if sub_state:
new_scene = self.scene.create_subscene(
# get the AST of type ogAST.CompositeState
ast, _, _, _, _ = ogParser.parseSingleElement(
# render the composite state content
self.new_text.lower()] = new_scene
class ResizeSymbol(QUndoCommand):
''' Undo/Redo command for resizing a symbol '''
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment