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

Skripting, undo: I gt an Error i dont understand

Participant ,
Apr 08, 2024 Apr 08, 2024

Copy link to clipboard

Copied

In the following simplified code I get the error that "the last command could not be undone".

Anyone knows WHY I get this error?

 

 

 

QGlobalSemaphores = [];

// ECMAScript 3 has no classes
function WaitForIt(callback, object) {
	this.object = object;
	this.answer = null;
	this.index  = -1;
	this.callback = callback;
}

function doSubscript(index) {
	mySemaphore = QGlobalSemaphores[index];
	mySemaphore.callback(mySemaphore.object);
	alert("executed");
}

function executeSubscript(callback, object) {
	var w = new WaitForIt(callback, object);
	w.index = QGlobalSemaphores.push(w) - 1;
	app.doScript(doSubscript,ScriptLanguage.JAVASCRIPT,[w.index],UndoModes.FAST_ENTIRE_SCRIPT,'FE-Test');
}

function deleteLayers(obj) {
	var doc = app.activeDocument;
	var i = doc.layers.length;
	while (i-->1) {
		doc.layers[i].remove();
	}
}

function test() {
	executeSubscript(deleteLayers, null);
	app.undo(); // <-- I get the error here.
}

app.doScript(test,ScriptLanguage.JAVASCRIPT,[],UndoModes.ENTIRE_SCRIPT,'Callback-Test');

 

 

 

TOPICS
Bug , How to , Scripting

Views

1.0K

Translate

Translate

Report

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

correct answers 1 Correct answer

Community Expert , Apr 16, 2024 Apr 16, 2024
quote

I didnt get a solution, I got some workarounds.

 

By @Lordrhavin

 

well. workarounds are solutions for situations where there are no other solutions.

Votes

Translate

Translate
Guide ,
Apr 08, 2024 Apr 08, 2024

Copy link to clipboard

Copied

