浏览代码

Semi-working activity execution

Yentl Van Tendeloo 7 年之前
父节点
当前提交
954f934b99
共有 6 个文件被更改,包括 1251 次插入1093 次删除
  1. 3 50
      classes/modelverse/modelverse.xml
  2. 3 8
      classes/widgets/entry.xml
  3. 417 309
      classes/window/activity.xml
  4. 6 2
      classes/window/attribute_editor.xml
  5. 26 13
      classes/window/main_window.xml
  6. 796 711
      frontend.py

+ 3 - 50
classes/modelverse/modelverse.xml

@@ -665,7 +665,7 @@
                             </state>
                         </state>
 
-                        <state id="transformation_execute_AL" initial="send_operation">
+                        <state id="transformation_execute" initial="send_operation">
                             <state id="send_operation">
                                 <onentry>
                                     <raise event="request">
@@ -673,48 +673,7 @@
                                     </raise>
                                 </onentry>
 
-                                <transition cond="self.expect_response('Success: ready for AL execution')" target="../dialog">
-                                    <script>
-                                        self.input_context = str(uuid.uuid4())
-                                        self.inputs[self.input_context] = []
-                                    </script>
-
-                                    <raise event="result">
-                                        <parameter expr="self.input_context"/>
-                                    </raise>
-                                </transition>
-                            </state>
-
-                            <state id="dialog">
-                                <transition cond="self.expect_response('Success', pop=False) or self.expect_response('Failure', pop=False)" target="../../../../wait_for_action/history">
-                                    <raise event="result">
-                                        <parameter expr="True if self.responses.pop(0) == 'Success' else False"/>
-                                    </raise>
-                                </transition>
-
-                                <transition cond="not (self.expect_response('Success', pop=False) or self.expect_response('Failure', pop=False)) and self.expect_response_partial('', pop=False)" target=".">
-                                    <raise event="data_output">
-                                        <parameter expr="self.responses.pop(0)"/>
-                                    </raise>
-                                </transition>
-
-                                <transition cond="self.expect_input(self.input_context, 'data_input')" target=".">
-                                    <raise event="request">
-                                        <parameter expr="self.inputs[self.input_context].pop(0)['parameters']"/>
-                                    </raise>
-                                </transition>
-                            </state>
-                        </state>
-
-                        <state id="transformation_execute_MT" initial="send_operation">
-                            <state id="send_operation">
-                                <onentry>
-                                    <raise event="request">
-                                        <parameter expr="['transformation_execute', self.parameters[0]] + self.dict_to_list(self.parameters[1]) + self.dict_to_list(self.parameters[2])"/>
-                                    </raise>
-                                </onentry>
-
-                                <transition cond="self.expect_response('Success: ready for MT execution')" target="../dialog">
+                                <transition cond="self.expect_response_partial('Success: ready for ', pop=True)" target="../dialog">
                                     <script>
                                         self.input_context = str(uuid.uuid4())
                                         self.inputs[self.input_context] = []
@@ -1599,13 +1558,7 @@
                             </script>
                         </transition>
 
-                        <transition cond="self.expect_action(None, 'transformation_execute_MT')" target="../../operations/store_on_scripted/transformation_execute_MT">
-                            <script>
-                                self.load_action(None)
-                            </script>
-                        </transition>
-
-                        <transition cond="self.expect_action(None, 'transformation_execute_AL')" target="../../operations/store_on_scripted/transformation_execute_AL">
+                        <transition cond="self.expect_action(None, 'transformation_execute')" target="../../operations/store_on_scripted/transformation_execute">
                             <script>
                                 self.load_action(None)
                             </script>

+ 3 - 8
classes/widgets/entry.xml

@@ -51,15 +51,10 @@
                     </raise>
                 </transition>
 
-                <transition event="mark_committed" target=".">
+                <transition event="change_bg" target=".">
+                    <parameter name="colour"/>
                     <script>
-                        self.entry.configure(bg="lime green")
-                    </script>
-                </transition>
-
-                <transition event="mark_uncommitted" target=".">
-                    <script>
-                        self.entry.configure(bg="orange2")
+                        self.entry.configure(bg=colour, disabledbackground=colour)
                     </script>
                 </transition>
 

+ 417 - 309
classes/window/activity.xml

@@ -17,16 +17,21 @@
             self.activity_frame = tk.Frame(self)
             self.input_frame = tk.Frame(self)
             self.output_frame = tk.Frame(self)
+            self.exec_frame = tk.Frame(self)
 
             self.activity_frame.pack()
             tk.Label(self, text="Inputs").pack()
             self.input_frame.pack()
             tk.Label(self, text="Outputs").pack()
             self.output_frame.pack()
+            self.exec_frame.pack()
 
-            self.associations = {}
+            self.stored_associations = {}
             self.current = None
             self.activity = None
+
+            self.exec_input_signature = {}
+            self.exec_output_signature = {}
         </body>
     </constructor>
 
