Page 1 of 1

Triggering function on (before) document save

Posted: Thu Mar 07, 2013 4:40 pm
by mariosboarina
Hi,
I have some external data files which I'd like to keep updated accordingly to the drawing document. So I have to save them when the user saves the document, and make renamed copies when the user does a SaveAs.
I wouldn't modify original QCad scriptings and so I'm trying somehow to intercept Save and Save As guiActions, or documentInterface.exportFile() function. Or any other way to do the task. Without success.
Isn't there some saving-related event or signal accessible to which I could connect? Or some suggestion about this issue?

Thank you in advance.
Mario

Re: Triggering function on (before) document save

Posted: Thu Mar 07, 2013 6:11 pm
by andrew
Interesting problem. The idea with intercepting the guiAction is good but fails because you cannot force your slot to be triggered before the original slot. Slots are always triggered in the same order as signals were connected to them.

The best solution I can come up with is to do a proper inheritance and extend the existing Save class. The original guiAction can simply be removed from the menu and tool bar to avoid confusion and force the user to use our own implementation.

Here's a brief example class that inherits and extends the Save class. I called it ExBeforeSave and put it into scripts/Examples/IOExamples/ExBeforeSave, but it can be in any other location inside the scripts directory:

Code: Select all

include("../../../File/Save/Save.js");

function ExBeforeSave(guiAction) {
    Save.call(this, guiAction);
}

ExBeforeSave.prototype = new Save();

ExBeforeSave.prototype.beginEvent = function() {
    // Do something here before saving...
    // If file name returned by this.getDocument().getFileName() 
    // is empty at this point, the file has not been saved yet
    // and the user will be forwarded to 'save as' automatically.

    // Calling beginEvent of the original save class which does all the work:
    Save.prototype.beginEvent.call(this);
    this.terminate();
}

ExBeforeSave.init = function(basePath) {
    // Remove the original save action from the file menu and the file tool bar:
    var saveAction = RGuiAction.getByScriptFile("scripts/File/Save/Save.js");
    File.getMenu().removeAction(saveAction);
    File.getToolBar().removeAction(saveAction);

    // Create our own save action instead:
    var action = new RGuiAction(qsTranslate("Save", "&Save"), RMainWindowQt.getMainWindow());
    action.setRequiresDocument(true);
    action.setScriptFile(basePath + "/ExBeforeSave.js");
    action.setIcon("scripts/File/Save/Save.svg");
    action.setDefaultShortcut(new QKeySequence(QKeySequence.Save));
    action.setDefaultCommands(["save"]);
    action.setSortOrder(1000);
    action.setNoState();
    EAction.addGuiActionTo(action, File, true, true, false, false);
};
For the 'SaveAs' class, the same idea can be applied.

Re: Triggering function on (before) document save

Posted: Thu Mar 07, 2013 8:20 pm
by mariosboarina
Thank you! That's what I needed.
Also, this way I can do both pre and post operations.

Re: Triggering function on (before) document save

Posted: Mon Mar 11, 2013 9:11 pm
by mariosboarina
Yet one issue still stands: this way I can't intercept Save when it's not called from gui. One important case is when the user closes an unsaved drawing.
In this case the original Save is called, by mdiChild.closeRequested.connect().
This connection is established in NewFile class which is invocated in many non-gui places (beginning from autostart.js), so I think it's difficult to override it with a subclass of itself.
For now, I'm making a second connection to mdiChild.closeRequested: this is generally called after the NewFile one and so I do only post-saving operations (as a consequence I have to save the document a second time after doing my operations). It's the same situation as my first solution, with the same problems.
Anyway, at the moment it isn't so bad, being a real problem only in the very one case in which the user closes an unsaved doc and he wants to save it and the doc is a big one (if small, the double saving is unnoticed).