[Solved]How to Call Save function on my Script?

Discussion forum for C++ and script developers who are using the QCAD development platform or who are looking to contribute to QCAD (translations, documentation, etc).

Moderator: andrew

Forum rules

Always indicate your operating system and QCAD version.

Attach drawing files, scripts and screenshots.

Post one question per topic.

Ghost_of_Magellan
Full Member
Posts: 58
Joined: Wed Mar 16, 2016 5:10 pm

[Solved]How to Call Save function on my Script?

Post by Ghost_of_Magellan » Fri May 27, 2016 7:59 am

Greetings.

I expect this will be my last request for information in a looooooooooong time. =D

The script I made introduces elements into the drawing (through entity color and entity type) that I do not wish to be saved. They serve their purpose in certain conditions but I don't want them to be saved into the final version of the drawing to be saved.
I could alter the 'Save' and 'Save As' scripts, but that might cause problems when I want to make regular designs that do not make use of my application, so I am choosing to make my own save button that alters what needs to be altered and then uses the default 'Save' or 'Save As' function.

How do I make this happen? How do I call the 'Save' or 'Save As' functions on script as if I'd clicked a button?

Thank you very much.
Last edited by Ghost_of_Magellan on Wed Jun 01, 2016 11:34 am, edited 3 times in total.

User avatar
andrew
Site Admin
Posts: 9061
Joined: Fri Mar 30, 2007 6:07 am

Re: How to Call Save function on my Script?

Post by andrew » Fri May 27, 2016 8:05 am

Ghost_of_Magellan wrote:How do I make this happen? How do I call the 'Save' or 'Save As' functions on script as if I'd clicked a button?
This triggers the Save action (or any other action indicated as relative path to the script):
var action = RGuiAction.getByScriptFile("scripts/File/Save/Save.js");
if (!isNull(action)) {
    action.slotTrigger();
}

Ghost_of_Magellan
Full Member
Posts: 58
Joined: Wed Mar 16, 2016 5:10 pm

Re: How to Call Save function on my Script?

Post by Ghost_of_Magellan » Fri May 27, 2016 8:15 am

Thank for the swift reply as always.

Also, offtopic question.
When I call my script for the first time, it seems it causes the tool mode to be activated, preventing me from drawing or selecting entities on the drawing board. I have to press Esc or right click the mouse button to leave that mode. It's not a ground breaking problem but it's annoying. How can I do that directly through code?

Thank you very much.

User avatar
andrew
Site Admin
Posts: 9061
Joined: Fri Mar 30, 2007 6:07 am

Re: How to Call Save function on my Script?

Post by andrew » Fri May 27, 2016 8:24 am

Ghost_of_Magellan wrote:When I call my script for the first time, it seems it causes the tool mode to be activated, preventing me from drawing or selecting entities on the drawing board. I have to press Esc or right click the mouse button to leave that mode. It's not a ground breaking problem but it's annoying. How can I do that directly through code?
Does your script have a state? I.e. does it require user input in the form of mouse clicks, etc? If so, that is expected behavior. The script stays active when started and waits for such user input until Escape is pressed or the user right-clicks.

If your script is stateless (like File > Open, File > Save, Auto zoom, etc.), make sure you initialize your RGuiAction with:
action.setNoState();
This typically happens in MyScriptInit.js for a class called MyScript.

Ghost_of_Magellan
Full Member
Posts: 58
Joined: Wed Mar 16, 2016 5:10 pm

Re: How to Call Save function on my Script?

Post by Ghost_of_Magellan » Fri May 27, 2016 2:04 pm

Does your script have a state?
Well, yes, it has a state.
It's somewhat annoying, but if there's nothing to be done about it, then that's life. It's a loss but not a major one.

Regarding the matter of calling the Save and Save As functions, which is much more important, I can't seem to make it work.
var action = RGuiAction.getByScriptFile("scripts/File/Save/Save.js");
if (!isNull(action)) {
    action.slotTrigger();
}
I do this, as instructed, and in debug mode I can see that the variable action gets the value RGuiAction(0x4653bb8) when I try to call Save As and RGuiAction(0x464be78) when I try the simple Save. (Not sure this is relevant, but just in case).