@@ -36,264 +41,106 @@
         </body>
     </destructor>
 
-    <scxml initial="create_activity_browse_label">
-        <state id="create_activity_browse_label" initial="create">
-            <state id="create">
-                <onentry>
-                    <raise event="create_instance" scope="cd">
-                        <parameter expr="'activity_browse'"/>
-                        <parameter expr="'Label'"/>
-                        <parameter expr="{'parent': self.activity_frame, 'text': 'Activity'}"/>
-                    </raise>
-                </onentry>
-
-                <transition event="instance_created" target="../pack">
-                    <parameter name="assoc_name"/>
-                    <raise event="start_instance" scope="cd">
-                        <parameter expr="assoc_name"/>
-                    </raise>
-                </transition>
-            </state>
-
-            <state id="pack">
-                <transition event="tk_widget" target="../../create_activity_browse_entry">
-                    <parameter name="tk_widget"/>
-                    <script>
-                        tk_widget.grid(row=0,column=0)
-                    </script>
-                </transition>
-            </state>
-        </state>
-
-        <state id="create_activity_browse_entry" initial="create">
-            <state id="create">
-                <onentry>
-                    <raise event="create_instance" scope="cd">
-                        <parameter expr="'activity_browse'"/>
-                        <parameter expr="'Entry'"/>
-                        <parameter expr="{'parent': self.activity_frame, 'name': 'activity_entry', 'value': '(none)', 'readonly': True}"/>
-                    </raise>
-                </onentry>
-
-                <transition event="instance_created" target="../pack">
-                    <parameter name="assoc_name"/>
-                    <raise event="start_instance" scope="cd">
-                        <parameter expr="assoc_name"/>
-                    </raise>
-                    <script>
-                        self.activity_entry = assoc_name
-                    </script>
-                </transition>
-            </state>
-
-            <state id="pack">
-                <transition event="tk_widget" target="../../create_activity_browse_button">
-                    <parameter name="tk_widget"/>
-                    <script>
-                        tk_widget.grid(row=0,column=1)
-                    </script>
-                </transition>
-            </state>
-        </state>
-
-        <state id="create_activity_browse_button" initial="create">
-            <state id="create">
-                <onentry>
-                    <raise event="create_instance" scope="cd">
-                        <parameter expr="'activity_browse'"/>
-                        <parameter expr="'Button'"/>
-                        <parameter expr="{'parent': self.activity_frame, 'event_parameters': 'browse_activity', 'visual': TextVisual('...'), 'tooltip_text': 'Browse for a activity'}"/>
-                    </raise>
-                </onentry>
-
-                <transition event="instance_created" target="../pack">
-                    <parameter name="assoc_name"/>
-                    <raise event="start_instance" scope="cd">
-                        <parameter expr="assoc_name"/>
-                    </raise>
-                </transition>
-            </state>
-
-            <state id="pack">
-                <transition event="tk_widget" target="../../ready">
-                    <parameter name="tk_widget"/>
-                    <script>
-                        tk_widget.grid(row=0,column=2)
-                    </script>
-                </transition>
-            </state>
-        </state>
-
-        <state id="ready">
-            <transition event="button_pressed" cond="event_name == 'browse_activity'" target="../browse_activity">
-                <parameter name="event_name"/>
-            </transition>
-            <transition event="button_pressed" cond="event_name.startswith('input_') or event_name.startswith('output_')" target="../browse_model">
-                <parameter name="event_name"/>
-                <script>
-                    self.current = event_name
-                    if event_name.startswith('input_'):
-                        self.required_type = self.input_signature[event_name.split("input_", 1)[1]]
-                    else:
-                        self.required_type = self.output_signature[event_name.split("output_", 1)[1]]
-                </script>
-            </transition>
-        </state>
-
-        <state id="browse_activity" initial="create_browser">
-            <state id="create_browser">
-                <onentry>
-                    <raise event="create_instance" scope="cd">
-                        <parameter expr="'browsers'"/>
-                        <parameter expr="'Browser'"/>
-                        <parameter expr="'Select activity to execute.'"/>
-                        <parameter expr="None"/>
-                    </raise>
-                </onentry>
-
-                <transition event="instance_created" target="../waiting_for_decision">
-                    <parameter name="assoc_name"/>
-                    <raise event="start_instance" scope="cd">
-                        <parameter expr="assoc_name"/>
-                    </raise>
-                </transition>
-            </state>
-
-            <state id="waiting_for_decision">
-                <transition event="browse_result" target=".">
-                    <parameter name="activity"/>
-                    <script>
-                        self.activity = activity
-                    </script>
-                    <raise event="change_value" target="self.activity_entry">
-                        <parameter expr="self.activity"/>
-                    </raise>
-                </transition>
-
-                <transition event="close_window" target="../../redraw_signature">
-                    <raise event="delete_instance" scope="cd">
-                        <parameter expr="'browsers'"/>
-                    </raise>
-                </transition>
-            </state>
-        </state>
-
-        <state id="redraw_signature" initial="clear_previous">
-            <state id="clear_previous">
-                <transition target="../read_signature">
-                    <raise event="delete_instance" scope="cd">
-                        <parameter expr="'model_browse_label'"/>
-                    </raise>
-                    <raise event="delete_instance" scope="cd">
-                        <parameter expr="'model_browse_button'"/>
-                    </raise>
-                </transition>
-            </state>
-
-            <state id="read_signature">
-                <onentry>
-                    <raise event="mv_request" scope="broad">
-                        <parameter expr="'transformation_signature'"/>
-                        <parameter expr="[self.activity]"/>
-                    </raise>
-                </onentry>
-
-                <transition event="mv_response" target="../add_input">
-                    <parameter name="result"/>
-                    <script>
-                        self.input_signature, self.output_signature = result
-                        self.input_signature_iter = dict(self.input_signature)
-                        self.output_signature_iter = dict(self.output_signature)
-                    </script>
-                </transition>
-            </state>
+    <scxml initial="all">
+        <state id="all" initial="create_activity_browse_label">
+            <state id="create_activity_browse_label" initial="create">
+                <state id="create">
+                    <onentry>
+                        <raise event="create_instance" scope="cd">
+                            <parameter expr="'activity_browse'"/>
+                            <parameter expr="'Label'"/>
+                            <parameter expr="{'parent': self.activity_frame, 'text': 'Activity'}"/>
+                        </raise>
+                    </onentry>
 
