Skip to content

Commit

Permalink
Python script editor should provide a workspace ID when updating model (
Browse files Browse the repository at this point in the history
#9988)

* Python node should provide a workspace ID when calling UpdateModelValueCommand, fixing #9479

* Draft test for #9479 (not passing yet due to undo issues)

* Disable section of python custom node save test that uses undo

* Remove file added by accident

* Fix null dereference in UpdateModelValueImpl
  • Loading branch information
mike-d-adsk authored and mjkkirschner committed Nov 20, 2019
1 parent c32d4b5 commit e775794
Show file tree
Hide file tree
Showing 6 changed files with 403 additions and 11 deletions.
7 changes: 5 additions & 2 deletions src/DynamoCore/Models/DynamoModelCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -565,8 +565,11 @@ private void UpdateModelValueImpl(UpdateModelValueCommand command)
if (!command.WorkspaceGuid.Equals(Guid.Empty))
targetWorkspace = Workspaces.FirstOrDefault(w => w.Guid.Equals(command.WorkspaceGuid));

targetWorkspace.UpdateModelValue(command.ModelGuids,
command.Name, command.Value);
if (targetWorkspace != null)
{
targetWorkspace.UpdateModelValue(command.ModelGuids,
command.Name, command.Value);
}
}

private void ConvertNodesToCodeImpl(ConvertNodesToCodeCommand command)
Expand Down
17 changes: 10 additions & 7 deletions src/Libraries/PythonNodeModelsWpf/PythonNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,27 @@
using PythonNodeModels;
using System;
using System.Windows;
using Dynamo.Graph.Workspaces;