As far as I am able to determine, action.slotTrigger(); does nothing but pass onto the command line: Command: saveas and Command: save according to my selection. Is there something missing here?

Thank you.

User avatar
andrew
Site Admin
Posts: 9061
Joined: Fri Mar 30, 2007 6:07 am

Re: How to Call Save function on my Script?

Post by andrew » Fri May 27, 2016 3:39 pm

Ghost_of_Magellan wrote:Well, yes, it has a state.
It's somewhat annoying, but if there's nothing to be done about it, then that's life. It's a loss but not a major one.
If your action has a state, it seems logical that it must listen for user input and must be terminated somehow. Maybe I don't understand the question correctly, but I don't think how this could be any different.. Perhaps you can elaborate on what you are trying to do? What is the new tool supposed to do? Why does it need to be stateful?
Ghost_of_Magellan wrote:action.slotTrigger(); does nothing but pass onto the command line: Command: saveas and Command: save according to my selection. Is there something missing here?
Yes, if your action is stateful, this will not work since the script engine is already busy handling a part of your action. In this case, you could queue the save action to be executed later:
include("scripts/File/Save/Save.js");
var a = new Save();
this.getDocumentInterface().queueAction(a);
This means that save will not be executed immediately but as soon as your action is done (terminated). Depending on what you are trying to achieve, it might make more sense to derive your action from "Save" in the first place and make it behave essentially like save with some bits and pieces added.

Ghost_of_Magellan
Full Member
Posts: 58
Joined: Wed Mar 16, 2016 5:10 pm

Re: How to Call Save function on my Script?

Post by Ghost_of_Magellan » Mon May 30, 2016 9:27 am

Perhaps you can elaborate on what you are trying to do? What is the new tool supposed to do? Why does it need to be stateful?
Basically, my application is used to list all valid existing entities, automatically organize the draw order of QCad designs, allow manual organization if the automatic one fails or is too broad, and changes colour and adds a circle at the end of the entity selected in the list, and the like.
However, it wasn't my intention to make the app awkward for the user to change the design or create new ones.

The save function here should only make a brief "clean" (wipe the colours and circles created in the user browsing the list so as not to save them) and refresh the list, making permanent the selected draw order. Everything else is supposed to be like the regular save.

Uncaught exception at scripts/IuSYS/FirstWidget/FirstWidget.js:1322: TypeError: Result of expression 'docInterface.getDocumentInterface' [undefined] is not a function.

This happens when I use the piece of code you gave me last.


Thanks

User avatar
andrew
Site Admin
Posts: 9061
Joined: Fri Mar 30, 2007 6:07 am

Re: How to Call Save function on my Script?

Post by andrew » Mon May 30, 2016 9:34 am

Ghost_of_Magellan wrote:Uncaught exception at scripts/IuSYS/FirstWidget/FirstWidget.js:1322: TypeError: Result of expression 'docInterface.getDocumentInterface' [undefined] is not a function.
This should probably be this.getDocumentInterface, not docInterface.getDocumentInterface...

Ghost_of_Magellan
Full Member
Posts: 58
Joined: Wed Mar 16, 2016 5:10 pm

Re: How to Call Save function on my Script?

Post by Ghost_of_Magellan » Mon May 30, 2016 9:43 am

Happens on this.getDocumentInterface too. I tested that first, actually.
widgets["cmd_Save"].clicked.connect(function () {
		//No point in saving an empty design
		if(nr_linhas > 0 && entityIds.length>0){
			//debugger;
			//Cleans colors and circles
			if (vl_nr_selected > 0){
				entityIds = WipeLastCircle(doc, docInterface, entityIds);
				SetLastColors(doc, docInterface, entityIds, last_id, last_color);	//returns original colors to items selected in the list
			}
			nr_linhas = DoRefresh(doc, docInterface, widgets, entityIds, nr_linhas);
			//Calls Save.
			var vl_save = new Save();
			this.getDocumentInterface().queueAction(vl_save);
				//if (!isNull(action)) {
				//	action.slotTrigger();
				//}
		}
	});