-            <state id="add_input" initial="check_next">
-                <onentry>
-                    <script>
-                        self.counter = -1
-                    </script>
-                </onentry>
+                    <transition event="instance_created" target="../pack">
+                        <parameter name="assoc_name"/>
+                        <raise event="start_instance" scope="cd">
+                            <parameter expr="assoc_name"/>
+                        </raise>
+                    </transition>
+                </state>
 
-                <state id="check_next">
-                    <transition cond="self.input_signature_iter" target="../create_label">
+                <state id="pack">
+                    <transition event="tk_widget" target="../../create_activity_browse_entry">
+                        <parameter name="tk_widget"/>
                         <script>
-                            self.counter += 1
-                            self.current = self.input_signature_iter.popitem()
+                            tk_widget.grid(row=0,column=0)
                         </script>
                     </transition>
-                    <transition cond="not self.input_signature_iter" target="../../add_output"/>
                 </state>
+            </state>
 
-                <state id="create_label">
+            <state id="create_activity_browse_entry" initial="create">
+                <state id="create">
                     <onentry>
                         <raise event="create_instance" scope="cd">
-                            <parameter expr="'model_browse_label'"/>
-                            <parameter expr="'Label'"/>
-                            <parameter expr="{'parent': self.input_frame, 'text': '%s : %s' % self.current}"/>
+                            <parameter expr="'activity_browse'"/>
+                            <parameter expr="'Entry'"/>
+                            <parameter expr="{'parent': self.activity_frame, 'name': 'activity_entry', 'value': '(none)', 'readonly': True}"/>
                         </raise>
                     </onentry>
 
-                    <transition event="instance_created" target="../pack_label">
+                    <transition event="instance_created" target="../pack">
                         <parameter name="assoc_name"/>
                         <raise event="start_instance" scope="cd">
                             <parameter expr="assoc_name"/>
                         </raise>
+                        <script>
+                            self.activity_entry = assoc_name
+                        </script>
                     </transition>
                 </state>
 
-                <state id="pack_label">
-                    <transition event="tk_widget" target="../create_entry">
+                <state id="pack">
+                    <transition event="tk_widget" target="../../create_activity_browse_button">
                         <parameter name="tk_widget"/>
                         <script>
-                            tk_widget.grid(row=self.counter,column=0)
-                            print("Adding input for " + str(self.current))
-                            print("At row " + str(self.counter))
+                            tk_widget.grid(row=0,column=1)
                         </script>
                     </transition>
                 </state>
+            </state>
 
-                <state id="create_entry">
+            <state id="create_activity_browse_button" initial="create">
+                <state id="create">
                     <onentry>
                         <raise event="create_instance" scope="cd">
-                            <parameter expr="'model_browse_entry'"/>
-                            <parameter expr="'Entry'"/>
-                            <parameter expr="{'parent': self.input_frame, 'name': 'input_%s' % self.current[0], 'value': '(none)', 'readonly': True}"/>
+                            <parameter expr="'activity_browse'"/>
+                            <parameter expr="'Button'"/>
+                            <parameter expr="{'parent': self.activity_frame, 'event_parameters': 'browse_activity', 'visual': TextVisual('...'), 'tooltip_text': 'Browse for a activity'}"/>
                         </raise>
                     </onentry>
 
