Scripting question, open template

Discussion forum for contributors and developers who are using the QCAD version 3 ECMAScript development platform or the C++ plugin interface or who are otherwise looking to contribute to QCAD (translations, documentation, etc).

Moderator: andrew

Scripting question, open template

Postby hungerburg » Thu Jun 16, 2011 8:38 pm

Before spending hours on what is bothering me now, I will just be bold and ask for a hint ;)

If in QCad2 I wanted to draw on a template, a single line of code was sufficient app.fileOpen("Vorlage.dxf");

I looked at the files in the script directory, there is of course a "load template" script. I wonder, how to wrap this into a function, that I can call in my own script as convenient as that one. Please share your ideas!

Regards

Peter
User avatar
hungerburg
Senior Member
 
Posts: 125
Joined: Fri May 28, 2010 7:35 pm

Postby andrew » Thu Jun 16, 2011 9:25 pm

Since a lot of the GUI part is implemented in ECMAScript (all MDI related things, how a document window looks like, scroll bars, rulers, etc.), you need to call that same script in order to get the same effect as when the user opens a file through the menu or tool button.

The script to open a file is located in scripts/File/Open/Open.js and can be used as follows in QCAD TP1:

Code: Select all
include("scripts/File/Open/Open.js");
...
var action = new Open();
action.openFile("Vorlage.dxf");
action.finishEvent();


You might want to create a wrapper function for this, so it can be easily ported if the script API changes for the final QCAD version. Class 'Open' will be called 'OpenFile' in the next QCAD release since we had some problems with class names like 'Open' or 'New'. So the code above will change for QCAD TP2 to:

Code: Select all
include("scripts/File/OpenFile/OpenFile.js");
...
var action = new OpenFile();
action.openFile("Vorlage.dxf");
action.finishEvent();
User avatar
andrew
Site Admin
 
Posts: 2590
Joined: Fri Mar 30, 2007 6:07 am

on the right track?

Postby hungerburg » Fri Jun 17, 2011 1:20 pm

I started with the wrapper. It currently looks like this:

Code: Select all
include("scripts/File/Open/Open.js"); // TP2 // include("scripts/File/OpenFile/OpenFile.js");

/**
 * Hilfsfunktion Vorlage öffnen, Namen der neuen Datei festlegen.
 * @constructor
 * @param {String} nameV Name/Pfad der Vorlage
 * @param {String} nameF Name/Pfad der neuen Datei
 */
function Vorlage(nameV, nameF) {
   this.openFile(nameV);
   this.finishEvent();
   this.document.setFileName(nameF);
   this.mdiChild.setWindowTitle(nameF);
}
Vorlage.prototype = new Open(); // TP2 // Vorlage.prototype = new OpenFile();


I can use it from my code like this:

Code: Select all
var Zeichnung = new Vorlage("Vorlage.dxf", "Zeichnung");
debugger; // inspect this

var operation = new RAddObjectsOperation(false);
var r = 10;
var off = 2 * Math.PI / 2000;
var c = 0;
for ( var a = 0.0; a < 2 * Math.PI; a += off) {
   var lineData = new RLineData(
      new RVector(Math.cos(a)*r, Math.sin(a)*r, 0),
      new RVector(Math.cos(a + off) * r, Math.sin(a + off) * r, 0)
   );
   var line = new RLineEntity(Zeichnung.document, lineData);
   operation.addObject(line);
   ++c;
}

Zeichnung.documentInterface.applyOperation(operation);


The drawing functions are taken from simple.js in the samples directory. Notice that "new RLineEntity()" takes two parameters, unlike in the example.

Am I on the right track?
User avatar
hungerburg
Senior Member
 
Posts: 125
Joined: Fri May 28, 2010 7:35 pm

Postby andrew » Fri Jun 17, 2011 1:33 pm

Yes, that looks good.

A small detail: we always start class names with a capital letter and variable names with a small letter (e.g. 'var zeichnung = new Vorlage(...)').
User avatar
andrew
Site Admin
 
Posts: 2590
Joined: Fri Mar 30, 2007 6:07 am

Start from "New()"

Postby hungerburg » Fri Jun 17, 2011 2:11 pm

Will it be better to start from "New()" ?

Code: Select all
include("scripts/File/New/New.js"); // TP2 // include("scripts/File/NewFile/NewFile.js");