This is my full fuction for the button that is supposed to save, for the moment. Any additional info that you require on other functions, please say so.

User avatar
andrew
Site Admin
Posts: 9061
Joined: Fri Mar 30, 2007 6:07 am

Re: How to Call Save function on my Script?

Post by andrew » Mon May 30, 2016 9:59 am

'this' in the context of a function is the function, not the object around the function.

Try:
var self = this;
widgets["cmd_Save"].clicked.connect(function () {
   ...
   self.getDocumentInterface().queueAction(...)
   ...
}
Depending on wider context this might make more sense:
var di = this.getDocumentInterface();
widgets["cmd_Save"].clicked.connect(function () {
   ...
   di.queueAction(...);
   ...
}

User avatar
andrew
Site Admin
Posts: 9061
Joined: Fri Mar 30, 2007 6:07 am

Re: How to Call Save function on my Script?

Post by andrew » Mon May 30, 2016 10:00 am

BTW: you might want to try switching on the script debugger to investigate such problems:

./qcad -enable-script-debugger

You can then print the object that causes a problem, etc.

Ghost_of_Magellan
Full Member
Posts: 58
Joined: Wed Mar 16, 2016 5:10 pm

Re: How to Call Save function on my Script?

Post by Ghost_of_Magellan » Mon May 30, 2016 10:22 am

It appears this is it!
include("scripts/File/Save/Save.js");
var self = this;
	widgets["cmdExit"].clicked.connect(function () {
		var vl_save = new Save();
		self.getDocumentInterface().queueAction(vl_save)
	});
NOTE: cmdExit button is just a button for general testing. If it works here, I assume it works anywhere.

To do the same to 'Save As' do I have to do something like:
include("scripts/File/Save/SaveAs.js");
var vl_saveAs = new SaveAs();
self.getDocumentInterface().queueAction(vl_saveAs)
Or am i being too hopeful? =D

BTW, what's the difference between ./qcad -enable-script-debugger and the one I'm using right now, -rescan -enable-script-debugger ?
Thank you.

Ghost_of_Magellan
Full Member
Posts: 58
Joined: Wed Mar 16, 2016 5:10 pm

Re: How to Call Save function on my Script?

Post by Ghost_of_Magellan » Mon May 30, 2016 10:37 am

Yup. this is it.

Still somewhat annoying that I have to press Esc for the apptool to be deselected, but its fairly ok as it is.
It is also worth mentioning that this only happens the first time the app is called. After I deselect it the first time, I can juggle with the design and the several options of the app without constraint. So if there is a way to automatically deselect it after at the end of the beginEvent call, it would solve my problem.

User avatar
andrew
Site Admin
Posts: 9061
Joined: Fri Mar 30, 2007 6:07 am

Re: How to Call Save function on my Script?

Post by andrew » Mon May 30, 2016 10:43 am

I have a feeling that your action should simply be stateless (action.setNoState()). Did you try this?

Ghost_of_Magellan
Full Member
Posts: 58
Joined: Wed Mar 16, 2016 5:10 pm

Re: How to Call Save function on my Script?

Post by Ghost_of_Magellan » Mon May 30, 2016 11:00 am

I have tried it. But though the tool is not activated anymore, it still requires the Esc or right click button for me to be able to select entities or finish the save when I call the app.

Also (and this is likely unrelated to the setNOState), the function works. but only once. Because when I try to make a second save, the program stops working.
It is similar to what happened to the applyOperation function. every time I had to apply it, I also had to refresh the variables that held the doc interface.

Here however, I can't put the var self = this; inside the button call, because I'll get the "Uncaught exception at scripts/IuSYS/FirstWidget/FirstWidget.js:1358: TypeError: Result of expression 'self.getDocumentInterface' [undefined] is not a function." treatment.

Any ideas?

Thank you.
Last edited by Ghost_of_Magellan on Mon May 30, 2016 11:21 am, edited 2 times in total.

Post Reply

Return to “QCAD Programming, Script Programming and Contributing”