-                    <transition event="instance_created" target="../pack_entry">
+                    <transition event="instance_created" target="../pack">
                         <parameter name="assoc_name"/>
                         <raise event="start_instance" scope="cd">
                             <parameter expr="assoc_name"/>
                         </raise>
-                        <script>
-                            self.associations["input_%s" % self.current[0]] = assoc_name
-                        </script>
                     </transition>
                 </state>
 
-                <state id="pack_entry">
-                    <transition event="tk_widget" target="../create_button">
+                <state id="pack">
+                    <transition event="tk_widget" target="../../create_exec">
                         <parameter name="tk_widget"/>
                         <script>
-                            tk_widget.grid(row=self.counter, column=1)
-                            print("Adding input for " + str(self.current))
-                            print("At row " + str(self.counter))
+                            tk_widget.grid(row=0,column=2)
                         </script>
                     </transition>
                 </state>
+            </state>
 
-                <state id="create_button">
+            <state id="create_exec" initial="create">
+                <state id="create">
                     <onentry>
                         <raise event="create_instance" scope="cd">
-                            <parameter expr="'model_browse_button'"/>
+                            <parameter expr="'activity_browse'"/>
                             <parameter expr="'Button'"/>
-                            <parameter expr="{'parent': self.input_frame, 'visual': TextVisual('...'), 'tooltip_text': 'Select input model for tag %s.' % self.current[0], 'event_parameters': 'input_%s' % self.current[0]}"/>
+                            <parameter expr="{'parent': self.exec_frame, 'event_parameters': 'execute', 'visual': TextVisual('EXECUTE'), 'tooltip_text': 'Execute the activity'}"/>
                         </raise>
                     </onentry>
 
-                    <transition event="instance_created" target="../pack_button">
+                    <transition event="instance_created" target="../pack">
                         <parameter name="assoc_name"/>
                         <raise event="start_instance" scope="cd">
                             <parameter expr="assoc_name"/>
@@ -301,102 +148,388 @@
                     </transition>
                 </state>
 
-                <state id="pack_button">
-                    <transition event="tk_widget" target="../check_next">
+                <state id="pack">
+                    <transition event="tk_widget" target="../../ready">
                         <parameter name="tk_widget"/>
                         <script>
-                            tk_widget.grid(row=self.counter, column=2)
+                            tk_widget.pack()
                         </script>
                     </transition>
                 </state>
             </state>
 
-            <state id="add_output" initial="check_next">
-                <onentry>
+            <state id="ready">
+                <transition event="button_pressed" cond="event_name == 'browse_activity'" target="../browse_activity">
+                    <parameter name="event_name"/>
+                </transition>
+                <transition event="button_pressed" cond="event_name.startswith('input_') or event_name.startswith('output_')" target="../browse_model">
+                    <parameter name="event_name"/>
                     <script>
-                        self.counter = -1
+                        self.current = event_name
+                        if event_name.startswith('input_'):
+                            self.required_type = [self.input_signature[event_name.split("input_", 1)[1]]]
+                        else:
+                            # We will overwrite the model anyway, so doesn't matter what it is!
+                            self.required_type = None
                     </script>
-                </onentry>
+                </transition>
+                <transition event="changed_entry" target=".">
+                    <parameter name="event_name"/>
+                    <parameter name="value"/>
+                    <script>
+                        if event_name.startswith('input_'):
+                            self.exec_input_signature[event_name.split("input_", 1)[1]] = value
+                        else:
+                            self.exec_output_signature[event_name.split("output_", 1)[1]] = value
+                    </script>
+                </transition>
+                <transition event="button_pressed" cond="event_name == 'execute'" target="../execute">
+                    <parameter name="event_name"/>
+                </transition>
+            </state>
 
-                <state id="check_next">
-                    <transition cond="self.output_signature_iter" target="../create_label">
+            <state id="execute" initial="check_args">
+                <state id="check_args">
+                    <onentry>
+                        <raise event="change_bg" scope="narrow" target="[self.stored_associations['input_%s' % i] for i in self.input_signature.keys()]">
+                            <parameter expr="'light grey'"/>
+                        </raise>
+                    </onentry>
+                    <transition cond="set(self.exec_input_signature.keys()) == set(self.input_signature.keys())" target="../execute">
+                        <raise event="change_bg" scope="narrow" target="'model_browse_entry'">
+                            <parameter expr="'light grey'"/>
+                        </raise>
+                        <script>
+                            print("Start execution")
+                        </script>
+                    </transition>
+                    <transition cond="set(self.exec_input_signature.keys()) != set(self.input_signature.keys())" target="../../ready">
                         <script>
-                            self.counter += 1
-                            self.current = self.output_signature_iter.popitem()
+                            actual = set(self.exec_input_signature.keys())
+                            formal = set(self.input_signature.keys())
+                            missing = formal - actual
+                            print("Missing input values for: " + str(missing))
                         </script>
