Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DYN-3844 Open Dynamo Template as new workspace #14871

Merged
merged 15 commits into from
Jan 27, 2024
5 changes: 5 additions & 0 deletions src/DynamoCore/Configuration/IPathResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,11 @@ public interface IPathManager
/// </summary>
string SamplesDirectory { get; }

/// <summary>
/// The root directory where all template files are stored
/// </summary>
string TemplatesDirectory { get; }

/// <summary>
/// The directory where the automatically saved files will be stored.
/// </summary>
Expand Down
57 changes: 56 additions & 1 deletion src/DynamoCore/Configuration/PathManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ internal static Lazy<PathManager>
public const string ViewExtensionsDirectoryName = "viewExtensions";
public const string DefinitionsDirectoryName = "definitions";
public const string SamplesDirectoryName = "samples";
public const string TemplateDirectoryName = "templates";
public const string BackupDirectoryName = "backup";
public const string PreferenceSettingsFileName = "DynamoSettings.xml";
public const string PythonTemplateFileName = "PythonTemplate.py";
Expand All @@ -82,6 +83,7 @@ internal static Lazy<PathManager>
private string commonPackages;
private string logDirectory;
private string samplesDirectory;
private string templatesDirectory;
private string backupDirectory;
private string defaultBackupDirectory;
private string preferenceFilePath;
Expand Down Expand Up @@ -240,6 +242,14 @@ public string SamplesDirectory
get { return samplesDirectory; }
}

/// <summary>
/// Dynamo Templates folder
/// </summary>
public string TemplatesDirectory
{
get { return templatesDirectory; }
}

public string BackupDirectory
{
get { return backupDirectory; }
Expand Down Expand Up @@ -572,6 +582,7 @@ private void BuildCommonDirectories()
commonDefinitions = Path.Combine(commonDataDir, DefinitionsDirectoryName);
commonPackages = Path.Combine(commonDataDir, PackagesDirectoryName);
samplesDirectory = GetSamplesFolder(commonDataDir);
templatesDirectory = GetTemplateFolder(commonDataDir);

rootDirectories = new List<string> { userDataDir };

Expand Down Expand Up @@ -715,7 +726,51 @@ private static string GetSamplesFolder(string dataRootDirectory)

return sampleDirectory;
}


/// <summary>
/// Get template folder path from common data directory
/// </summary>
/// <param name="dataRootDirectory"></param>
/// <returns></returns>
private string GetTemplateFolder(string dataRootDirectory)
{
var versionedDirectory = dataRootDirectory;
if (!Directory.Exists(versionedDirectory))
{
// Try to see if folder "%ProgramData%\{...}\{major}.{minor}" exists, if it
// does not, then root directory would be "%ProgramData%\{...}".
//
dataRootDirectory = Directory.GetParent(versionedDirectory).FullName;
}
else if (!Directory.Exists(Path.Combine(versionedDirectory, TemplateDirectoryName)))
{
// If the folder "%ProgramData%\{...}\{major}.{minor}" exists, then try to see
// if the folder "%ProgramData%\{...}\{major}.{minor}\templates" exists. If it
// doesn't exist, then root directory would be "%ProgramData%\{...}".
//
dataRootDirectory = Directory.GetParent(versionedDirectory).FullName;
}

var uiCulture = CultureInfo.CurrentUICulture.Name;
var templateDirectory = Path.Combine(dataRootDirectory, TemplateDirectoryName, uiCulture);

// If the localized template directory does not exist then fall back
// to using the en-US template folder. Do an additional check to see
// if the localized folder is available but is empty.
//
var di = new DirectoryInfo(templateDirectory);
if (!Directory.Exists(templateDirectory) ||
!di.GetDirectories().Any() ||
!di.GetFiles("*.dyn", SearchOption.AllDirectories).Any())
{
var neturalCommonTemplates = Path.Combine(dataRootDirectory, TemplateDirectoryName, "en-US");
if (Directory.Exists(neturalCommonTemplates))
templateDirectory = neturalCommonTemplates;
}

return templateDirectory;
}

private IEnumerable<string> LibrarySearchPaths(string library)
{
// Strip out possible directory from library path.
Expand Down
35 changes: 30 additions & 5 deletions src/DynamoCore/Models/DynamoModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1957,6 +1957,29 @@ public void OpenFileFromPath(string filePath, bool forceManualExecutionMode = fa
}
}