I suspect it is the nested doScripts. Try the undo after the app.doScript(test....

 

P.

Votes

Translate

Translate

Report

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
Participant ,
Apr 08, 2024 Apr 08, 2024

Copy link to clipboard

Copied

Yeah, thats sadly not what i need -.-
I need to undo the subscript, not the entire script.

Votes

Translate

Translate

Report

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 ,
Apr 08, 2024 Apr 08, 2024

Copy link to clipboard

Copied

just a shot in the dark but will the default undo mode 'script request' make a difference?

Votes

Translate

Translate

Report

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 ,
Apr 08, 2024 Apr 08, 2024

Copy link to clipboard

Copied

You have probably tried this already but if not, try UndoModes.ENTIRE_SCRIPT rather than UndoModes.FAST_ENTIRE_SCRIPT because I recall that users have reported issues related to Undo with FAST_ENTIRE_SCRIPT.  There is an old article that discusses.

 

I would be tempted to test the various UndoModes in your inner and outer doScripts. Does any combination of them give you the desired result with no error?  Maybe it's just that using FAST_ENTIRE_SCRIPT *and then undo-ing it* is not going to work?

- Mark

Votes

Translate

Translate

Report

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
Participant ,
Apr 09, 2024 Apr 09, 2024

Copy link to clipboard

Copied

I tested all 16 combinations.

- All combinations throw the error.
- If the outher script is set to SCRIPT_REQUEST, it does not undo automatically. Further, the inner script has *then* the following results:
ENTIRE_SCRIPT or FAST_ENTIRE_SCRIPT: I can manually undo everything in one step.
SCRIPT_REQUEST:  I can manually undo everything stepwise.


The combination SCRIPT_REQUEST on mainscript and AUTO_UNDO on subscript didnt undo and I couldnt even undo manually; I had to reload the doc.

I also tested doing undo in a try-clause. It ommited the error but didnt undo at all 😄

Votes

Translate

Translate

Report

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 ,
Apr 09, 2024 Apr 09, 2024

Copy link to clipboard

Copied

Hi @Lordrhavin , Have you run your deleteLayers(obj) function by itself to check if it is doing what you expect?

 

A document has to have at least one layer, so the function would throw an error on a single layer document, and on a multi layer doc it only removes half the layers. Something like this, which loops an array rather than a collection, would remove all the layers (and their contents) except for the bottom layer:

 

deleteLayers("hi")

function deleteLayers(obj) {
	var lyr = app.activeDocument.layers.everyItem().getElements();
	for (var i = lyr.length-2; i > -1; i--) {
		lyr[i].remove();
	}
    $.writeln(obj)//returns hi
}

 

 

Votes

Translate

Translate

Report

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
Participant ,
Apr 09, 2024 Apr 09, 2024

Copy link to clipboard

Copied

Yes, I know that it i not deleting the last layer. But as it does this without any error and I also get this error if I just start with i=1, I dont saw the difference in posting that code.

 

Votes

Translate

Translate

Report

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 ,
Apr 09, 2024 Apr 09, 2024

Copy link to clipboard

Copied

I dont saw the difference in posting that code.

 

With your function I get this:

 

Before:

Screen Shot 20.png

After

 

Screen Shot 21.png

 

With the reverse array loop I get this

 

Screen Shot 19.png

Votes

Translate

Translate

Report

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
Participant ,
Apr 09, 2024 Apr 09, 2024

Copy link to clipboard

Copied

yes, this is oversimplified. Im tracking the error. You get the same error if you just kill one arbitrary layer. deleteLayer just had to do smething to my demo-doc, so i really didn't care if it does this correctly. I updated the code above.

Votes

Translate

Translate

Report

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 ,
Apr 09, 2024 Apr 09, 2024

Copy link to clipboard

Copied

quote

yes, this is oversimplified. Im tracking the error. You get the same error if you just kill one arbitrary layer. deleteLayer just had to do smething to my demo-doc, so i really didn't care if it does this correctly. I updated the code above.


By @Lordrhavin

 

Do not delete i-th layer - becuase as @rob day pointed out - you'll be skipping elements - delete last or first one - depends on which one you wan to keep:

 

function deleteLayers(obj) {
	var doc = app.activeDocument;
	var i = doc.layers.length;
	while (i-->1) {
		doc.layers[-1].remove();
	}
}

 

Votes

Translate

Translate

Report

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
Participant ,
Apr 09, 2024 Apr 09, 2024

Copy link to clipboard

Copied

app.activeDocument.layers.length is n= "it has n layer(s)"
app.activeDocument.layers is base 0

 

 

 

var i = 10;
while (i-->1) {
   // i goes 9 to 1
}

 

 

 

 It actually deletes all layers except the zeroth.

Votes

Translate

Translate

Report

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 ,
Apr 09, 2024 Apr 09, 2024

Copy link to clipboard

Copied

I think you need app.activeDoucument.undo() rather than app.undo(). This works for me:

 

var doc = app.activeDocument;

function deleteLayers() {
	doc.layers[0].remove();
}

app.doScript(deleteLayers,ScriptLanguage.JAVASCRIPT,[],UndoModes.ENTIRE_SCRIPT,'DeleteLayer');

alert("Restoring Layer")

//app.undo();//throws Unable to undo the last command. error
doc.undo()

Votes

Translate

Translate

Report

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
Participant ,
Apr 09, 2024 Apr 09, 2024

Copy link to clipboard

Copied

I still get the same error. Did you call the subscript?

Votes

Translate

Translate

Report

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 ,
Apr 09, 2024 Apr 09, 2024

Copy link to clipboard

Copied

I’m not sure what’s going on with your code, my example just shows that app.undo() always throws an error with doScript()—it has to be app.activeDocument.undo().

 

I think you should watch out for the difference between collections and arrays—layers is a collection not an array of layers. A collection is similar to an array but they do not share the same methods. @Robert at ID-Tasker while loop could also be written like this where I’m explicity using the collection’s firstItem() and lastItem() methods to remove all the items above or below.

 


var doc = app.activeDocument;

function deleteLayers() {
	var i = app.activeDocument.layers.count();
	while (i-->1) {
		//doc.layers.firstItem().remove();//removes all layers except for the bottom layer
		doc.layers.lastItem().remove();//removes all layers except for the top layer
	}
}

app.doScript(deleteLayers,ScriptLanguage.JAVASCRIPT,[],UndoModes.ENTIRE_SCRIPT,'DeleteLayer');

alert("Restoring Layers")

//app.undo();//throws Unable to undo the last command. error
doc.undo()

Votes

Translate

Translate

Report

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
Participant ,
Apr 09, 2024 Apr 09, 2024

Copy link to clipboard

Copied

Yeah, but that is not the point. I cant see a subscript in you code. Try this even more simplified version:

 

 

function inner() {
	var doc = app.activeDocument;
	var i = doc.layers.length;
	while (i-->1) {
		doc.layers.lastItem().remove();
	}
}

function outher() {
	app.doScript(inner,ScriptLanguage.JAVASCRIPT,[],UndoModes.SCRIPT_REQUEST,'inner');
	alert("pause");
	app.activeDocument.undo(); //<- error
}

app.doScript(outher,ScriptLanguage.JAVASCRIPT,[],UndoModes.ENTIRE_SCRIPT,'outher');

 

 

Votes

Translate

Translate

Report

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 ,
Apr 09, 2024 Apr 09, 2024

Copy link to clipboard

Copied

I don‘t think it‘s going to work—the pause and undo have to happen after outher is called.

 

function inner() {
	var doc = app.activeDocument;
	var i = doc.layers.length;
	while (i-->1) {
		doc.layers.lastItem().remove();
	}
}

function outher() {
	app.doScript(inner,ScriptLanguage.JAVASCRIPT,[],UndoModes.SCRIPT_REQUEST,'outher');
}

app.doScript(outher,ScriptLanguage.JAVASCRIPT,[],UndoModes.ENTIRE_SCRIPT,'inner');

alert("pause");
app.activeDocument.undo();

Votes

Translate

Translate

Report

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 ,
Apr 09, 2024 Apr 09, 2024

Copy link to clipboard

Copied

Is there a problem with running the doScripts sequentially?

 

function inner() {
	var doc = app.activeDocument;
	var i = doc.layers.length;
	while (i-->1) {
		doc.layers.lastItem().remove();
	}
}


app.doScript(inner,ScriptLanguage.JAVASCRIPT,[],UndoModes.ENTIRE_SCRIPT,'inner');

alert("Oops Restoring layers");
app.activeDocument.undo();

alert("Deleting them again");
app.doScript(inner,ScriptLanguage.JAVASCRIPT,[],UndoModes.ENTIRE_SCRIPT,'inner');

alert("Wait Just Kidding");
app.activeDocument.undo();

 

 

Votes

Translate

Translate

Report

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
Participant ,
Apr 09, 2024 Apr 09, 2024

Copy link to clipboard

Copied

>Is there a problem with running the doScripts sequentially?

Yes. The doScript encapsulate the blocks I need to undo. Still, after executing th script, Strg+Z should undo everything.

Votes

Translate

Translate

Report

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 ,
Apr 09, 2024 Apr 09, 2024

Copy link to clipboard

Copied

quote

>Is there a problem with running the doScripts sequentially?

Yes. The doScript encapsulate the block I need to undo.


By @Lordrhavin

 

Why do you need to undo the block? 

 

Votes

Translate

Translate

Report

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
Participant ,
Apr 09, 2024 Apr 09, 2024

Copy link to clipboard

Copied

- Userdialog asks which layers to export at which setting into which file.
- Skript iterates tru settings, calls subscript for each setting

subskript does
- delete layers not to export
- set layer-state on those to export (normal, hidden, unprintable, hidden+unprintabe)
- export to file(s)

Now skript undoes and start again for next setting.

Lordrhavin_0-1712677134675.png

 

Votes

Translate

Translate

Report

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 ,
Apr 09, 2024 Apr 09, 2024

Copy link to clipboard

Copied

quote

- Userdialog asks which layers to export at which setting into which file.
- Skript iterates tru settings, calls subscript for each setting

subskript does
- delete layers not to export
- set layer-state on those to export (normal, hidden, unprintable, hidden+unprintabe)
- export to file(s)

Now skript undoes and start again for next setting.

By @Lordrhavin

 

Well... next time please describe your workflow / what you want to achieve - you'll get the solution quicker...

 

Instead of finghting with UNDO - make a copy of the file, do what you want to do on the copy - delete the copy.

 

Do the above for each step / iteration.

 

Votes

Translate

Translate

Report

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
Participant ,
Apr 16, 2024 Apr 16, 2024

Copy link to clipboard

Copied

Thee >  next time please describe your workflow / what you want to achieve - you'll get the solution quicker
I didnt get a solution, I got some workarounds.

Me > Anyone knows WHY I get this error?
That is still not answered. I filed a bug report, as I think this a false-negative error .
https://indesign.uservoice.com/forums/601180-adobe-indesign-bugs/suggestions/48231980-undo-does-work...

Votes

Translate

Translate

Report

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 ,
Apr 16, 2024 Apr 16, 2024

Copy link to clipboard

Copied

quote

Thee >  next time please describe your workflow / what you want to achieve - you'll get the solution quicker
I didnt get a solution, I got some workarounds.


By @Lordrhavin

 

I'm sorry, what I meant, there is no need for you to try undoing things - what you want to achieve would be much easier if you make a copy of your original file, do show/hide/delete of the layers, export - and then start over with a new copy of the file.

 

That way, you don't need to try to go back to the right point in time - with a new copy of the file - you are starting with a clean slate.

 

Votes

Translate

Translate

Report

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 ,
Apr 16, 2024 Apr 16, 2024

Copy link to clipboard

Copied

There’s also revert()

 

app.scriptPreferences.userInteractionLevel = UserInteractionLevels.NEVER_INTERACT;
app.activeDocument.revert();
app.scriptPreferences.userInteractionLevel = UserInteractionLevels.INTERACT_WITH_ALL

Votes

Translate

Translate

Report

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