+                        <raise event="change_bg" scope="narrow" target="[self.stored_associations['input_%s' % i] for i in missing]">
+                            <parameter expr="'red'"/>
+                        </raise>
                     </transition>
-                    <transition cond="not self.output_signature_iter" target="../../../ready"/>
                 </state>
 
-                <state id="create_label">
+                <state id="execute">
                     <onentry>
-                        <raise event="create_instance" scope="cd">
-                            <parameter expr="'model_browse_label'"/>
-                            <parameter expr="'Label'"/>
-                            <parameter expr="{'parent': self.output_frame, 'text': '%s : %s' % self.current}"/>
+                        <raise event="mv_request" scope="broad">
+                            <parameter expr="'transformation_execute'"/>
+                            <parameter expr="[self.activity, self.exec_input_signature, self.exec_output_signature]"/>
                         </raise>
                     </onentry>
 
-                    <transition event="instance_created" target="../pack_label">
-                        <parameter name="assoc_name"/>
-                        <raise event="start_instance" scope="cd">
-                            <parameter expr="assoc_name"/>
-                        </raise>
+                    <transition event="mv_response" target="../in_context">
+                        <parameter name="context"/>
+                        <script>
+                            self.current_context = context
+                        </script>
                     </transition>
                 </state>
 
-                <state id="pack_label">
-                    <transition event="tk_widget" target="../create_entry">
-                        <parameter name="tk_widget"/>
+                <state id="in_context">
+                    <!-- TODO Add data_input and data_output -->
+                    <transition event="mv_response" target="../../closing">
+                        <parameter name="result"/>
                         <script>
-                            tk_widget.grid(row=self.counter, column=0)
-                            print("Adding output for " + str(self.current))
-                            print("At row " + str(self.counter))
+                            print("Finished execution: " + str(result))
+                            #TODO if true: alter_context for output models
                         </script>
                     </transition>
                 </state>
+            </state>
 
-                <state id="create_entry">
+            <state id="browse_activity" initial="create_browser">
+                <state id="create_browser">
                     <onentry>
                         <raise event="create_instance" scope="cd">
-                            <parameter expr="'model_browse_entry'"/>
-                            <parameter expr="'Entry'"/>
-                            <parameter expr="{'parent': self.output_frame, 'name': 'output_%s' % self.current[0], 'value': '(none)', 'readonly': False}"/>
+                            <parameter expr="'browsers'"/>
+                            <parameter expr="'Browser'"/>
+                            <parameter expr="'Select activity to execute.'"/>
+                            <parameter expr="None"/>
                         </raise>
                     </onentry>
 
-                    <transition event="instance_created" target="../pack_entry">
+                    <transition event="instance_created" target="../waiting_for_decision">
                         <parameter name="assoc_name"/>
                         <raise event="start_instance" scope="cd">
                             <parameter expr="assoc_name"/>
                         </raise>
+                    </transition>
+                </state>
+
+                <state id="waiting_for_decision">
+                    <transition event="browse_result" target=".">
+                        <parameter name="activity"/>
                         <script>
-                            self.associations["output_%s" % self.current[0]] = assoc_name
+                            self.activity = activity
                         </script>
+                        <raise event="change_value" target="self.activity_entry">
+                            <parameter expr="self.activity"/>
+                        </raise>
+                    </transition>
+
+                    <transition event="close_window" target="../../redraw_signature">
+                        <raise event="delete_instance" scope="cd">
+                            <parameter expr="'browsers'"/>
+                        </raise>
                     </transition>
                 </state>
+            </state>
 
-                <state id="pack_entry">
-                    <transition event="tk_widget" target="../create_button">
-                        <parameter name="tk_widget"/>
+            <state id="redraw_signature" initial="clear_previous">
+                <state id="clear_previous">
+                    <transition target="../read_signature">
+                        <raise event="delete_instance" scope="cd">
+                            <parameter expr="'model_browse_label'"/>
+                        </raise>
+                        <raise event="delete_instance" scope="cd">
+                            <parameter expr="'model_browse_button'"/>
+                        </raise>
+                        <raise event="delete_instance" scope="cd">
+                            <parameter expr="'model_browse_entry'"/>
+                        </raise>
+                    </transition>
+                </state>
+
+                <state id="read_signature">
+                    <onentry>
+                        <raise event="mv_request" scope="broad">
+                            <parameter expr="'transformation_signature'"/>
+                            <parameter expr="[self.activity]"/>
+                        </raise>
+                    </onentry>
+
+                    <transition event="mv_response" target="../add_input">
+                        <parameter name="result"/>
                         <script>
-                            tk_widget.grid(row=self.counter, column=1)
-                            print("Adding output for " + str(self.current))
-                            print("At row " + str(self.counter))
+                            self.input_signature, self.output_signature = result
+                            self.input_signature_iter = dict(self.input_signature)
+                            self.output_signature_iter = dict(self.output_signature)
                         </script>
                     </transition>
                 </state>
 