namespace PythonNodeModelsWpf
{
public class PythonNodeViewCustomization : VariableInputNodeViewCustomization, INodeViewCustomization<PythonNode>
{
private DynamoViewModel dynamoViewModel;
private PythonNode model;
private NodeView view;
private PythonNode pythonNodeModel;
private NodeView pythonNodeView;
private WorkspaceModel workspaceModel;
private ScriptEditorWindow editWindow;
private ModelessChildWindow.WindowRect editorWindowRect;

public void CustomizeView(PythonNode nodeModel, NodeView nodeView)
{
base.CustomizeView(nodeModel, nodeView);

model = nodeModel;
view = nodeView;
pythonNodeModel = nodeModel;
pythonNodeView = nodeView;
dynamoViewModel = nodeView.ViewModel.DynamoViewModel;
workspaceModel = nodeView.ViewModel.WorkspaceViewModel.Model;

var editWindowItem = new MenuItem { Header = PythonNodeModels.Properties.Resources.EditHeader, IsCheckable = false };
nodeView.MainContextMenu.Items.Add(editWindowItem);
Expand All @@ -53,7 +56,7 @@ private void NodeModel_DeletionStarted(object sender, System.ComponentModel.Canc
var res = MessageBox.Show(
String.Format(
PythonNodeModels.Properties.Resources.DeletingPythonNodeWithOpenEditorMessage,
this.model.Name),
this.pythonNodeModel.Name),
PythonNodeModels.Properties.Resources.DeletingPythonNodeWithOpenEditorTitle,
MessageBoxButton.OKCancel,
MessageBoxImage.Question);
Expand Down Expand Up @@ -89,8 +92,8 @@ private void EditScriptContent()
}
else
{
editWindow = new ScriptEditorWindow(dynamoViewModel, model, view, ref editorWindowRect);
editWindow.Initialize(model.GUID, "ScriptContent", model.Script);
editWindow = new ScriptEditorWindow(dynamoViewModel, pythonNodeModel, pythonNodeView, ref editorWindowRect);
editWindow.Initialize(workspaceModel.Guid, pythonNodeModel.GUID, "ScriptContent", pythonNodeModel.Script);
editWindow.Closed += editWindow_Closed;
editWindow.Show();
}
Expand Down
6 changes: 4 additions & 2 deletions src/Libraries/PythonNodeModelsWpf/ScriptEditorWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public partial class ScriptEditorWindow : ModelessChildWindow
{
private string propertyName = string.Empty;
private Guid boundNodeId = Guid.Empty;
private Guid boundWorkspaceId = Guid.Empty;
private CompletionWindow completionWindow = null;
private readonly IronPythonCompletionProvider completionProvider;
private readonly DynamoViewModel dynamoViewModel;
Expand All @@ -47,8 +48,9 @@ ref ModelessChildWindow.WindowRect windowRect
Dynamo.Logging.Analytics.TrackScreenView("Python");
}

internal void Initialize(Guid nodeGuid, string propName, string propValue)
internal void Initialize(Guid workspaceGuid, Guid nodeGuid, string propName, string propValue)
{
boundWorkspaceId = workspaceGuid;
boundNodeId = nodeGuid;
propertyName = propName;

Expand Down Expand Up @@ -143,7 +145,7 @@ private void OnRevertClicked(object sender, RoutedEventArgs e)
private void UpdateScript(string scriptText)
{
var command = new DynamoModel.UpdateModelValueCommand(
System.Guid.Empty, boundNodeId, propertyName, scriptText);
boundWorkspaceId, boundNodeId, propertyName, scriptText);

dynamoViewModel.ExecuteCommand(command);
this.Focus();
Expand Down
48 changes: 48 additions & 0 deletions test/Libraries/DynamoPythonTests/PythonEditTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Dynamo.Graph.Nodes;
using NUnit.Framework;
using PythonNodeModels;
using Dynamo.Graph.Nodes.CustomNodes;
using DynCmd = Dynamo.Models.DynamoModel;

namespace Dynamo.Tests
Expand Down Expand Up @@ -41,6 +42,53 @@ public void PythonScriptEdit_WorkspaceChangesReflected()
Assert.IsTrue(model.CurrentWorkspace.HasUnsavedChanges);
}

[Test]
public void PythonScriptEdit_CustomNode()
{
// open file
var model = ViewModel.Model;
var examplePath = Path.Combine(TestDirectory, @"core\python", "PythonCustomNodeHomeWorkspace.dyn");
ViewModel.OpenCommand.Execute(examplePath);
var homeWorkspace = model.CurrentWorkspace;

// open custom node
var customNodeModel = homeWorkspace.NodeFromWorkspace("83c2b47d81e14226a93941f1e47dc47d") as Function;
ViewModel.GoToWorkspaceCommand.Execute(customNodeModel.Definition.FunctionId);
var customNodeWorkspace = model.CurrentWorkspace;

// get the python node
var nodeModel = customNodeWorkspace.NodeFromWorkspace("439c4e7bd4ed45f49d5786209c2ec403");
var pynode = nodeModel as PythonNode;
Assert.NotNull(pynode);

// make changes to python script
UpdatePythonNodeContent(pynode, @"OUT = IN[0] * 2");

// custom node workspace should have changes, home workspace should not
Assert.IsTrue(customNodeWorkspace.HasUnsavedChanges);
Assert.IsFalse(homeWorkspace.HasUnsavedChanges);

/* TODO: uncomment this section after undo issues are resolved
// undo change
ViewModel.UndoCommand.Execute(null);
// custom node workspace should not have changes, and neither should home
Assert.IsFalse(customNodeWorkspace.HasUnsavedChanges);
Assert.IsFalse(homeWorkspace.HasUnsavedChanges);
// make home workspace current
ViewModel.HomeCommand.Execute(null);
// make changes to python script
UpdatePythonNodeContent(pynode, @"OUT = IN[0] * 2");
// custom node workspace should have changes, home workspace should not
Assert.IsTrue(customNodeWorkspace.HasUnsavedChanges);
Assert.IsFalse(homeWorkspace.HasUnsavedChanges);
*/
}


[Test]
public void PythonScriptEdit_UndoRedo()
{
Expand Down
171 changes: 171 additions & 0 deletions test/core/python/PythonCustomNodeHomeWorkspace.dyn
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
{
"Uuid": "c858978f-0411-4a88-a690-160622d6d562",
"IsCustomNode": false,
"Description": null,
"Name": "python custom node test home workspace",
"ElementResolver": {
"ResolutionMap": {}
},
"Inputs": [],
"Outputs": [],
"Nodes": [
{
"ConcreteType": "CoreNodeModels.Input.DoubleSlider, CoreNodeModels",
"NodeType": "NumberInputNode",
"NumberType": "Double",
"MaximumValue": 100.0,
"MinimumValue": 0.0,
"StepValue": 0.1,
"InputValue": 89.300000000000011,
"Id": "7122f1ba29ac4efabf075856fdd4dbfa",
"Inputs": [],
"Outputs": [
{
"Id": "baa777f60cc548398ad31dc92cc6e0c8",
"Name": "",
"Description": "Double",
"UsingDefaultValue": false,
"Level": 2,
"UseLevels": false,
"KeepListStructure": false
}
],
"Replication": "Disabled",
"Description": "A slider that produces numeric values."
},
{
"ConcreteType": "CoreNodeModels.Watch, CoreNodeModels",
"NodeType": "ExtensionNode",
"Id": "9a9fb65f6d8943f289168911c0de4e36",
"Inputs": [
{
"Id": "624a10003c78444f9bd526194c0a1eee",
"Name": "",
"Description": "Node to evaluate.",
"UsingDefaultValue": false,
"Level": 2,
"UseLevels": false,
"KeepListStructure": false
}
],
"Outputs": [
{
"Id": "a625b42d31814b3889d1b2618097bf06",
"Name": "",
"Description": "Watch contents.",
"UsingDefaultValue": false,
"Level": 2,
"UseLevels": false,
"KeepListStructure": false
}
],
"Replication": "Disabled",
"Description": "Visualize the output of node."
},
{
"ConcreteType": "Dynamo.Graph.Nodes.CustomNodes.Function, DynamoCore",
"FunctionSignature": "ad7f8950-a02c-4dae-872e-3754d8c354f3",
"FunctionType": "Graph",
"NodeType": "FunctionNode",
"Id": "83c2b47d81e14226a93941f1e47dc47d",
"Inputs": [
{
"Id": "0a3849e12a7b4d8d962a6683335bc62e",
"Name": "IN",
"Description": "var[]..[]",
"UsingDefaultValue": false,
"Level": 2,
"UseLevels": false,
"KeepListStructure": false
}
],
"Outputs": [
{
"Id": "2d15ee12629f4dcd8ff2f8587b314d45",
"Name": "OUT",
"Description": "return value",
"UsingDefaultValue": false,
"Level": 2,
"UseLevels": false,
"KeepListStructure": false
}
],
"Replication": "Auto",
"Description": "test python in a custom node"
}
],
"Connectors": [
{
"Start": "baa777f60cc548398ad31dc92cc6e0c8",
"End": "0a3849e12a7b4d8d962a6683335bc62e",
"Id": "f738ce18436b4b08a59e0993db2f5aa9"
},
{
"Start": "2d15ee12629f4dcd8ff2f8587b314d45",
"End": "624a10003c78444f9bd526194c0a1eee",
"Id": "64d359be969340f9a625c84f6945f6e1"
}
],
"Dependencies": [
"ad7f8950-a02c-4dae-872e-3754d8c354f3"
],
"Bindings": [],
"View": {
"Dynamo": {
"ScaleFactor": 1.0,
"HasRunWithoutCrash": true,
"IsVisibleInDynamoLibrary": true,
"Version": "2.3.0.6256",
"RunType": "Automatic",
"RunPeriod": "1000"
},
"Camera": {
"Name": "Background Preview",
"EyeX": -17.0,
"EyeY": 24.0,
"EyeZ": 50.0,
"LookX": 12.0,
"LookY": -13.0,
"LookZ": -58.0,
"UpX": 0.0,
"UpY": 1.0,
"UpZ": 0.0
},
"NodeViews": [
{
"ShowGeometry": true,
"Name": "Number Slider",
"Id": "7122f1ba29ac4efabf075856fdd4dbfa",
"IsSetAsInput": false,
"IsSetAsOutput": false,
"Excluded": false,
"X": 329.99999999999977,
"Y": 389.6
},
{
"ShowGeometry": true,
"Name": "Watch",
"Id": "9a9fb65f6d8943f289168911c0de4e36",
"IsSetAsInput": false,
"IsSetAsOutput": false,
"Excluded": false,
"X": 1064.4,
"Y": 392.79999999999995
},
{
"ShowGeometry": true,
"Name": "PythonCustomNodeTest",
"Id": "83c2b47d81e14226a93941f1e47dc47d",
"IsSetAsInput": false,
"IsSetAsOutput": false,
"Excluded": false,
"X": 766.8,
"Y": 404.79999999999995
}
],
"Annotations": [],
"X": 0.0,
"Y": 0.0,
"Zoom": 1.0
}
}
Loading

0 comments on commit e775794

Please sign in to comment.