Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
5

Can you make scripts behave differently if run from the script panel or run through use of shortcut?

Contributor ,
Aug 22, 2023 Aug 22, 2023

Hello everyone, 

 

Thanks to those have helped me so far.

New question, I have a script which has some parameters which can be changed but they are parameters which ought hardly ever to be changed. This is for InDesign

So I would prefer for the user not to have to face a dialogue box everytime they run it.

Can you prevent a dialogue box appear if they run it from shortcut? and only appear if run from the script menu?

 

Many thanks all, 

 

Best, 

 

Smyth

TOPICS
How to , Scripting , SDK
544
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 22, 2023 Aug 22, 2023

Hmm, don't think so. But you can write the prefs to a txt file in the same folder as the script, and have the values autopopulate in the panel. Then they could just hit OK, or adjust the parameters if needed (and you can write the new prefs back to the pref file). 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Aug 22, 2023 Aug 22, 2023

It seems they can. 

Ive managed to get the script when clicked to prompt a box in which the user can change parameters

and when they run the shortcut no parameter box comes up

it is reading to a json files which seems insane, as when the user inputs data it holds it in the json file and then that data is used if they use the shortcut

surely indesign can hold user data itself without having to use external json files etc

 

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Aug 22, 2023 Aug 22, 2023

This code 

used to work - this is later version which is even more destroyed 

however it does correcrly record user parameters to the json file 

there as a time the script would allow for users to input data 

and then on the shortcut running the script it would just do defult

// JSON polyfill
#targetengine "jsonPolyfill" // This avoids polluting the global namespace

// Include the JSON polyfill library
$.evalFile("C:\\Users\\user\\Desktop\\json2.js"); // Replace with the actual path to the json2.js file

// Initialize settingsFile as a File object
var settingsFile = new File("C:\\Users\\user\\Desktop\\rule_settings.json");

// Check if the script was invoked via a shortcut key
var invokedViaShortcut = false;
if (ScriptUI.environment.keyboardState.ctrlKey || ScriptUI.environment.keyboardState.altKey) {
    invokedViaShortcut = true;
}

// Declare user-defined variables
var userDefinedAmountTop = 0;
var userDefinedAmountBottom = 0;

// Function to save user-defined settings
function saveUserSettings() {
    var settings = {
        top: userDefinedAmountTop,
        bottom: userDefinedAmountBottom
    };

    // Save settings to the settingsFile
    settingsFile.open("w");
    settingsFile.write(JSON.stringify(settings));
    settingsFile.close();
}

// Function to load user-defined settings
function loadUserSettings() {
    if (settingsFile.exists) {
        settingsFile.open("r");
        var settingsData = settingsFile.read();
        settingsFile.close();

        var settings = JSON.parse(settingsData);
        userDefinedAmountTop = settings.top;
        userDefinedAmountBottom = settings.bottom;
    }
}

// Load user-defined settings when not invoked via shortcut
if (!invokedViaShortcut) {
    // Create a dialog box to input user-defined values
    var dialog = app.dialogs.add({ name: "Enter Values" });

    with (dialog) {
        // Add a dialog column
        with (dialogColumns.add()) {
            // Add fields to input user-defined values
            staticTexts.add({ staticLabel: "User-defined Amount Top:" });
            var topInput = measurementEditboxes.add({ editValue: userDefinedAmountTop });

            staticTexts.add({ staticLabel: "User-defined Amount Bottom:" });
            var bottomInput = measurementEditboxes.add({ editValue: userDefinedAmountBottom });

            // Remove unit values from user input fields
            topInput.editUnits = MeasurementUnits.POINTS;
            bottomInput.editUnits = MeasurementUnits.POINTS;
        }
    }

    // Display the dialog box
    if (dialog.show() == true) {
        userDefinedAmountTop = topInput.editValue;
        userDefinedAmountBottom = bottomInput.editValue;

        // Save user-defined settings
        saveUserSettings();
    } else {
        alert("Please select at least two text frames.");
    }

    dialog.destroy(); // Close the dialog after processing
} else {
    // Load user-defined settings
    loadUserSettings();

    // Sort selected text frames by their horizontal position
    selectedFrames.sort(function(a, b) {
        return a.geometricBounds[1] - b.geometricBounds[1];
    });

    // Wrap the script in an undoable action
    app.doScript(function() {
        // Iterate through the sorted selected text frames
        for (var i = 0; i < selectedFrames.length - 1; i++) {
            var currentFrame = selectedFrames[i];
            var nextFrame = selectedFrames[i + 1];

            // Check if the frames are on the same page
            if (currentFrame.parentPage === nextFrame.parentPage) {
                // Calculate the center position for the vertical rule
                var centerX = (currentFrame.geometricBounds[3] + nextFrame.geometricBounds[1]) / 2;

                // Calculate the height of the rule (same as the height of the taller object)
                var ruleHeight = Math.max(
                    currentFrame.geometricBounds[2] - currentFrame.geometricBounds[0],
                    nextFrame.geometricBounds[2] - nextFrame.geometricBounds[0]
                );

                // Determine the starting and ending heights for the rule
                var startHeight = Math.max(
                    currentFrame.geometricBounds[2],
                    nextFrame.geometricBounds[2]
                );

                var endHeight = Math.min(
                    currentFrame.geometricBounds[0],
                    nextFrame.geometricBounds[0]
                );

                // Adjust the start height for the line based on the user-defined amount
                var adjustedStartHeight = startHeight + userDefinedAmountBottom;
                var adjustedEndHeight = endHeight - userDefinedAmountTop;

                // Create a new line
                var newLine = currentFrame.parentPage.graphicLines.add();
                newLine.paths[0].entirePath = [
                    [centerX, adjustedStartHeight],
                    [centerX, adjustedEndHeight]
                ];

                // Send the line to the back
                newLine.sendToBack();
            }
        }
    }, ScriptLanguage.JAVASCRIPT, [], UndoModes.ENTIRE_SCRIPT, "Add Vertical Lines Between Text Boxes");
}
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 22, 2023 Aug 22, 2023