-                <state id="create_button">
+                <state id="add_input" initial="check_next">
+                    <onentry>
+                        <script>
+                            self.counter = -1
+                        </script>
+                    </onentry>
+
+                    <state id="check_next">
+                        <transition cond="self.input_signature_iter" target="../create_label">
+                            <script>
+                                self.counter += 1
+                                self.current = self.input_signature_iter.popitem()
+                            </script>
+                        </transition>
+                        <transition cond="not self.input_signature_iter" target="../../add_output"/>
+                    </state>
+
+                    <state id="create_label">
+                        <onentry>
+                            <raise event="create_instance" scope="cd">
+                                <parameter expr="'model_browse_label'"/>
+                                <parameter expr="'Label'"/>
+                                <parameter expr="{'parent': self.input_frame, 'text': '%s : %s' % self.current}"/>
+                            </raise>
+                        </onentry>
+
+                        <transition event="instance_created" target="../pack_label">
+                            <parameter name="assoc_name"/>
+                            <raise event="start_instance" scope="cd">
+                                <parameter expr="assoc_name"/>
+                            </raise>
+                        </transition>
+                    </state>
+
+                    <state id="pack_label">
+                        <transition event="tk_widget" target="../create_entry">
+                            <parameter name="tk_widget"/>
+                            <script>
+                                tk_widget.grid(row=self.counter,column=0)
+                                print("Adding input for " + str(self.current))
+                                print("At row " + str(self.counter))
+                            </script>
+                        </transition>
+                    </state>
+
+                    <state id="create_entry">
+                        <onentry>
+                            <raise event="create_instance" scope="cd">
+                                <parameter expr="'model_browse_entry'"/>
+                                <parameter expr="'Entry'"/>
+                                <parameter expr="{'parent': self.input_frame, 'name': 'input_%s' % self.current[0], 'value': '', 'readonly': True}"/>
+                            </raise>
+                        </onentry>
+
+                        <transition event="instance_created" target="../pack_entry">
+                            <parameter name="assoc_name"/>
+                            <raise event="start_instance" scope="cd">
+                                <parameter expr="assoc_name"/>
+                            </raise>
+                            <script>
+                                self.stored_associations["input_%s" % self.current[0]] = assoc_name
+                            </script>
+                        </transition>
+                    </state>
+
+                    <state id="pack_entry">
+                        <transition event="tk_widget" target="../create_button">
+                            <parameter name="tk_widget"/>
+                            <script>
+                                tk_widget.grid(row=self.counter, column=1)
+                                print("Adding input for " + str(self.current))
+                                print("At row " + str(self.counter))
+                            </script>
+                        </transition>
+                    </state>
+
+                    <state id="create_button">
+                        <onentry>
+                            <raise event="create_instance" scope="cd">
+                                <parameter expr="'model_browse_button'"/>
+                                <parameter expr="'Button'"/>
+                                <parameter expr="{'parent': self.input_frame, 'visual': TextVisual('...'), 'tooltip_text': 'Select input model for tag %s.' % self.current[0], 'event_parameters': 'input_%s' % self.current[0]}"/>
+                            </raise>
+                        </onentry>
+
+                        <transition event="instance_created" target="../pack_button">
+                            <parameter name="assoc_name"/>
+                            <raise event="start_instance" scope="cd">
+                                <parameter expr="assoc_name"/>
+                            </raise>
+                        </transition>
+                    </state>
+
+                    <state id="pack_button">
+                        <transition event="tk_widget" target="../check_next">
+                            <parameter name="tk_widget"/>
+                            <script>
+                                tk_widget.grid(row=self.counter, column=2)
+                            </script>
+                        </transition>
+                    </state>
+                </state>
+
+                <state id="add_output" initial="check_next">
+                    <onentry>
+                        <script>
+                            self.counter = -1
+                        </script>
+                    </onentry>
+
+                    <state id="check_next">
+                        <transition cond="self.output_signature_iter" target="../create_label">
+                            <script>
+                                self.counter += 1
+                                self.current = self.output_signature_iter.popitem()
+                            </script>
+                        </transition>
+                        <transition cond="not self.output_signature_iter" target="../../../ready"/>
+                    </state>
+
+                    <state id="create_label">
+                        <onentry>
+                            <raise event="create_instance" scope="cd">
+                                <parameter expr="'model_browse_label'"/>
+                                <parameter expr="'Label'"/>
+                                <parameter expr="{'parent': self.output_frame, 'text': '%s : %s' % self.current}"/>
+                            </raise>
+                        </onentry>
+
+                        <transition event="instance_created" target="../pack_label">
+                            <parameter name="assoc_name"/>
+                            <raise event="start_instance" scope="cd">
+                                <parameter expr="assoc_name"/>
+                            </raise>
+                        </transition>
+                    </state>
+
+                    <state id="pack_label">
+                        <transition event="tk_widget" target="../create_entry">
+                            <parameter name="tk_widget"/>
+                            <script>
+                                tk_widget.grid(row=self.counter, column=0)
+                            </script>
+                        </transition>
+                    </state>
+
+                    <state id="create_entry">
+                        <onentry>
+                            <raise event="create_instance" scope="cd">
+                                <parameter expr="'model_browse_entry'"/>
+                                <parameter expr="'Entry'"/>
+                                <parameter expr="{'parent': self.output_frame, 'name': 'output_%s' % self.current[0], 'value': '', 'readonly': False}"/>
+                            </raise>
+                        </onentry>
+
+                        <transition event="instance_created" target="../pack_entry">
+                            <parameter name="assoc_name"/>
+                            <raise event="start_instance" scope="cd">
+                                <parameter expr="assoc_name"/>
+                            </raise>
+                            <script>
+                                self.stored_associations["output_%s" % self.current[0]] = assoc_name
+                            </script>
+                        </transition>
+                    </state>
+
+                    <state id="pack_entry">
+                        <transition event="tk_widget" target="../create_button">
+                            <parameter name="tk_widget"/>
+                            <script>
+                                tk_widget.grid(row=self.counter, column=1)
+                            </script>
+                        </transition>
+                    </state>
+
+                    <state id="create_button">
+                        <onentry>
+                            <raise event="create_instance" scope="cd">
+                                <parameter expr="'model_browse_button'"/>
+                                <parameter expr="'Button'"/>
+                                <parameter expr="{'parent': self.output_frame, 'visual': TextVisual('...'), 'tooltip_text': 'Select output model for tag %s.' % self.current[0], 'event_parameters': 'output_%s' % self.current[0]}"/>
+                            </raise>
+                        </onentry>
+
+                        <transition event="instance_created" target="../pack_button">
+                            <parameter name="assoc_name"/>
+                            <raise event="start_instance" scope="cd">
+                                <parameter expr="assoc_name"/>
+                            </raise>
+                        </transition>
+                    </state>
+
+                    <state id="pack_button">
+                        <transition event="tk_widget" target="../check_next">
+                            <parameter name="tk_widget"/>
+                            <script>
+                                tk_widget.grid(row=self.counter, column=2)
+                            </script>
+                        </transition>
+                    </state>
+                </state>
+            </state>
+
+            <state id="browse_model" initial="create_browser">
+                <state id="create_browser">
                     <onentry>
                         <raise event="create_instance" scope="cd">
-                            <parameter expr="'model_browse_button'"/>
-                            <parameter expr="'Button'"/>
-                            <parameter expr="{'parent': self.output_frame, 'visual': TextVisual('...'), 'tooltip_text': 'Select output model for tag %s.' % self.current[0], 'event_parameters': 'output_%s' % self.current[0]}"/>
+                            <parameter expr="'browsers'"/>
+                            <parameter expr="'Browser'"/>
+                            <parameter expr="'Select model to use.'"/>
+                            <parameter expr="self.required_type"/>
                         </raise>
                     </onentry>
 
-                    <transition event="instance_created" target="../pack_button">
+                    <transition event="instance_created" target="../waiting_for_decision">
                         <parameter name="assoc_name"/>
                         <raise event="start_instance" scope="cd">
                             <parameter expr="assoc_name"/>
@@ -404,73 +537,48 @@
                     </transition>
                 </state>
 
-                <state id="pack_button">
-                    <transition event="tk_widget" target="../check_next">
-                        <parameter name="tk_widget"/>
-                        <script>
-                            tk_widget.grid(row=self.counter, column=2)
-                        </script>
+                <state id="waiting_for_decision">
+                    <transition event="browse_result" target=".">
+                        <parameter name="model"/>
+                        <raise event="change_value" scope="narrow" target="self.stored_associations[self.current]">
+                            <parameter expr="model"/>
+                        </raise>
+                    </transition>
+
+                    <transition event="close_window" target="../../ready">
+                        <raise event="delete_instance" scope="cd">
+                            <parameter expr="'browsers'"/>
+                        </raise>
                     </transition>
                 </state>
             </state>
-        </state>
 
-        <state id="browse_model" initial="create_browser">
-            <state id="create_browser">
-                <onentry>
-                    <raise event="create_instance" scope="cd">
-                        <parameter expr="'browsers'"/>
-                        <parameter expr="'Browser'"/>
-                        <parameter expr="'Select model to use.'"/>
-                        <parameter expr="[self.required_type]"/>
+            <state id="closing">
+                <transition target="../closed">
+                    <raise event="delete_instance" scope="cd">
+                        <parameter expr="'model_browse_button'"/>
                     </raise>
