Triggering function on (before) document save

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.

Post Reply
mariosboarina
Junior Member
Posts: 19
Joined: Thu Nov 29, 2012 4:28 pm

Triggering function on (before) document save

Post by mariosboarina » Thu Mar 07, 2013 4:40 pm

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

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

Re: Triggering function on (before) document save

Post by andrew » Thu Mar 07, 2013 6:11 pm

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.

mariosboarina
Junior Member
Posts: 19
Joined: Thu Nov 29, 2012 4:28 pm

Re: Triggering function on (before) document save

Post by mariosboarina » Thu Mar 07, 2013 8:20 pm

Thank you! That's what I needed.
Also, this way I can do both pre and post operations.

mariosboarina
Junior Member
Posts: 19
Joined: Thu Nov 29, 2012 4:28 pm

Re: Triggering function on (before) document save

Post by mariosboarina » Mon Mar 11, 2013 9:11 pm

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).

Post Reply

Return to “QCAD Programming, Script Programming and Contributing”