/// <summary>
/// Opens a Dynamo workspace from a path to a template on disk.
/// </summary>
/// <param name="filePath">Path to file</param>
/// <param name="forceManualExecutionMode">Set this to true to discard
/// execution mode specified in the file and set manual mode</param>
public void OpenTemplateFromPath(string filePath, bool forceManualExecutionMode = false)
{

if (DynamoUtilities.PathHelper.isValidJson(filePath, out string fileContents, out Exception ex))
{
OpenJsonFileFromPath(fileContents, filePath, forceManualExecutionMode, true);
}
else
{
// These kind of exceptions indicate that file is not accessible
if (ex is IOException || ex is UnauthorizedAccessException || ex is JsonReaderException)
{
throw ex;
}
}
}

/// <summary>
/// Inserts a Dynamo graph or Custom Node inside the current workspace from a file path
/// </summary>
Expand Down Expand Up @@ -2028,8 +2051,9 @@ static private DynamoPreferencesData DynamoPreferencesDataFromJson(string json)
/// <param name="filePath">Path to file</param>
/// <param name="forceManualExecutionMode">Set this to true to discard
/// execution mode specified in the file and set manual mode</param>
/// <param name="isTemplate">Set this to true to indicate that the file is a template</param>
/// <returns>True if workspace was opened successfully</returns>
private bool OpenJsonFileFromPath(string fileContents, string filePath, bool forceManualExecutionMode)
private bool OpenJsonFileFromPath(string fileContents, string filePath, bool forceManualExecutionMode, bool isTemplate = false)
{
try
{
Expand All @@ -2040,7 +2064,7 @@ private bool OpenJsonFileFromPath(string fileContents, string filePath, bool for
if (true) //MigrationManager.ProcessWorkspace(dynamoPreferences.Version, xmlDoc, IsTestMode, NodeFactory))
QilongTang marked this conversation as resolved.
Show resolved Hide resolved
{
WorkspaceModel ws;
if (OpenJsonFile(filePath, fileContents, dynamoPreferences, forceManualExecutionMode, out ws))
if (OpenJsonFile(filePath, fileContents, dynamoPreferences, forceManualExecutionMode, isTemplate, out ws))
{
OpenWorkspace(ws);
//Raise an event to deserialize the view parameters before
Expand Down Expand Up @@ -2076,7 +2100,7 @@ private bool InsertJsonFileFromPath(string fileContents, string filePath, bool f
{
if (true) //MigrationManager.ProcessWorkspace(dynamoPreferences.Version, xmlDoc, IsTestMode, NodeFactory))
{
if (OpenJsonFile(filePath, fileContents, dynamoPreferences, forceManualExecutionMode, out WorkspaceModel ws))
if (OpenJsonFile(filePath, fileContents, dynamoPreferences, forceManualExecutionMode, false, out WorkspaceModel ws))
{
ExtraWorkspaceViewInfo viewInfo = ExtraWorkspaceViewInfo.ExtraWorkspaceViewInfoFromJson(fileContents);

Expand Down Expand Up @@ -2268,6 +2292,7 @@ private bool OpenJsonFile(
string fileContents,
DynamoPreferencesData dynamoPreferences,
bool forceManualExecutionMode,
bool isTemplate,
out WorkspaceModel workspace)
{
if (!string.IsNullOrEmpty(filePath))
Expand Down Expand Up @@ -2295,8 +2320,8 @@ private bool OpenJsonFile(
CustomNodeManager,
this.LinterManager);

workspace.FileName = string.IsNullOrEmpty(filePath) ? "" : filePath;
workspace.FromJsonGraphId = string.IsNullOrEmpty(filePath) ? WorkspaceModel.ComputeGraphIdFromJson(fileContents) : "";
workspace.FileName = string.IsNullOrEmpty(filePath) || isTemplate? string.Empty : filePath;
workspace.FromJsonGraphId = string.IsNullOrEmpty(filePath) ? WorkspaceModel.ComputeGraphIdFromJson(fileContents) : string.Empty;
workspace.ScaleFactor = dynamoPreferences.ScaleFactor;

if (!IsTestMode && !IsHeadless)
Expand Down
8 changes: 8 additions & 0 deletions src/DynamoCore/Models/DynamoModelCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,20 @@ protected virtual void OpenFileImpl(OpenFileCommand command)
{
string filePath = command.FilePath;
bool forceManualMode = command.ForceManualExecutionMode;
bool isTemplate = command.IsTemplate;
OpenFileFromPath(filePath, forceManualMode);

//clear the clipboard to avoid copying between dyns
//ClipBoard.Clear();
}

protected virtual void OpenTemplateImpl(OpenFileCommand command)
{
string filePath = command.FilePath;
bool forceManualMode = command.ForceManualExecutionMode;
OpenTemplateFromPath(filePath, forceManualMode);
}

protected virtual void OpenFileFromJsonImpl(OpenFileFromJsonCommand command)
{
string fileContents = command.FileContents;
Expand Down
16 changes: 13 additions & 3 deletions src/DynamoCore/Models/RecordableCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -458,14 +458,16 @@ public class OpenFileCommand : RecordableCommand
#region Public Class Methods

/// <summary>
///
/// Constructor
/// </summary>
/// <param name="filePath">The path to the file.</param>
/// <param name="forceManualExecutionMode">Should the file be opened in manual execution mode?</param>
public OpenFileCommand(string filePath, bool forceManualExecutionMode = false)
/// <param name="isTemplate">Is Dynamo opening a template file?</param>
public OpenFileCommand(string filePath, bool forceManualExecutionMode = false, bool isTemplate = false)
{
FilePath = filePath;
ForceManualExecutionMode = forceManualExecutionMode;
IsTemplate = isTemplate;
}

private static string TryFindFile(string xmlFilePath, string uriString = null)
Expand Down Expand Up @@ -507,6 +509,7 @@ internal static OpenFileCommand DeserializeCore(XmlElement element)
[DataMember]
internal string FilePath { get; private set; }
internal bool ForceManualExecutionMode { get; private set; }
internal bool IsTemplate { get; private set; }
private DynamoModel dynamoModel;

#endregion
Expand All @@ -516,7 +519,14 @@ internal static OpenFileCommand DeserializeCore(XmlElement element)
protected override void ExecuteCore(DynamoModel dynamoModel)
{
this.dynamoModel = dynamoModel;
dynamoModel.OpenFileImpl(this);
if (IsTemplate)
{
dynamoModel.OpenTemplateImpl(this);
}
else
{
dynamoModel.OpenFileImpl(this);
}
}

protected override void SerializeCore(XmlElement element)
Expand Down
36 changes: 36 additions & 0 deletions src/DynamoCoreWpf/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 13 additions & 1 deletion src/DynamoCoreWpf/Properties/Resources.en-US.resx
Original file line number Diff line number Diff line change
Expand Up @@ -3900,4 +3900,16 @@ In certain complex graphs or host program scenarios, Automatic mode may cause in
<data name="ResetChangesWarningPopupMessage" xml:space="preserve">
<value>Your changes will be lost if you proceed.</value>
</data>
</root>
<data name="DynamoViewFileMenuOpenFile" xml:space="preserve">
<value>_File</value>
</data>
<data name="DynamoViewFileMenuOpenTemplate" xml:space="preserve">
<value>_Template</value>
</data>
<data name="WorkspaceSaveTemplateDirectoryBlockMsg" xml:space="preserve">
<value>Workspaces cannot be saved to the Templates folder. Please choose a different folder to save your file.</value>
</data>
<data name="WorkspaceSaveTemplateDirectoryBlockTitle" xml:space="preserve">
<value>Invalid Save Path</value>
</data>
</root>
12 changes: 12 additions & 0 deletions src/DynamoCoreWpf/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -3887,4 +3887,16 @@ In certain complex graphs or host program scenarios, Automatic mode may cause in
<data name="ResetChangesWarningPopupMessage" xml:space="preserve">
<value>Your changes will be lost if you proceed.</value>
</data>
<data name="DynamoViewFileMenuOpenFile" xml:space="preserve">
<value>_File</value>
</data>
<data name="DynamoViewFileMenuOpenTemplate" xml:space="preserve">
<value>_Template</value>
</data>
<data name="WorkspaceSaveTemplateDirectoryBlockMsg" xml:space="preserve">
<value>Workspaces cannot be saved to the Templates folder. Please choose a different folder to save your file.</value>
</data>
<data name="WorkspaceSaveTemplateDirectoryBlockTitle" xml:space="preserve">
<value>Invalid Save Path</value>
</data>
</root>
Loading
Loading