-                </onentry>
-
-                <transition event="instance_created" target="../waiting_for_decision">
-                    <parameter name="assoc_name"/>
-                    <raise event="start_instance" scope="cd">
-                        <parameter expr="assoc_name"/>
+                    <raise event="delete_instance" scope="cd">
+                        <parameter expr="'activity_browse'"/>
                     </raise>
-                </transition>
-            </state>
-
-            <state id="waiting_for_decision">
-                <transition event="browse_result" target=".">
-                    <parameter name="model"/>
-                    <raise event="change_value" scope="narrow" target="self.associations[self.current]">
-                        <parameter expr="model"/>
+                    <raise event="delete_instance" scope="cd">
+                        <parameter expr="'model_browse_entry'"/>
                     </raise>
-                </transition>
-
-                <transition event="close_window" target="../../ready">
                     <raise event="delete_instance" scope="cd">
-                        <parameter expr="'browsers'"/>
+                        <parameter expr="'model_browse_label'"/>
                     </raise>
                 </transition>
             </state>
-        </state>
 
-        <state id="closing">
-            <transition target="../closed">
-                <raise event="delete_instance" scope="cd">
-                    <parameter expr="'model_browse_label'"/>
-                </raise>
-                <raise event="delete_instance" scope="cd">
-                    <parameter expr="'model_browse_button'"/>
-                </raise>
-                <raise event="delete_instance" scope="cd">
-                    <parameter expr="'model_browse_entry'"/>
-                </raise>
-                <raise event="delete_instance" scope="cd">
-                    <parameter expr="'activity_browse'"/>
-                </raise>
-            </transition>
-        </state>
+            <state id="closed">
+                <onentry>
+                    <raise event="window_close" scope="narrow" target="'parent'"/>
+                </onentry>
+            </state>
 
-        <state id="closed">
-            <onentry>
-                <raise event="window_close" scope="narrow" target="'parent'"/>
-            </onentry>
+            <transition event="window-close" cond="id(self) == ID" target="closing">
+                <parameter name="ID"/>
+            </transition>
         </state>
     </scxml>
 </class>

+ 6 - 2
classes/window/attribute_editor.xml

@@ -335,7 +335,9 @@
 
             <state id="change_name" initial="waiting">
                 <onentry>
-                    <raise event="mark_uncommitted" scope="narrow" target="self.associations_name[self.parameter[0]]"/>
+                    <raise event="change_bg" scope="narrow" target="self.associations_name[self.parameter[0]]">
+                        <parameter expr="orange2"/>
+                    </raise>
                 </onentry>
 
                 <state id="waiting">
@@ -373,7 +375,9 @@
                         <raise event="change_event_name" scope="narrow" target="self.associations_type[self.parameter[0]]">
                             <parameter expr="self.parameter[1]"/>
                         </raise>
-                        <raise event="mark_committed" scope="narrow" target="self.associations_name[self.parameter[0]]"/>
+                        <raise event="change_bg" scope="narrow" target="self.associations_name[self.parameter[0]]">
+                            <parameter expr="'lime green'"/>
+                        </raise>
                         <raise event="change_triggers" scope="narrow" target="self.associations_optional[self.parameter[0]]">
                             <parameter expr="'optional_%s' % self.parameter[1]"/>
                             <parameter expr="'mandatory_%s' % self.parameter[1]"/>

+ 26 - 13
classes/window/main_window.xml

@@ -194,20 +194,33 @@
                         </state>
                     </state>
 
-                    <state id="execute_activity">
-                        <onentry>
-                            <raise event="create_instance" scope="cd">
-                                <parameter expr="'subwindow'"/>
-                                <parameter expr="'ActivityExecutor'"/>
-                            </raise>
-                        </onentry>
+                    <state id="execute_activity" initial="open_window">
+                        <state id="open_window">
+                            <onentry>
+                                <raise event="create_instance" scope="cd">
+                                    <parameter expr="'subwindow'"/>
+                                    <parameter expr="'ActivityExecutor'"/>
+                                </raise>
+                            </onentry>
 
-                        <transition event="instance_created" target="../idle">
-                            <parameter name="assoc_name"/>
-                            <raise event="start_instance" scope="cd">
-                                <parameter expr="assoc_name"/>
-                            </raise>
-                        </transition>
+                            <transition event="instance_created" target="../waiting">
+                                <parameter name="assoc_name"/>
+                                <raise event="start_instance" scope="cd">
+                                    <parameter expr="assoc_name"/>
+                                </raise>
+                                <script>
+                                    self.activity_executor = assoc_name
+                                </script>
+                            </transition>
+                        </state>
+
+                        <state id="waiting">
+                            <transition event="window_close" target="../../idle">
+                                <raise event="delete_instance" scope="cd">
+                                    <parameter expr="self.activity_executor"/>
+                                </raise>
+                            </transition>
+                        </state>
                     </state>
 
                     <state id="add_object_diagrams" initial="init">

文件差异内容过多而无法显示
+ 796 - 711
frontend.py