/**
 * Hilfsfunktion Vorlage öffnen, Namen der neuen Datei festlegen.
 * @constructor
 * @param {String} template Name/Pfad zur Vorlage
 * @param {String} path Pfad der neuen Datei
 * @param {String} name Name der neuen Datei
 */
function Vorlage(template, path, name) {
   New.prototype.beginEvent.call(this, false);
   if (this.documentInterface.importFile(template) != RDocumentInterface.IoErrorNoError) {
      var dlg = new QMessageBox(QMessageBox.Warning,
                          "Vorlage nicht gefunden",
                          "Vorlage nicht gefunden\n\n'%1'\n".arg(template),
                          QMessageBox.OK);
      dlg.exec();
      this.terminate();
      return;
   }
   this.documentInterface.regenerateScenes();
   this.documentInterface.autoZoom();
   this.document.setFileName(path + "/" + name);
   this.mdiChild.setWindowTitle(name);
}
Vorlage.prototype = new New(); // TP2 // Vorlage.prototype = new NewFile();


When inspecting in the debugger I see that the object created from "Vorlage()" is of type "ActionAdaptor" - will that make problems?

(Peter Happy Hacking :)
User avatar
hungerburg
Senior Member
 
Posts: 125
Joined: Fri May 28, 2010 7:35 pm

Re: Start from "New()"

Postby andrew » Fri Jun 17, 2011 4:01 pm

hungerburg wrote:Will it be better to start from "New()" ?


In my opinion, both solutions are equally good. Opening a template is indeed somewhere between New and Open.

hungerburg wrote:When inspecting in the debugger I see that the object created from "Vorlage()" is of type "ActionAdaptor"


This is normal for all actions (tools). The complete inheritance hierarchy is:

Code: Select all
RAction
RActionAdapter
EAction
New
Vorlage


The debugger calls the toString() function to display information about an object. toString() is implemented for all C++ class wrappers (classes starting with an R) to return the class name. Of course, you can also overwrite toString for your ECMAScript class, for example:

Code: Select all
Vorlage.prototype.toString = function() {
   return 'Vorlage';
}


The debugger will then identify objects of that class with 'Vorlage'.
User avatar
andrew
Site Admin
 
Posts: 2590
Joined: Fri Mar 30, 2007 6:07 am

save template

Postby hungerburg » Fri Jun 17, 2011 6:42 pm

Thank you Andrew for your attentiveness. Slowly I am getting the knack:

Code: Select all
Vorlage.prototype.save = function() {
    return new Save().save(this.document.getFileName());
}


Will save the file. Can I depend upon it, that this will be dxf? Is this determined by extension?
User avatar
hungerburg
Senior Member
 
Posts: 125
Joined: Fri May 28, 2010 7:35 pm

Re: Scripting question, open template

Postby hungerburg » Wed Aug 29, 2012 8:53 am

Sorry for waking up this old thread. Yet, the method in here, to programmatically open a template and use it as a base for further scripted drawing, got broken between release candidate 5 and qcad 3 final.

Code: Select all
NewFile.prototype.beginEvent.call(this, false);

will no longer stuff the callers "this" with all the "documentInterface", "mdiChild" etc. properties.

As NewFile does quite a lot of initializations, I hesitate to reproduce all of its functionality in my own code, and would like to "inherit" again most of that.

Please advise, how in qcad 3, to open a template programmatically.

Thank You

Peter
User avatar
hungerburg
Senior Member
 
Posts: 125
Joined: Fri May 28, 2010 7:35 pm

Re: Scripting question, open template

Postby hungerburg » Wed Aug 29, 2012 9:56 am

Got it sorted out by looking at "NewFromTemplate":

Code: Select all
NewFile.createMdiChild();
this.documentInterface = EAction.getDocumentInterface();
this.document = EAction.getDocument();

in place of "NewFile.prototype.beginEvent.call(this, false);" seems to do what I want.

Though I do not understand, why this works without passing some handles, it works flawlessly, creating several tabs in sequence, even from the same template.

--
Peter
User avatar
hungerburg
Senior Member
 
Posts: 125
Joined: Fri May 28, 2010 7:35 pm


Return to QCAD 3 Developers and Contributors

Who is online

Users browsing this forum: No registered users and 1 guest

cron