I am wondering if it is possible create or maybe even save multiple folder structures so that I can create a new folder with a template the user defines at the click of a toolbar button. So instead of having to go to my own custom premade folder and copy it every time when starting a new project I just use a quick button that uses the premade folder. I made a simple one that works for one folder which is cool
this allows for renaming the new folder and copying the folder I defined but I want more options and control. For instance allowing the user to create multiple templates and choose them and save them through a dialog popup. I thought I had something going with this but running into issues:
function OnClick(clickData)
{
var DOpusVars = DOpus.vars;
var templatePaths;
// Retrieve the stored template paths or initialize a new Vector if it doesn't exist
if (DOpusVars.Exists("TemplatePaths")) {
templatePaths = DOpusVars.Get("TemplatePaths");
} else {
templatePaths = DOpus.Create.Vector();
}
// Main dialog to choose an action
var dlg = clickData.func.Dlg;
dlg.window = clickData.func.sourcetab;
dlg.title = "Project Folder Template";
dlg.message = "Select an option:";
dlg.buttons = "Create Project|Add Template|Remove Template|Cancel";
dlg.icon = "question";
var choice = dlg.Show();
if (choice == 0 || choice == 4) return; // User clicked Cancel or closed dialog
if (choice == 2) // Add Template
{
// Use dlg.Folder() to select a folder
var folderDlg = clickData.func.Dlg;
folderDlg.window = clickData.func.sourcetab;
folderDlg.title = "Add Template Path";
folderDlg.message = "Select the template folder to add:";
folderDlg.initial = clickData.func.sourcetab.path;
var newTemplatePath = folderDlg.Folder();
if (!newTemplatePath) return; // User clicked Cancel
// Avoid duplicates
var exists = false;
for (var i = 0; i < templatePaths.count; i++) {
if (templatePaths(i) == newTemplatePath) {
exists = true;
break;
}
}
if (!exists) {
templatePaths.push_back(newTemplatePath);
DOpusVars.Set("TemplatePaths", templatePaths);
DOpus.Output("Template path added: " + newTemplatePath);
// Show success message
var msgDlg = clickData.func.Dlg;
msgDlg.window = clickData.func.sourcetab;
msgDlg.title = "Info";
msgDlg.message = "Template path added successfully.";
msgDlg.buttons = "OK";
msgDlg.icon = "info";
msgDlg.Show();
} else {
// Show error message
var msgDlg = clickData.func.Dlg;
msgDlg.window = clickData.func.sourcetab;
msgDlg.title = "Error";
msgDlg.message = "This template path already exists.";
msgDlg.buttons = "OK";
msgDlg.icon = "error";
msgDlg.Show();
}
return; // Exit script after adding template
}
else if (choice == 3) // Remove Template
{
if (templatePaths.count == 0)
{
// Show message if no templates to remove
var msgDlg = clickData.func.Dlg;
msgDlg.window = clickData.func.sourcetab;
msgDlg.title = "Info";
msgDlg.message = "No templates to remove.";
msgDlg.buttons = "OK";
msgDlg.icon = "info";
msgDlg.Show();
return;
}
// Build a list of template paths for selection
var items = DOpus.Create.Vector();
for (var i = 0; i < templatePaths.count; i++)
{
items.push_back(templatePaths(i));
}
var removeDlg = clickData.func.Dlg;
removeDlg.window = clickData.func.sourcetab;
removeDlg.title = "Remove Template Path";
removeDlg.message = "Select the template to remove:";
removeDlg.buttons = "OK|Cancel";
removeDlg.list = items;
removeDlg.icon = "info";
var res = removeDlg.Show();
if (res == 0) return; // User clicked Cancel
var removeIndex = removeDlg.listindex;
if (removeIndex >= 0 && removeIndex < templatePaths.count)
{
var removedTemplate = templatePaths(removeIndex);
templatePaths.erase(removeIndex);
DOpusVars.Set("TemplatePaths", templatePaths);
DOpus.Output("Removed template: " + removedTemplate);
// Show success message
var msgDlg = clickData.func.Dlg;
msgDlg.window = clickData.func.sourcetab;
msgDlg.title = "Info";
msgDlg.message = "Template removed successfully.";
msgDlg.buttons = "OK";
msgDlg.icon = "info";
msgDlg.Show();
}
else
{
// Show error message
var msgDlg = clickData.func.Dlg;
msgDlg.window = clickData.func.sourcetab;
msgDlg.title = "Error";
msgDlg.message = "Invalid selection.";
msgDlg.buttons = "OK";
msgDlg.icon = "error";
msgDlg.Show();
}
return; // Exit script after removing template
}
else if (choice == 1) // Create Project
{
if (templatePaths.count == 0)
{
// Show message if no templates available
var msgDlg = clickData.func.Dlg;
msgDlg.window = clickData.func.sourcetab;
msgDlg.title = "Info";
msgDlg.message = "No templates available. Please add a template first.";
msgDlg.buttons = "OK";
msgDlg.icon = "info";
msgDlg.Show();
return;
}
// Show list of templates to select from
var items = DOpus.Create.Vector();
for (var i = 0; i < templatePaths.count; i++)
{
items.push_back(templatePaths(i));
}
var selectDlg = clickData.func.Dlg;
selectDlg.window = clickData.func.sourcetab;
selectDlg.title = "Select Template";
selectDlg.message = "Select a template to use:";
selectDlg.buttons = "OK|Cancel";
selectDlg.list = items;
selectDlg.icon = "question";
var res = selectDlg.Show();
if (res == 0) return; // User clicked Cancel
var selectedIndex = selectDlg.listindex;
if (selectedIndex >= 0 && selectedIndex < templatePaths.count)
{
var selectedTemplate = templatePaths(selectedIndex);
DOpus.Output("Selected template: " + selectedTemplate);
// Prompt for project name
var nameDlg = clickData.func.Dlg;
nameDlg.window = clickData.func.sourcetab;
nameDlg.title = "Project Name";
nameDlg.message = "Enter Project Name:";
nameDlg.buttons = "OK|Cancel";
nameDlg.icon = "info";
nameDlg.max = 128;
var resName = nameDlg.Show();
if (resName == 0) return; // User clicked Cancel
var projectName = nameDlg.input;
if (!projectName) {
// Show error message if project name is empty
var msgDlg = clickData.func.Dlg;
msgDlg.window = clickData.func.sourcetab;
msgDlg.title = "Error";
msgDlg.message = "Project name cannot be empty.";
msgDlg.buttons = "OK";
msgDlg.icon = "error";
msgDlg.Show();
return;
}
// Copy the template to the destination
var cmd = clickData.func.command;
cmd.ClearFiles();
var destPath = clickData.func.sourcetab.path;
var copyCommand = 'Copy "' + selectedTemplate + '" TO="' + destPath + '" AS="' + projectName + '"';
cmd.RunCommand(copyCommand);
// Show success message
var msgDlg = clickData.func.Dlg;
msgDlg.window = clickData.func.sourcetab;
msgDlg.title = "Info";
msgDlg.message = "Project folder created successfully.";
msgDlg.buttons = "OK";
msgDlg.icon = "info";
msgDlg.Show();
}
else
{
// Show error message
var msgDlg = clickData.func.Dlg;
msgDlg.window = clickData.func.sourcetab;
msgDlg.title = "Error";
msgDlg.message = "Invalid selection.";
msgDlg.buttons = "OK";
msgDlg.icon = "error";
msgDlg.Show();
}
}
}
Something akin to what you can do with Anchorpoint here where you define your folder to use as a template but you can have a dropdown where you can save multiple to choose from when making a new folder. Ignore him talking about tokens the first part where it copies the folder is sufficient in my case.
Parse this folder (no recurse) to retrieve all the subfolders
Put their name in a drop down (custom dialog to build)
The custom dialog would have to have a button to "instantiate" that template to the current folder
You may have to find a way to get more speaking names than the name of the folder itself. That can be done in various ways depending on your constraints on the template folder naming (one easy way would be to have your templates folders in a two level tree structure <Name To Display in DropDown>/<Template folder with whatever name you need/want>).
EDIT : If you want a very simplified dialog, it may even be possible to do the dialog dynamically without reverting to the dialog editor.
If you want a folder with template folders below it, you can use Go FOLDERCONTENT to put a list of template folders on a menu or toolbar, and some other arguments to tell it ti copy them to the current folder when selected.
Alternatively, you could make buttons/menus which each have a few CreateFolder commands in to make the folders, with everything defined in the buttons/menus and no template folders on disk.
This is an interesting approach that I think is getting me closer to a solution. Currently have this but it keeps giving an "undefine" error. It is not recognizing the selected folder from the dropdown when clicking to copy over.
function OnClick(clickData)
{
// Set the path to your templates directory
var templatesPath = "F:\\Assets Editing\\Templates"; // Update this path accordingly
// Use FileSystemObject to read subfolders
var fso = new ActiveXObject("Scripting.FileSystemObject");
if (!fso.FolderExists(templatesPath)) {
DOpus.Output("Templates path does not exist: " + templatesPath);
DOpus.MessageBox("Templates path does not exist:\n" + templatesPath, "Error", "OK");
return;
}
var folder = fso.GetFolder(templatesPath);
var subFolders = new Enumerator(folder.SubFolders);
var templates = [];
for (; !subFolders.atEnd(); subFolders.moveNext()) {
var subFolder = subFolders.item();
templates.push(subFolder.Name);
}
if (templates.length == 0) {
DOpus.Output("No templates found in " + templatesPath);
DOpus.MessageBox("No templates found in:\n" + templatesPath, "Error", "OK");
return;
}
// Show dialog to select a template
var dlg = clickData.func.Dlg;
dlg.window = clickData.func.sourcetab;
dlg.title = "Select Template";
dlg.message = "Select a template to use:";
dlg.buttons = "OK|Cancel";
dlg.choices = templates;
var result = dlg.Show();
if (result != 1) {
DOpus.Output("User canceled the template selection.");
return;
}
var selectedTemplateIndex = dlg.choice;
var selectedTemplateName = templates[selectedTemplateIndex];
var selectedTemplatePath = templatesPath + "\\" + selectedTemplateName;
// Prompt for project name
var nameDlg = clickData.func.Dlg;
nameDlg.window = clickData.func.sourcetab;
nameDlg.title = "Project Name";
nameDlg.message = "Enter Project Name:";
nameDlg.buttons = "OK|Cancel";
nameDlg.max = 128;
var resName = nameDlg.GetString();
if (!resName) {
DOpus.Output("User canceled the project name input.");
return;
}
var projectName = nameDlg.input;
if (!projectName) {
DOpus.Output("Project name is empty.");
DOpus.MessageBox("Project name cannot be empty.", "Error", "OK");
return;
}
// Copy the template to the current folder with the new project name
var cmd = clickData.func.command;
cmd.ClearFiles();
var destPath = clickData.func.sourcetab.path;
cmd.AddFile(selectedTemplatePath);
cmd.RunCommand('Copy TO="' + destPath + '" AS="' + projectName + '"');
DOpus.Output("Copied template '" + selectedTemplateName + "' to '" + destPath + '\\' + projectName + "'");
// Show success message
DOpus.MessageBox("Project folder created successfully:\n" + destPath + '\\' + projectName, "Success", "OK");
}
Hey Leo! I can't seem to figure out how to get your Go FOLDERCONTENT method to work. Also would I then need individual buttons for every different template with this method?
First : I think you do not need to use an ActiveX Scripting.FileSystemObject. You could use Opus internal objects, building a path and use DOpus.FSUtil.ReadDir to iterate your folder. But it's not critical.
Second, in your script, get to the line in the first dialog building part where you declare the choices from your templates array and replace by :
dlg.choices = templates;
dlg.selection = 0;
var result = dlg.Show();
if (result != 1) {
DOpus.Output("User canceled the template selection.");
return;
}
var selectedTemplateIndex = dlg.choices[dlg.selection];
DOpus.Output("Choice " + selectedTemplateIndex );
var selectedTemplateName = templates[selectedTemplateIndex];
DOpus.Output("Name " + selectedTemplateName);
Setting the dlg.selection = 0; : allows to automatically select first item in the list
Then use dlg.choices[dlg.selection] to access the item from the array (since you assigned an array to dlg.choices).
That worked! Weirdly though it is throwing an error even though it seems to be Functioning properly:
Choice 2
Name General
Copied template 'General' to 'E:\Current Projects\dhdhd'
Error at line 77, position 5
Object doesn't support this property or method (0x800a01b6)
It looks like a way around this error has to do with the messagebox or dialog. This code works
function OnClick(clickData)
{
// Set the path to your templates directory
var templatesPath = "F:\\Assets Editing\\Templates\\Project Folder Templates"; // Update this path accordingly
// Use FileSystemObject to read subfolders
var fso = new ActiveXObject("Scripting.FileSystemObject");
if (!fso.FolderExists(templatesPath)) {
DOpus.Output("Templates path does not exist: " + templatesPath);
var dlg = clickData.func.Dlg;
dlg.window = clickData.func.sourcetab;
dlg.Request("Templates path does not exist:\n" + templatesPath, "Error", "OK", "error");
return;
}
var folder = fso.GetFolder(templatesPath);
var subFolders = new Enumerator(folder.SubFolders);
var templates = [];
for (; !subFolders.atEnd(); subFolders.moveNext()) {
var subFolder = subFolders.item();
templates.push(subFolder.Name);
}
if (templates.length == 0) {
DOpus.Output("No templates found in " + templatesPath);
var dlg = clickData.func.Dlg;
dlg.window = clickData.func.sourcetab;
dlg.Request("No templates found in:\n" + templatesPath, "Error", "OK", "error");
return;
}
// Show dialog to select a template
var dlg = clickData.func.Dlg;
dlg.window = clickData.func.sourcetab;
dlg.title = "Select Template";
dlg.message = "Select a template to use:";
dlg.buttons = "OK|Cancel";
dlg.choices = templates;
dlg.selection = 0;
var result = dlg.Show();
if (result != 1) {
DOpus.Output("User canceled the template selection.");
return;
}
var selectedTemplateIndex = dlg.selection;
DOpus.Output("Choice " + selectedTemplateIndex );
var selectedTemplateName = templates[selectedTemplateIndex];
DOpus.Output("Name " + selectedTemplateName);
var selectedTemplatePath = templatesPath + "\\" + selectedTemplateName;
// Prompt for project name
var nameDlg = clickData.func.Dlg;
nameDlg.window = clickData.func.sourcetab;
nameDlg.title = "Project Name";
nameDlg.message = "Enter Project Name:";
nameDlg.buttons = "OK|Cancel";
nameDlg.max = 128;
var resName = nameDlg.GetString();
if (!resName) {
DOpus.Output("User canceled the project name input.");
return;
}
var projectName = nameDlg.input;
if (!projectName) {
DOpus.Output("Project name is empty.");
var dlg = clickData.func.Dlg;
dlg.window = clickData.func.sourcetab;
dlg.Request("Project name cannot be empty.", "Error", "OK", "error");
return;
}
// Copy the template to the current folder with the new project name
var cmd = clickData.func.command;
cmd.ClearFiles();
var destPath = clickData.func.sourcetab.path;
cmd.AddFile(selectedTemplatePath);
cmd.RunCommand('Copy TO="' + destPath + '" AS="' + projectName + '"');
DOpus.Output("Copied template '" + selectedTemplateName + "' to '" + destPath + '\\' + projectName + "'");
// Show success message
var dlg = clickData.func.Dlg;
dlg.window = clickData.func.sourcetab;
dlg.Request("Project folder created successfully:\n" + destPath + '\\' + projectName, "Success", "OK", "info");
}
Yep : DOpus.MessageBox does not exist (see Manual for DOpus object).
So the error you get is quite normal : (DOpus) Object doesn't support this method.
Well Unless I am not using yours correctly it does not do what I want. It just takes me to the directory where my preset folders are. I want a streamlined solution that creates a new file, names it, and lets the user define their own directory of where to look for template folders without even needing to look at code and change it. For instance I can change the template easily with a dropdown window and can also customize any template path I want just by clicking change path.
Then I just name.
So unless I am missing something which I very well may be I cant get your solution to do something like that.
The \\ should only be \, but that looks fine otherwise.
If you put that on a toolbar and then click one of the sub-dirs that it places on the toolbar, the sub-dir will be copied to the current location. I just tested it with this command and it worked for me:
Go "C:\Program Files" FOLDERCONTENT=copytosource COPYARGS COPYFILETIMES=no