You can write the data to app.label and read that label using app.extractLabel, but what's wrong with writing to file?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 22, 2023 Aug 22, 2023

Like @brian_p_dts, I'm a big fan of writing to script settings to file(s). That keeps them accessible/inspectable but you can still keep them right out of sight (eg. if stored in the userData folder).

- Mark

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 22, 2023 Aug 22, 2023

Can you prevent a dialogue box appear if they run it from shortcut? and only appear if run from the script menu?

 

You could have two different scripts saved in the panel, one with a dialog and another with the default values and no dialog, then assign 2 different keyboard shortcuts—e.g. Command-A no dialog, or Command-Option-A show dialog.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 22, 2023 Aug 22, 2023

Rob's suggestion is a very good one. You put all your logic in "script file A". If you run "script file A" then the script runs using existing settings (json?). Then you make a UI/editor script—"script file B". If you run "script file B" it shows a UI, then runs "script file A" with those settings, and (optionally) saves the new settings to the json file that is read by "script file A".

- Mark

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Aug 22, 2023 Aug 22, 2023

Hello Rob and Mark, 

I do like this idea, two files - one with the script which provides funtionality - another which is an interface to paramerters. Both scripts access JSON one writes the other reads. 

I would like to give this a shot also - I feel like this should work quite easliy without tearing up much the origional script. 

The amusing part is that the script works perfectly fine, just would be easlier for users not to have to adjust via opening the file and editing - although once set users ought not to need to change but users will be users

Thanking you kindly. 

Smyth

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 23, 2023 Aug 23, 2023

You can also use Extendscript’s XML object to get and set dialog values. Here the last used values are saved in the script’s parent folder—if the XML file doesn’t exist one is wrtten with the values set as 0:

 

 

 

//this script’s folder
var f = File($.fileName).parent + "/defaults.xml";

//if there’s no XML set a default
var xml = readXML(f)
if (xml == "") {
    xml = XML( "<dialog><values><top>0</top><bottom>0</bottom></values></dialog>")
}

//get the top and bottom values from XML
//will be 0 if an xml file does not exist
var tv = Number(xml.values.top);
var bv = Number(xml.values.bottom);

var t, b;
makeDialog();
function makeDialog(){
    var d = app.dialogs.add({name:"Enter Values", canCancel:true});
    with(d.dialogColumns.add()){
        staticTexts.add({staticLabel:"User-defined Amount Top:"});
        staticTexts.add({staticLabel:"User-defined Amount Bottom:"});
    }
    with(d.dialogColumns.add()){
        t = measurementEditboxes.add({editUnits:MeasurementUnits.POINTS, editValue:tv, minWidth:50});
        b = measurementEditboxes.add({editUnits:MeasurementUnits.POINTS, editValue:bv, minWidth:50});
    }
    if(d.show() == true){
        //get the edit values
        t = t.editValue;
        b = b.editValue;

        //update defaults.xml with the entered dialog values
        xml.values.top = t;
        xml.values.bottom = b;
        writeXML(f, xml.toXMLString());

        //run main script
        app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Set Dimensions');
        d.destroy();
	}
}

/**
* The main script 
*/
function main(){
    alert("Dialog values:\r" + t + "\r" +b)
    $.writeln(xml)
    //returns the updated xml text
    
    //do something...
}

/**
* Write an XML file 
* @ param the file path 
* @ param the xml text 
* @ return void
*/
function writeXML(p,s){
    var file = new File(p);
    file.encoding = 'UTF-8';
    file.open('w');
    file.write(s);
    file.close();
}

/**
* Read an XML file 
* @ param the file path 
* @ returns an XML object
*/
function readXML(p) {
	var f = new File(p);
	f.open("r");  
	var t = f.read();  
	f.close();
	return XML(t); 
}

 

 

 

First run result:

Screen Shot 19.png

 

Next run dialog:

Screen Shot 20.png

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Aug 24, 2023 Aug 24, 2023
LATEST

Wow, thank you.

I will give this a shot to see how it works, 

Thank you, 

Smyth

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 22, 2023 Aug 22, 2023

Hi @SmythWharf, maybe holding alt key would be a viable solution? - Mark

var value = 34;
var altKey = ScriptUI.environment.keyboardState.altKey;

if (altKey) {
    // call your UI here
    value = prompt('Enter the number: ', value);
}

if (value !== null)
    alert('The number is ' + value + '.');
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Aug 22, 2023 Aug 22, 2023

Hello, 

Many thanks for the replys. 

Mark very nice concept - I wille explore this seems like it could cutdown a lot of code plus extra files.

Best, 

Smyth 


Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines