prikhi / pencil

DEPRECATED: Multiplatform GUI Prototyping/Wireframing
https://github.com/evolus/pencil
GNU General Public License v2.0
1.92k stars 193 forks source link

No data input when exporting a page #696

Open steroides opened 9 years ago

steroides commented 9 years ago

Hi,

I'm currently working on developping new stencils and xsl templates in order to extract those stencils in HTML/CSS/JS. What I am doing is that I am saving my work in a .ep file and I then copy/paste the code in a tool like "Oxygen XML Editor" which can do the xsl transformation with my template.

Until now, things are going well but I would like to do the same, simply by cliking on the "Export document" button in Pencil. So, I did my own "Pencil extraction template", based on their "Html export template" model - I just changed the "StyleSheet.xslt" file, putting my xsl in it - .

Unfortunately, it seems that the datas given in input to my xsl file via the "Export document" way are not the same as those saved in the .ep file. More precisely, it's like all the content is missing (the xsl doesn't match for svg:g but it matches for p:Page, for example).

Finally, my question are:

Here is an example of xsl I use:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
     xmlns:p="http://www.evolus.vn/Namespace/Pencil"
     xmlns:html="http://www.w3.org/1999/xhtml"
     xmlns:svg="http://www.w3.org/2000/svg"
     xmlns="http://www.w3.org/1999/xhtml">

<xsl:output 
    method="html"
    encoding="UTF-8"
    doctype-public="-//W3C//DTD HTML 4.01//EN"
    doctype-system="http://www.w3.org/TR/html4/strict.dtd"
    indent="yes"/>

<!-- Global variables -->
<xsl:variable name="nomCollection">collectionTest</xsl:variable>

<!-- Basic match -->
<xsl:template match="/">
    <html>
        <head>
            <title><xsl:value-of select="/p:Document/p:Properties/p:Property[@name='fileName']/text()"/></title>
            <!-- Css -->
            <!-- Bootstrap -->
            <xsl:text>&#xA;</xsl:text>
            <xsl:comment> Bootstrap </xsl:comment>
            <link href="css/bootstrapv311/css/bootstrap.min.css" rel="stylesheet" />

           <!-- etc... Css and js load here ... -->
        </head>

        <body>                  
            <div id="page">
                <div id="content">
                    <xsl:apply-templates select="/p:Document/p:Pages/p:Page" />
                </div>
            </div>
        </body>
    </html>        
</xsl:template>

<!-- Page treatments -->
<xsl:template match="p:Page">
    <xsl:apply-templates select="p:Content/svg:g" />
</xsl:template>

<!-- Content treatments -->
<xsl:template match="svg:g">
    <xsl:param name="css"></xsl:param>

    <xsl:choose>

        <!-- Really simple exemple with an Hello World element --> 
        <xsl:when test="@p:def = concat($nomCollection, ':', 'helloworld')">

            <!-- Get coords from the matrice -->
            <xsl:variable name="coord_x" select="html:getCoordX(@transform)"/>
            <xsl:variable name="coord_y" select="html:getCoordY(@transform)"/>

            <!-- Construct element style -->
            <xsl:variable name="style" select="concat('color', substring-after(concat(svg:text/@style, ' position: absolute; left: ', $coord_x, 'px; top: ', $coord_y, 'px;'), 'fill'))"/>

            <!-- Construct Hello World element-->
            <p class="bdf_HelloWorld" style="{$style}"><xsl:value-of select="svg:text"/></p>      
        </xsl:when>

        <xsl:otherwise/>
    </xsl:choose>

</xsl:template>

</xsl:stylesheet>
amarach78 commented 9 years ago

Could this have anything to do with #559 ?

steroides commented 9 years ago

Possibly,yes. I don't know how the PDF template works.

Anyway, I solved it, changing some code in the controller.js (Pencil\app\content\pencil\common\controller.js). I just put to false booleans or conditions relative to the "rasterize" part since I'm not intersted in it.

Here is my new controller.js for those who are interested:


function Controller(win) {
    this.window = win;
    this.doc = null;
    this.modified = false;
    this.mainView = this.window.ownerDocument.getElementById("mainView");
    this.mainViewHeader = this.window.ownerDocument.getElementById("mainViewHeader");
    this.mainViewPanel = this.window.ownerDocument.getElementById("mainViewPanel");
    this.pagePropertiesMenuItem = this.window.ownerDocument.getElementById("pagePropertiesMenuItem");
    this.pageNoteMenuItem = this.window.ownerDocument.getElementById("pageNoteMenuItem");
    this.deletePageMenuItem = this.window.ownerDocument.getElementById("deletePageMenuItem");
    this.pageMoveLeftMenuItem = this.window.ownerDocument.getElementById("pageMoveLeftMenuItem");
    this.pageMoveRightMenuItem = this.window.ownerDocument.getElementById("pageMoveRightMenuItem");
    this.pageDuplicateMenuItem = this.window.ownerDocument.getElementById("pageDuplicateMenuItem");
    this.tabPopupMenu = this.window.ownerDocument.getElementById("pageTabContextMenu");
    this.gotoTabMenu = this.window.ownerDocument.getElementById("gotoTabMenu");
    var tabScrollBox = this.window.ownerDocument.getElementById("tabScrollBox");
    this.tabScrollBox = tabScrollBox;
    var thiz = this;
    this.mainViewHeader.addEventListener("select", function (event) {
        var currentPage = thiz.getCurrentPage();
        var canvas = currentPage._view.canvas;
        try {
            currentPage.ensureBackground();
        } catch (e) {
        }
        if (!canvas) return;
        Dom.emitEvent("p:CanvasChanged", thiz.mainViewHeader, {canvas: canvas});
    }, false);
    this.mainViewHeader.addEventListener("dblclick", function (event) {
        var page = thiz.getCurrentPage();
        if (!page) return;
        thiz.editPageProperties(page);
    }, false);
    this.mainView.addEventListener("p:ContentModified", function (event) {
        thiz.markDocumentModified();
    }, false);
    tabScrollBox.addEventListener("contextmenu", function (event) {
        thiz._handleContextMenuShow(event);
    }, false);
    this.pagePropertiesMenuItem.addEventListener("command", function (event) {
        if (thiz._pageToEdit) {
            thiz.editPageProperties(thiz._pageToEdit);
            thiz._pageToEdit = null;
        }
    }, false);
    this.pageNoteMenuItem.addEventListener("command", function (event) {
        if (thiz._pageToEdit) {
            thiz.editPageNote(thiz._pageToEdit);
        }
    }, false);
    this.gotoTabMenu.addEventListener("command", function (event) {
        var item = Dom.findUpward(event.originalTarget, function(node) {
            return node._page;
        });
        if (!item) return;
        thiz.gotoPage(item._page);
    }, false);
    this.deletePageMenuItem.addEventListener("command", function (event) {
        if (thiz._pageToEdit) {
            if (confirm(Util.getMessage("are.you.sure.delete.page"))) {
                try {
                    thiz._deletePage(thiz._pageToEdit);
                } catch (e) {
                    Console.dumpError(e);
                }
                thiz._pageToEdit = null;
            }
        }
    }, false);
}
Controller.PAGES_SUBFOLDER_NAME = "pages";
Controller.prototype._movePage = function (index, forward) {
    debug("Moving: " + [index, forward]);
    try {
        if (index < 0 || index >= this.doc.pages.length) return;
        var otherIndex = index + (forward ? 1 : -1);
        if (otherIndex < 0 || otherIndex >= this.doc.pages.length) return;
        var page = this.doc.pages[index];
        var otherPage = this.doc.pages[otherIndex];
        if (!page || !otherPage) return;
        debug("swapping: " + [index, otherIndex]);
        this.doc.pages[index] = otherPage;
        this.doc.pages[otherIndex] = page;
        this._updatePageFromView();
        this._clearView();
        this._pageSetupCount = 0;
        var thiz = this;
        this.markDocumentModified();
        for (p in this.doc.pages) {
            this._createPageView(this.doc.pages[p], function () {
                thiz._pageSetupCount ++;
                if (thiz._pageSetupCount == thiz.doc.pages.length) {
                    thiz._ensureAllBackgrounds(function () {});
                }
            });
            this._setSelectedPageIndex(otherIndex);
        }
    } catch (e) {
        Console.dumpError(e);
    }
};
Controller.prototype._findPageToEditIndex = function () {
    for (var i = 0; i < this.doc.pages.length; i ++) {
        if (this._pageToEdit == this.doc.pages[i]) {
            return i;
            break;
        }
    }
    return -1;
}
Controller.prototype.pageMoveRight = function () {
    var pageIndex = this._findPageToEditIndex();
    if (pageIndex < 0) return;
    this._movePage(pageIndex, true);
}
Controller.prototype.pageMoveLeft = function () {
    var pageIndex = this._findPageToEditIndex();
    if (pageIndex < 0) return;
    this._movePage(pageIndex, false);
}
Controller.prototype.gotoPage = function (page) {
    var tab = page._view.header;
    this.mainView.selectedTab = tab;
    this.tabScrollBox.ensureElementIsVisible(tab);
}
Controller.prototype.markDocumentModified = function () {
    this.modified = true;
    this._setupTitle();
}
Controller.prototype.markDocumentSaved = function () {
    this.modified = false;
    this._setupTitle();
}
Controller.prototype._setupTitle = function () {
    var path = this.filePath ? this.filePath : Util.getMessage("untitled.document");
    var title = this.modified ? (path + "*") : path;
    Pencil.setTitle(title);
};
Controller.prototype.hasDoc = function () {
    return this.doc ? true : false;
};
Controller.prototype.getCurrentPage = function () {
    if (!this.doc) throw Util.getMessage("no.active.document");
    return this.doc.pages[this.mainView.selectedIndex];
};
Controller.prototype.isBoundToFile = function () {
    if (!this.doc) throw Util.getMessage("no.document.is.attached.to.this.controller");
    return this.filePath != null;
};
var SIZE_RE = /^([0-9]+)x([0-9]+)$/;
Controller.prototype.parseSizeText = function (text) {
    if (!text.match(SIZE_RE)) {
        return null;
    }
    return {
        width: parseInt(RegExp.$1, 10),
        height: parseInt(RegExp.$2, 10)
    };
};
Controller.prototype.newDocument = function () {
    if (this.modified) {
        if (!this._confirmAndSaveDocument()) return;
    }
    this._clearView();
    //TODO: asking for params
    this.doc = new PencilDocument();
    var size = null;
    var lastSize = Config.get("lastSize");
    debug("lastSize: " + lastSize);
    if (lastSize) {
        size = this.parseSizeText(lastSize);
    }

    debug("lastSize: " + Pencil.getBestFitSize());
    if (size == null) {
        size = this.parseSizeText(Pencil.getBestFitSize());
    }
    this._addPage(Util.getMessage("untitled.page"), this._generateId(), size.width, size.height);

    this._setSelectedPageIndex(0);
    this.filePath = null;
    this.modified = false;
    this._setupTitle();
};
Controller.prototype.duplicatePage = function () {
    var page = this.getCurrentPage();
    var name = page.properties.name;
    var width = page.properties.width;
    var height = page.properties.height;
    var background = page.properties.background;
    var dimBackground = page.properties.dimBackground;
    var backgroundColor = page.properties.backgroundColor;
    var transparentBackground = page.properties.transparentBackground;
    var id = this._generateId();
    this._addPage(name, id, width, height, background, dimBackground, backgroundColor, transparentBackground);
    this._setSelectedPageIndex(this.doc.pages.length - 1);
    var newPage = this.doc.pages[this.doc.pages.length-1];
    for (var i = 0; i < page._view.canvas.drawingLayer.childNodes.length; i ++) {
        var node = page._view.canvas.drawingLayer.childNodes[i];
        newPage._view.canvas.drawingLayer.appendChild(newPage._view.canvas.ownerDocument.importNode(node, true));
        Dom.renewId(node);
    }
    this.markDocumentModified();
};
Controller.prototype.newPage = function () {
    var returnValueHolder = {};
    var dialog = window.openDialog("chrome://pencil/content/pageDetailDialog.xul", "pageDetailDialog", "modal,centerscreen",
                                    null,
                                    this.doc.pages,
                                    returnValueHolder);
    if (!returnValueHolder.ok)  return;
    var name = returnValueHolder.data.title;
    var width = returnValueHolder.data.width;
    var height = returnValueHolder.data.height;
    var background = returnValueHolder.data.background ? returnValueHolder.data.background : null;
    var dimBackground = returnValueHolder.data.dimBackground ? true : false;
    var backgroundColor = returnValueHolder.data.backgroundColor ? returnValueHolder.data.backgroundColor : "#ffffff";
    var transparentBackground = returnValueHolder.data.transparentBackground == "false" ? "false" : "true";
    var id = this._generateId();
    this._addPage(name, id, width, height, background, dimBackground, backgroundColor, transparentBackground);
    this._setSelectedPageIndex(this.doc.pages.length - 1);
    this.markDocumentModified();
};
Controller.prototype.saveDocumentAs = function () {
    this.saveDocument(true);
}
Controller.prototype.saveDocument = function (saveAsArg) {
    var currentPath = this.filePath ? this.filePath : null;
    var saveAs = saveAsArg ? saveAsArg : false;
    try {
        this._updatePageFromView();
        if (!this.isBoundToFile() || saveAs) {
            var nsIFilePicker = Components.interfaces.nsIFilePicker;
            var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
            fp.init(window, Util.getMessage("filepicker.save.document.as"), nsIFilePicker.modeSave);
            fp.appendFilter(Util.getMessage("filepicker.pencil.documents"), "*.ep; *.epz");
            fp.appendFilter(Util.getMessage("filepicker.all.files"), "*");
            if (fp.show() == nsIFilePicker.returnCancel) return false;
            this.filePath = fp.file.path;
            if (!this.filePath.match(/\.ep[z]?$/)) {
                this.filePath += ".ep";
                //FIXME: check existing once again
            }
            try {
                //new file was saved, update recent file list
                var files = Config.get("recent-documents");
                if (!files) {
                    files = [this.filePath];
                } else {
                    for (var i = 0; i < files.length; i ++) {
                        if (files[i] == this.filePath) {
                            //remove it
                            files.splice(i, 1);
                            break;
                        }
                    }
                    files.unshift(this.filePath);
                    if (files.length > 10) {
                        files.splice(files.length - 1, 1);
                    }
                }
                Config.set("recent-documents", files);
                Pencil.buildRecentFileMenu();
            } catch (e) {
                Console.dumpError(e, true);
            }
        }
        XMLDocumentPersister.save(this.doc, this.filePath);
        Pencil.setTitle(this.filePath);
        this.markDocumentSaved();
    } catch (e) {
        Util.info(Util.getMessage("error.saving.file"), "" + e);
        this.filePath = currentPath;
        return false;
    }
    return true;
};
Controller.prototype.loadDocument = function (uri) {
    if (this.modified) {
        if (!this._confirmAndSaveDocument()) return;
    }
    var file = null;
    if (!uri) {
        var nsIFilePicker = Components.interfaces.nsIFilePicker;
        var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
        fp.init(window, Util.getMessage("filepicker.open.document"), nsIFilePicker.modeOpen);
        fp.appendFilter(Util.getMessage("filepicker.pencil.documents"), "*.ep; *.epz");
        fp.appendFilter(Util.getMessage("filepicker.all.files"), "*");
        if (fp.show() != nsIFilePicker.returnOK) return;
        file = fp.file;
    } else {
        try {
            if (uri.indexOf("-") == 0) return;
            //assume uri is a nsILocalFile
            file = uri.QueryInterface(Components.interfaces.nsILocalFile);
        } catch (e1) {
            try {//
                //assume uri is an absolute path
                file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
                file.initWithPath("" + uri);
            } catch (e){
                try {
                    //assume uri is a real uri
                    file = fileHandler.getFileFromURLSpec(uri).QueryInterface(Components.interfaces.nsILocalFile);
                } catch(e) {
                    Console.dumpError(e);
                }
            }
        }
        if (!file.exists()) {
            Util.error(Util.getMessage("error.title"), Util.getMessage("file.not.exist", file.path), Util.getMessage("button.cancel.close"));
            //alert("The file '" + file.path + "' does not exist");
            return;
        }
    }
    var path = file.path;
    try {
        //new file was loaded, update recent file list
        var files = Config.get("recent-documents");
        if (!files) {
            files = [path];
        } else {
            for (var i = 0; i < files.length; i ++) {
                if (files[i] == path) {
                    //remove it
                    files.splice(i, 1);
                    break;
                }
            }
            files.unshift(path);
            if (files.length > 10) {
                files.splice(files.length - 1, 1);
            }
        }
        Config.set("recent-documents", files);
        Pencil.buildRecentFileMenu();
    } catch (e) {
        Console.dumpError(e, true);
    }
    this._loadDocumentImpl(file, path);
}
Controller.prototype._loadDocumentImpl = function (file, path) {
    var thiz = this;
    var starter = function (listener) {
        thiz._clearView();
        document.documentElement.setAttribute("wait-cursor", true);
        try {
            thiz.doc = XMLDocumentPersister.load(file);
        } catch (e) {
            Console.dumpError(e);
            document.documentElement.removeAttribute("wait-cursor");
            Util.error(Util.getMessage("could.not.load.document"), e.message, Util.getMessage("button.cancel.close"));
            return;
        }
        thiz._pageSetupCount = 0;
        var p = -1;
        function loadPage() {
            p++;
            try {
                listener.onProgressUpdated(Util.getMessage("loading.page", thiz.doc.pages[p].properties.name), thiz._pageSetupCount + 1, thiz.doc.pages.length);
                thiz._createPageView(thiz.doc.pages[p], function () {
                    thiz._pageSetupCount ++;
                    if (thiz._pageSetupCount == thiz.doc.pages.length) {
                        listener.onProgressUpdated(Util.getMessage("loading.background"), thiz._pageSetupCount + 1, thiz.doc.pages.length);
                        thiz._ensureAllBackgrounds(function () {
                            thiz._setSelectedPageIndex(0);
                            thiz.filePath = path;
                            Pencil.setTitle(thiz.filePath);
                            thiz.markDocumentSaved();
                            document.documentElement.removeAttribute("wait-cursor");
                            listener.onTaskDone();
                        });
                        return true;
                    }
                    window.setTimeout(loadPage, 10);
                });
            } catch (ex) {
                document.documentElement.removeAttribute("wait-cursor");
                listener.onTaskDone();
                Util.error(Util.getMessage("error.title"), ex.message, Util.getMessage("button.cancel.close"));
            }
        }
        loadPage();
    }
    Util.beginProgressJob(Util.getMessage("loading.document"), starter);
};
//---------------------- privates -----
Controller.prototype._ensureAllBackgrounds = function (callback) {
    this._ensureBackground(0, callback);
};
Controller.prototype._ensureBackground = function (index, callback) {
    if (index >= this.doc.pages.length) {
        if (callback) callback();
        return;
    }
    var page = this.doc.pages[index];
    var thiz = this;
    page.ensureBackground(function () {
        thiz._ensureBackground(index + 1, callback);
    });
}
Controller.prototype._updatePageFromView = function () {
    if (!this.doc) throw Util.getMessage("no.active.document");
    for (p in this.doc.pages) {
        var page = this.doc.pages[p];
        var drawingLayer = page._view.canvas.drawingLayer;
        page.contentNode = drawingLayer;
    }
}
Controller.prototype._generateId = function () {
    return (new Date().getTime()) + "_" + Math.round(Math.random() * 10000);
};
Controller.prototype._addPage = function (name, id, width, height, background, dimBackground, backgroundColor, transparentBackground, note) {
    var page = new Page(this.doc);
    page.properties.name = name;
    page.properties.id = id;
    page.properties.width = width;
    page.properties.height = height;
    page.properties.dimBackground = false;
    page.properties.transparentBackground = transparentBackground;
    if (backgroundColor) {
        page.properties.backgroundColor = backgroundColor;
    } else {
        page.properties.backgroundColor = "#ffffff";
    }
    if (background) {
        page.properties.background = background;
        page.properties.dimBackground = dimBackground;
    }
    if(note) {
        page.properties.note = note;
    }
    this.doc.addPage(page);
    page._doc = this.doc;
    this._createPageView(page, function () {
        page.ensureBackground();
    });
};
Controller.prototype._createPageView = function (page, callback) {
    var tab = this.window.ownerDocument.createElementNS(PencilNamespaces.xul, "tab");
    this.mainViewHeader.appendChild(tab);
    tab._page = page;
    tab.setAttribute("label", page.properties.name);
    var tabpanel = this.window.ownerDocument.createElementNS(PencilNamespaces.xul, "tabpanel");
    this.mainViewPanel.appendChild(tabpanel);
    var vbox = this.window.ownerDocument.createElementNS(PencilNamespaces.xul, "vbox");
    tabpanel.appendChild(vbox);
    var canvas = this.window.ownerDocument.createElementNS(PencilNamespaces.xul, "pcanvas");
    canvas.setAttribute("flex", 1);
    canvas.setAttribute("width", parseInt(page.properties.width, 10));
    canvas.setAttribute("height", parseInt(page.properties.height, 10));
    vbox.appendChild(canvas);
    var view = {header: tab, body: tabpanel, canvas: canvas};
    page._view = view;
    tabpanel._canvas = canvas;
    window.setTimeout(function () {
        Pencil.installEditors(canvas);
        Pencil.installXferHelpers(canvas);
        Pencil.installDragObservers(canvas);
        if (page.contentNode) {
            for (var i = 0; i < page.contentNode.childNodes.length; i ++) {
                var node = page.contentNode.childNodes[i];
                canvas.drawingLayer.appendChild(canvas.ownerDocument.importNode(node, true));
            }
        }
        canvas.careTaker.reset();
        canvas.addEventListener("p:ContentModified", function (event) {
            page.rasterizeDataCache = null;
        }, false);
        if (page.properties.transparentBackground == "true" || page.properties.background) {
            canvas.setBackgroundColor(Color.fromString("#ffffffff"));
        } else {
            canvas.setBackgroundColor(Color.fromString(page.properties.backgroundColor));
        }
        canvas.snappingHelper.rebuildSnappingGuide();
        if (callback) callback();
    }, 200);
};
Controller.prototype._setSelectedPageIndex = function (index) {
    this.mainView.selectedIndex = index;
};
Controller.prototype._clearView = function () {
    if (this.doc) {
        for (p in this.doc.pages) {
            var page = this.doc.pages[p];
            page._view.canvas.passivateEditors();
        }
    }
    Dom.empty(this.mainViewHeader);
    Dom.empty(this.mainViewPanel);
};
Controller.prototype._handleContextMenuShow = function (event) {
    var tab = Dom.findTop(event.originalTarget, function (node) {
        return node.localName == "tab";
    });
    Dom.workOn("./xul:menuseparator", this.tabPopupMenu, function (sep) {
        sep.style.display = "";
    });
    if (tab) {
        this.pagePropertiesMenuItem.style.display = "";
        this.pageNoteMenuItem.style.display = "";
        this.deletePageMenuItem.style.display = "";
        this.pageDuplicateMenuItem.style.display = "";
        this.pageMoveLeftMenuItem.style.display = "";
        this.pageMoveRightMenuItem.style.display = "";
        this._pageToEdit = tab._page;
        var index = this._findPageToEditIndex(this._pageToEdit);
        Pencil._enableCommand("moveLeftCommand", index > 0);
        Pencil._enableCommand("moveRightCommand", index < this.doc.pages.length - 1);
    } else {
        this.pagePropertiesMenuItem.style.display = "none";
        this.pageNoteMenuItem.style.display = "none";
        this.deletePageMenuItem.style.display = "none";
        this.pageDuplicateMenuItem.style.display = "none";
        this.pageMoveLeftMenuItem.style.display = "none";
        this.pageMoveRightMenuItem.style.display = "none";
        this._pageToEdit = null;
    }
    //setup goto tab menu
    var popup = this.gotoTabMenu.firstChild;
    Dom.empty(popup);
    if (this.doc.pages.length < 2) {
        this.gotoTabMenu.disabled = true;
    } else {
        this.gotoTabMenu.disabled = false;
        for (var i = 0; i < this.doc.pages.length; i ++) {
            var page = this.doc.pages[i];
            var item = popup.ownerDocument.createElementNS(PencilNamespaces.xul, "menuitem");
            item.setAttribute("label", page.properties.name);
            item._page = page;
            popup.appendChild(item);
        }
    }
    var childs = this.tabPopupMenu.childNodes;
    var shouldHideNextSeparator = true;
    for (var i = 0; i < childs.length; i ++) {
        var child = childs[i];
        if (child.localName == "menuseparator") {
            if (shouldHideNextSeparator) {
                child.style.display = "none";
            } else {
                shouldHideNextSeparator = true;
            }
        } else {
            if (child.style.display != "none") {
                shouldHideNextSeparator = false;
            }
        }
    }
    for (var i = childs.length - 1; i >= 0; i --) {
        var child = childs[i];
        if (child.localName != "menuseparator" && child.style.display != "none") {
            break;
        }
        child.style.display = "none";
    }
};
Controller.prototype._modifyPageProperties = function (page, data) {
    if (!page._view) return;
    page.properties.name = data.title;
    page.properties.width = data.width;
    page.properties.height = data.height;
    page.properties.dimBackground = data.dimBackground;
    page.properties.backgroundColor = data.backgroundColor;
    page.properties.transparentBackground = data.transparentBackground;
    if (data.background) {
        page.properties.background = data.background;
    } else {
        try {
            delete page.properties.background;
        } catch (e) {}
    }
    page._view.header.setAttribute("label", data.title);
    try {
        this.mainViewPanel.setAttributeNS(PencilNamespaces.p, "p:resizing", "true");
        page._view.canvas.setSize(data.width, data.height);
        if (page.properties.transparentBackground == "true" || page.properties.background) {
            page._view.canvas.setBackgroundColor(Color.fromString("#ffffffff"));
        } else {
            page._view.canvas.setBackgroundColor(Color.fromString(page.properties.backgroundColor));
        }
        this.mainViewPanel.removeAttributeNS(PencilNamespaces.p, "resizing");
    } catch (e) {
        Console.dumpError(e, "Error");
    }
    page.rasterizeDataCache = null;
    this.markDocumentModified();
};
Controller.prototype._deletePage = function (page) {
    //find page in the list
    var currentIndex = this.mainView.selectedIndex;
    var index = -1;
    for (var i = 0; i < this.doc.pages.length; i ++) {
        if (this.doc.pages[i].properties.id == page.properties.id) {
            index = i;
            break;
        }
    }
    if (index < 0) return;
    //remove UI
    page._view.header.parentNode.removeChild(page._view.header);
    page._view.body.parentNode.removeChild(page._view.body);
    //remove the page
    delete this.doc.pages[index];
    for (var i = index; i < this.doc.pages.length - 1; i ++) {
        this.doc.pages[i] = this.doc.pages[i + 1];
    }
    this.doc.pages.length --;
    for (var i in this.doc.pages) {
        var page = this.doc.pages[i];
        if (page.properties.background && !page.getBackgroundPage()) {
            delete page.properties.background;
        }
    }
    this._ensureAllBackgrounds();
    if (index == currentIndex && this.doc.pages.length > 0) {
        this._setSelectedPageIndex(Math.min(index, this.doc.pages.length - 1));
    } else if (index < currentIndex) {
        this._setSelectedPageIndex(currentIndex - 1);
    }
};
Controller.prototype._confirmAndSaveDocument = function () {
    var result = Util.confirmExtra(Util.getMessage("save.changes.to.document.before.closing"),
                                    Util.getMessage("changes.will.be.permanently.lost"),
                                    Util.getMessage("button.save.label"), Util.getMessage("button.discard.changes"), Util.getMessage("button.cancel.label"));
    if (result.extra) return true;
    if (result.cancel) return false;
    return this.saveDocument();
};
Controller.prototype.editPageProperties = function (page) {
    if (!page) return;
    var returnValueHolder = {};
    var possibleBackgroundPages = [];
    for (var i in this.doc.pages) {
        var bgPage = this.doc.pages[i];
        if (page.canSetBackgroundTo(bgPage)) {
            possibleBackgroundPages.push(bgPage);
        }
    }
    var currentData = {title: page.properties.name,
                         id: page.properties.id,
                         width: page.properties.width,
                         height: page.properties.height,
                         backgroundColor: page.properties.backgroundColor ? page.properties.backgroundColor : null,
                         transparentBackground: page.properties.transparentBackground == "false" ? "false" : "true",
                         background: page.properties.background ? page.properties.background : null,
                         dimBackground: page.properties.dimBackground};
    var dialog = window.openDialog("chrome://pencil/content/pageDetailDialog.xul",
                                    "pageDetailDialog" + Util.getInstanceToken(),
                                    "modal,centerscreen",
                                    currentData, possibleBackgroundPages, returnValueHolder);
    if (!returnValueHolder.ok)  return;
    //change page now:
    try {
        this._modifyPageProperties(page, returnValueHolder.data);
        this._ensureAllBackgrounds(null);
    } catch (e) {
        Console.dumpError(e);
    }
};
Controller.prototype.editPageNote = function (page) {
    var returnValueHolder = {};
    var currentData = {value : page.properties.note ? page.properties.note : ""};
    var returnValueHolder = {};
    var dialog = window.openDialog("chrome://pencil/content/pageNoteDialog.xul", "PageNoteDialog" + Util.getInstanceToken(), "dialog=no,centerscreen,resizable,minimizable=yes,maximizable=yes,dependent, modal", currentData, returnValueHolder, page.properties.name);
    if (returnValueHolder.ok) {
        if (!page._view) return;
        page.properties.note = RichText.fromString(returnValueHolder.html);
        //debug("html " + returnValueHolder.html);
        //debug("RichText " + page.properties.note);
        this.markDocumentModified();
    }
};
Controller.prototype.rasterizeDocument = function () {
    try {
    var currentDir = null;
        if (this.isBoundToFile()) {
            var file = Components.classes["@mozilla.org/file/local;1"]
                                 .createInstance(Components.interfaces.nsILocalFile);
            file.initWithPath(this.filePath);
            currentDir = file.parent;
        }
        var nsIFilePicker = Components.interfaces.nsIFilePicker;
        var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
        if (currentDir) fp.displayDirectory = currentDir;
        fp.init(window, Util.getMessage("filepicker.export.all.pages.into"), nsIFilePicker.modeGetFolder);
        fp.appendFilter(Util.getMessage("filepicker.all.files"), "*");
        if (fp.show() == nsIFilePicker.returnCancel) return false;
        var pageIndex = -1;
        var dir = fp.file;
        debug("Selected folder: " + dir.path);
        var thiz = this;
        var starter = function (listener) {
            var rasterizeNext = function () {
                try {
                    pageIndex ++;
                    if (pageIndex >= thiz.doc.pages.length) {
                        listener.onTaskDone();
                        //Util.info("Document has been exported", "Location: " + dir.parent.path);
                        return;
                    }
                    var page = thiz.doc.pages[pageIndex];
                    if (Config.get("document.SaveWithPrefixNumber") == null){
                        Config.set("document.SaveWithPrefixNumber", false);
                    }
                    //signal progress
                    var withPrefix = Config.get("document.SaveWithPrefixNumber");
                    var task = "";
                    if (withPrefix) {
                        task = Util.getMessage("exporting.page.with.prefix", pageIndex + 1, page.properties.name);
                    } else {
                        task = Util.getMessage("exporting.page.no.prefix", page.properties.name);
                    }
                    listener.onProgressUpdated(task, pageIndex + 1, thiz.doc.pages.length);
                    if (pageIndex > 0) dir = dir.parent;
                    var fileName = "";
                    if (withPrefix) {
                        var fileName = (pageIndex + 1) + "_" + page.properties.name.replace(/[\/!\\'"]/g, "_");
                    } else {
                        var fileName = page.properties.name.replace(/[\/!\\'"]/g, "_");
                    }
                    dir.append(fileName + ".png");
                    var pagePath = dir.path;
                    debug("File path: " + pagePath);
                    thiz._rasterizePage(page, pagePath, function() {
                        window.setTimeout(rasterizeNext, 100);
                    });
                } catch (e2) {
                    Console.dumpError(e2, "stdout");
                }
            };
            rasterizeNext();
        }
        //take a shower, doit together!!!
        Util.beginProgressJob(Util.getMessage("export.document"), starter);
    } catch (e) {
        Console.dumpError(e, "stdout");
    }
};
Controller.prototype.printDocument = function () {
    this.exportDocument("PrintingExporter");
}
Controller.prototype.exportDocument = function (forcedExporterId) {
    var data = {
        lastSelection: this.lastSelection ? this.lastSelection : null,
        forcedExporterId: forcedExporterId ? forcedExporterId : null
    };
    window.openDialog("chrome://pencil/content/exportWizard.xul", "", "chrome,centerscreen,modal", data);
    if (!data.selection) return;
    this.lastSelection = data.selection;
    //Création des fichiers et du dossier de destination
    try {
        var exporter = Pencil.getDocumentExporterById(data.selection.exporterId);
        if (!exporter) return;
        //Select target dir
        var pageIndex = -1;
        var destFile = null;
        if (data.selection.targetPath) {
            destFile = Components.classes["@mozilla.org/file/local;1"]
                                 .createInstance(Components.interfaces.nsILocalFile);
            destFile.initWithPath(data.selection.targetPath);
            if (exporter.getOutputType() == BaseExporter.OUTPUT_TYPE_DIRECTORY) {
                if (!destFile.exists()) {
                    destFile.create(destFile.DIRECTORY_TYPE, 0777);
                }
            }
        }
        var pagesDir = null;

        //Ancien code: var requireRasterizedData = exporter.requireRasterizedData(data.selection);
        var requireRasterizedData = false; //Nouveau code; Pour la BDF, les captures d'écrans du workspace sont inutiles
        if (requireRasterizedData) {
            pagesDir = exporter.getRasterizedPageDestination(destFile);
            if (!pagesDir.exists()) {
                pagesDir.create(pagesDir.DIRECTORY_TYPE, 0777);
            }
        }
        //populating friendly-id. WARN: side-effect!
        var usedFriendlyIds = [];
        for (var i = 0; i < this.doc.pages.length; i ++) {
            var p = this.doc.pages[i];
            var fid = p.generateFriendlyId(usedFriendlyIds);
            p.properties.fid = fid;
        }

        this._updatePageFromView();
        var pages = [];
        pages = this.doc.pages;
        var thiz = this;
        var starter = null;
        var pageExtraInfos = {};
        starter = function (listener) {
            try {
                thiz._exportDocumentToXML(pages, pageExtraInfos, destFile, data.selection, function () {
                    listener.onTaskDone();
                    if (destFile) {
                        Util.showStatusBarInfo("Document has been exported, location: " + destFile.path, true);
                    } else {
                        Util.showStatusBarInfo("Document has been exported.", true);
                    }
                });
            } catch (ex) {
                listener.onTaskDone();
                Util.error(Util.getMessage("error.title"), ex.message, Util.getMessage("button.cancel.close"));
            }
        };
        //take a shower, doit together!!!
        Util.beginProgressJob(Util.getMessage("export.documents"), starter);
    } catch (e) {
        Console.dumpError(e, "stdout");
    }
};
Controller.prototype._getPageLinks = function (page, pageExtraInfos, includeBackground) {
    var bgLinks = [];
    if (page.properties.background && includeBackground) {
        var bgPage = this.doc.getPageById(page.properties.background);
        if (bgPage) {
            bgLinks = this._getPageLinks(bgPage, pageExtraInfos, true);
        }
    }
    var extra = null;
    if (pageExtraInfos[page.properties.id]) {
        extra = pageExtraInfos[page.properties.id];
    } else {
        // the current page is not processed for linking
        // this may because it is not included in exporting
        // so, do this manually here
        page._view.canvas.zoomTo(1);
        var node = page._view.canvas.drawingLayer;
        extra = {};
        var processor = new LinkingGeometryPreprocessor(extra);
        processor.process(node);
        pageExtraInfos[page.properties.id] = extra;
    }
    var thisPageLinks = extra.objectsWithLinking;
    var links = [];
    for (var j = 0; j < thisPageLinks.length; j ++) {
        links.push(thisPageLinks[j]);
    }
    for (var j = 0; j < bgLinks.length; j ++) {
        links.push(bgLinks[j]);
    }
    var validLinks = [];
    for (var j = 0; j < links.length; j ++) {
        var targetPage = this.doc.getPageById(links[j].pageId);
        if (targetPage) validLinks.push(links[j]);
    }
    //debug("Returning links for page: " + page.properties.fid + ", total: " + validLinks.length);
    return validLinks;
};
Controller.prototype.getFriendlyDocumentName = function () {
    if (!this.isBoundToFile()) return "Untitled Document";

    var epFile = Components.classes["@mozilla.org/file/local;1"]
                     .createInstance(Components.interfaces.nsILocalFile);
    epFile.initWithPath(this.filePath);
    var name = epFile.leafName;
    name = name.replace(/\.ep$/, "").replace(/([^ A-Z])([A-Z]+)/g, "$1 $2");
    return name;
};
Controller.prototype._exportDocumentToXML = function (pages, pageExtraInfos, destFile, exportSelection, callback) {
    var exporter = Pencil.getDocumentExporterById(exportSelection.exporterId);
    var dom = document.implementation.createDocument(PencilNamespaces.p, "Document", null);
    //properties
    var propertyContainerNode = dom.createElementNS(PencilNamespaces.p, "Properties");
    dom.documentElement.appendChild(propertyContainerNode);
    var docProperties = {};
    for (name in this.doc.properties) {
        docProperties[name] = this.doc.properties[name];
    }
    //enriching with additional properties
    var d = new Date();
    docProperties["exportTime"] = d;
    docProperties["exportTimeShort"] = "" + d.getFullYear() + (d.getMonth() + 1) + d.getDate();
    if (this.isBoundToFile()) {
        docProperties["path"] = this.filePath;
        var epFile = Components.classes["@mozilla.org/file/local;1"]
                             .createInstance(Components.interfaces.nsILocalFile);
        epFile.initWithPath(this.filePath);
        docProperties["fileName"] = epFile.leafName;
    }

    docProperties["friendlyName"] = this.getFriendlyDocumentName();
    for (name in docProperties) {
        var propertyNode = dom.createElementNS(PencilNamespaces.p, "Property");
        propertyContainerNode.appendChild(propertyNode);
        propertyNode.setAttribute("name", name);
        propertyNode.appendChild(dom.createTextNode(docProperties[name].toString()));
    }
    //pages
    var pageContainerNode = dom.createElementNS(PencilNamespaces.p, "Pages");
    dom.documentElement.appendChild(pageContainerNode);

    var requireRasterizedData = false;
    for (i in pages) {
        var page = pages[i];
        var pageNode = page.toNode(dom, requireRasterizedData);
        pageNode.setAttribute("id", page.properties.id);

        if (!requireRasterizedData) {
            var bgPageNode = dom.createElementNS(PencilNamespaces.p, "BackgroundPages");
            var bgId = page.properties.background;
            while (bgId) {
                var bgPage = this.doc.getPageById(bgId);
                if (!bgPage) break;
                if (bgPageNode.firstChild) {
                    bgPageNode.insertBefore(bgPage.toNode(dom, false), bgPageNode.firstChild);
                } else {
                    bgPageNode.appendChild(bgPage.toNode(dom, false));
                }

                bgId = bgPage.properties.background;
            }

            if (bgPageNode.firstChild) {
                pageNode.appendChild(bgPageNode);
            }
        }
        //ugly walkarround for Gecko d-o-e bug (https://bugzilla.mozilla.org/show_bug.cgi?id=98168)
        //we have to reparse the provided notes as XHTML and append it directly to the dom
        if (page.properties.note) {
            var xhtml = "
" + page.properties.note + "
"; var node = Dom.parseToNode(xhtml, dom); this._populateLinkTargetsInNote(node); var noteNode = dom.createElementNS(PencilNamespaces.p, "Note"); noteNode.appendChild(node); pageNode.appendChild(noteNode); } pageContainerNode.appendChild(pageNode); if (!pageExtraInfos[page.properties.id]) continue; var extra = pageExtraInfos[page.properties.id]; pageNode.setAttribute("rasterized", extra.rasterizedPath); var linkingContainerNode = dom.createElementNS(PencilNamespaces.p, "Links"); pageNode.appendChild(linkingContainerNode); var linkings = this._getPageLinks(page, pageExtraInfos, !exportSelection || !exportSelection.options || exportSelection.options.copyBGLinks); for (var j = 0; j < linkings.length; j ++) { var linking = linkings[j]; //debug("Validating: " + page.properties.name + " to: " + linking.pageId); var targetPage = this.doc.getPageById(linking.pageId); if (!targetPage) { debug("targetPage not found"); continue; } var linkNode = dom.createElementNS(PencilNamespaces.p, "Link"); linkNode.setAttribute("target", linking.pageId); linkNode.setAttribute("targetName", targetPage.properties.name); linkNode.setAttribute("targetFid", targetPage.properties.fid); linkNode.setAttribute("x", linking.geo.x); linkNode.setAttribute("y", linking.geo.y); linkNode.setAttribute("w", linking.geo.w); linkNode.setAttribute("h", linking.geo.h); linkingContainerNode.appendChild(linkNode); //debug("Created link from: " + page.properties.name + " to: " + targetPage.properties.name); } } var xmlFile = Local.newTempFile("pencil-doc", "xml"); Dom.serializeNodeToFile(dom, xmlFile); var exporter = Pencil.getDocumentExporterById(exportSelection.exporterId); try { exporter.export(this.doc, exportSelection, destFile, xmlFile, function () { debug("Finish exporting, DOC XML = " + xmlFile.path); //xmlFile.remove(true); callback(); }); } catch (e) { Console.dumpError(e); throw e; } }; Controller.prototype._populateLinkTargetsInNote = function (htmlNode) { var thiz = this; Dom.workOn("//html:a[@page-id or starts-with(@href, '#id:')]", htmlNode, function (link) { var id = link.getAttribute("page-id"); if (!id) { id = link.getAttribute("href").substring(4); } var page = thiz.doc.getPageById(id); if (!page) return; link.setAttribute("page-name", page.properties.name); link.setAttribute("page-fid", page.properties.fid); }); Dom.workOn("//html:a[@page-fid or starts-with(@href, '#fid:')]", htmlNode, function (link) { var fid = link.getAttribute("page-fid"); if (!fid) { fid = link.getAttribute("href").substring(5); } var page = thiz.doc.getPageByFid(fid); if (!page) return; link.setAttribute("page-name", page.properties.name); link.setAttribute("page-id", page.properties.id); }); Dom.workOn("//html:a[@page-name or starts-with(@href, '#name:')]", htmlNode, function (link) { var name = link.getAttribute("page-name"); if (!name) { name = link.getAttribute("href").substring(6); } var page = thiz.doc.getFirstPageByName(name); if (!page) return; link.setAttribute("page-fid", page.properties.fid); link.setAttribute("page-id", page.properties.id); }); }; Controller.prototype.rasterizeCurrentPage = function () { var page = this.getCurrentPage(); if (!page) return; var fileName = page.properties.name + ".png"; var currentDir = null; if (this.isBoundToFile()) { var file = Components.classes["@mozilla.org/file/local;1"] .createInstance(Components.interfaces.nsILocalFile); file.initWithPath(this.filePath); currentDir = file.parent; } var nsIFilePicker = Components.interfaces.nsIFilePicker; var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); fp.defaultString = fileName; if (currentDir) fp.displayDirectory = currentDir; fp.init(window, Util.getMessage("filepicker.export.page.as"), nsIFilePicker.modeSave); fp.appendFilter(Util.getMessage("filepicker.png.image"), "*.png"); fp.appendFilter(Util.getMessage("filepicker.all.files"), "*"); if (fp.show() == nsIFilePicker.returnCancel) return false; try { this._rasterizePage(page, fp.file.path, function () { Util.showStatusBarInfo(Util.getMessage("page.has.been.exported", page.properties.name), true); //Util.info("Page '" + page.properties.name + "' has been exported", "Location: " + fp.file.path); }); } catch (e) { Console.dumpError(e); } }; Controller.prototype._rasterizePage = function (page, path, callback, preprocessor) { //create a new svg document var svg = document.createElementNS(PencilNamespaces.svg, "svg"); svg.setAttribute("width", "" + page.properties.width + "px"); svg.setAttribute("height", "" + page.properties.height + "px"); if (page._view.canvas.hasBackgroundImage) { var bgImage = page._view.canvas.backgroundImage.cloneNode(true); bgImage.removeAttribute("transform"); bgImage.removeAttribute("id"); svg.appendChild(bgImage); } var drawingLayer = page._view.canvas.drawingLayer.cloneNode(true); drawingLayer.removeAttribute("transform"); drawingLayer.removeAttribute("id"); svg.appendChild(drawingLayer); //debug("bgr: " + page.properties.backgroundColor); //debug("trans: " + page.properties.transparentBackground); Pencil.rasterizer.rasterizeDOM(svg, path, callback, preprocessor, (page.properties.transparentBackground == "false" && !page.properties.background) ? page.properties.backgroundColor : null); }; Controller.prototype.rasterizeSelection = function () { var target = Pencil.getCurrentTarget(); if (!target || !target.getGeometry) return; var geo = target.getGeometry(); if (!geo) { //Util.showStatusBarWarning(Util.getMessage("the.selected.objects.cannot.be.exported"), true); alert(Util.getMessage("the.selected.objects.cannot.be.exported")); return; } var padding = 2 * Config.get("export.selection.padding", 0); //stroke fix? var strokeStyle = target.getProperty("strokeStyle"); if (strokeStyle) { padding += strokeStyle.w; } var w = geo.dim.w + padding; var h = geo.dim.h + padding; debug("w: " + w); var nsIFilePicker = Components.interfaces.nsIFilePicker; var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); fp.init(window, Util.getMessage("filepicker.export.selection.as"), nsIFilePicker.modeSave); fp.appendFilter(Util.getMessage("filepicker.png.image"), "*.png"); fp.appendFilter(Util.getMessage("filepicker.all.files"), "*"); if (fp.show() == nsIFilePicker.returnCancel) return; var svg = document.createElementNS(PencilNamespaces.svg, "svg"); svg.setAttribute("width", "" + w + "px"); svg.setAttribute("height", "" + h + "px"); var content = target.svg.cloneNode(true); content.removeAttribute("transform"); content.removeAttribute("id"); try { var dx = Math.round((w - geo.dim.w) / 2); var dy = Math.round((h - geo.dim.h) / 2); content.setAttribute("transform", "translate(" + dx + ", " + dy + ")"); } catch (e) { Console.dumpError(e); } svg.appendChild(content); Pencil.rasterizer.rasterizeDOM(svg, fp.file.path, function () {}); }; Controller.prototype.sizeToContent = function (passedPage, askForPadding) { var page = passedPage ? passedPage : this.getCurrentPage(); var canvas = page._view.canvas; if (!canvas) return; var padding = 0; if (askForPadding) { var paddingString = window.prompt(Util.getMessage("please.enter.the.padding"), "0"); if (!paddingString) return null; var padding = parseInt(paddingString, 10); if (!padding) padding = 0; } var newSize = canvas.sizeToContent(padding, padding); if (newSize) { page.properties.width = newSize.width; page.properties.height = newSize.height; } }; Controller.prototype.sizeToBestFit = function (passedPage) { var page = passedPage ? passedPage : this.getCurrentPage(); var canvas = page._view.canvas; if (!canvas) return; var newSize = Pencil.getBestFitSizeObject(); if (newSize) { canvas.setSize(newSize.width, newSize.height); page.properties.width = newSize.width; page.properties.height = newSize.height; Config.set("lastSize", [newSize.width, newSize.height].join("x")); } }; Controller.prototype._exportAsLayout = function () { var page = this.getCurrentPage(); var container = page._view.canvas.drawingLayer; var pw = parseFloat(page.properties.width); var ph = parseFloat(page.properties.height); var items = []; Dom.workOn("//svg:g[@p:type='Shape']", container, function (g) { var dx = 0; //rect.left; var dy = 0; //rect.top; var owner = g.ownerSVGElement; if (owner.parentNode && owner.parentNode.getBoundingClientRect) { var rect = owner.parentNode.getBoundingClientRect(); dx = rect.left; dy = rect.top; } debug("dx, dy: " + [dx, dy]); rect = g.getBoundingClientRect(); var refId = g.getAttributeNS(PencilNamespaces.p, "sc"); if (!refId) { refId = g.getAttributeNS(PencilNamespaces.p, "def"); } refId = refId.replace(/^system:ref:/, ""); var linkingInfo = { node: g, refId: refId, geo: { x: rect.left - dx, y: rect.top - dy, w: rect.width, h: rect.height } }; // if (!linkingInfo.refId) return; items.push(linkingInfo); }); var nsIFilePicker = Components.interfaces.nsIFilePicker; var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); fp.init(window, "Select folder", nsIFilePicker.modeGetFolder); fp.appendFilter(Util.getMessage("filepicker.all.files"), "*"); if (fp.show() == nsIFilePicker.returnCancel) return false; var dir = fp.file; dir.append("Shapes"); if (!dir.exists()) { dir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0777); } var current = 0; var done = function () { var html = document.createElementNS(PencilNamespaces.html, "html"); var body = document.createElementNS(PencilNamespaces.html, "body"); html.appendChild(body); var div = document.createElementNS(PencilNamespaces.html, "div"); div.setAttribute("style", "position: relative;"); body.appendChild(div); /* var canvas = document.createElementNS(PencilNamespaces.html, "canvas"); canvas.setAttribute("width", pw); canvas.setAttribute("height", ph); var bg = document.createElementNS(PencilNamespaces.html, "img"); bg.setAttribute("style", "width: 100%;"); bg.setAttribute("src", canvas.toDataURL("image/png")); div.appendChild(bg); */ for (var i = 0; i < items.length; i ++) { var link = items[i]; var img = document.createElementNS(PencilNamespaces.html, "img"); img.setAttribute("src", "Shapes/" + link.path); img.setAttribute("ref", link.refId); img.setAttribute("id", link.refId); var css = new CSS(); css.set("position", "absolute"); css.set("left", "" + link.geo.x + "px"); css.set("top", "" + link.geo.y + "px"); css.set("width", "" + link.geo.w + "px"); css.set("height", "" + link.geo.h + "px"); /* css.set("left", "" + (100 * link.geo.x / pw) + "%"); css.set("top", "" + (100 * link.geo.y / ph) + "%"); css.set("width", "" + (100 * link.geo.w / pw) + "%"); css.set("height", "" + (100 * link.geo.h / ph) + "%"); */ img.setAttribute("style", css.toString()); div.appendChild(img); } dir = dir.parent; dir.append("Layout.html"); if (dir.exists()) dir.remove(true); Dom.serializeNodeToFile(html, dir, ""); }; var next = function (listener) { if (current >= items.length) { done(); listener.onTaskDone(); return; } var link = items[current]; var padding = 2 * Config.get("export.selection.padding", 0); var target = page._view.canvas.createControllerFor(link.node); var geo = target.getGeometry(); //stroke fix? var strokeStyle = target.getProperty("strokeStyle"); if (strokeStyle) { padding += 2 * strokeStyle.w; } var w = geo.dim.w + padding; var h = geo.dim.h + padding; debug("w: " + w); var fileName = "" + current + ".png"; dir.append(fileName); var path = dir.path; dir = dir.parent; var svg = document.createElementNS(PencilNamespaces.svg, "svg"); svg.setAttribute("width", "" + w + "px"); svg.setAttribute("height", "" + h + "px"); var content = target.svg.cloneNode(true); content.removeAttribute("transform"); content.removeAttribute("id"); try { var dx = Math.round((w - geo.dim.w) / 2); var dy = Math.round((h - geo.dim.h) / 2); content.setAttribute("transform", "translate(" + dx + ", " + dy + ")"); } catch (e) { Console.dumpError(e); } svg.appendChild(content); Pencil.rasterizer.rasterizeDOM(svg, path, function () { link.path = fileName; current ++; listener.onProgressUpdated("Rasterizing", current, items.length); next(listener); }); }; Util.beginProgressJob("Exporting layout", next); }; function LinkingGeometryPreprocessor(pageExtraInfo) { this.pageExtraInfo = pageExtraInfo; } LinkingGeometryPreprocessor.prototype.process = function (doc) { var objects = Dom.getList(".//svg:g[@p:RelatedPage]", doc); objects.reverse(); debug("Count: " + objects.length); this.pageExtraInfo.objectsWithLinking = []; for (var i = 0; i < objects.length; i ++) { var g = objects[i]; var dx = 0; //rect.left; var dy = 0; //rect.top; var owner = g.ownerSVGElement; if (owner.parentNode && owner.parentNode.getBoundingClientRect) { var rect = owner.parentNode.getBoundingClientRect(); dx = rect.left; dy = rect.top; } debug("dx, dy: " + [dx, dy]); rect = g.getBoundingClientRect(); var linkingInfo = { pageId: g.getAttributeNS(PencilNamespaces.p, "RelatedPage"), geo: { x: rect.left - dx, y: rect.top - dy, w: rect.width, h: rect.height } }; if (!linkingInfo.pageId) continue; debug("Linking info: " + linkingInfo.toSource()); this.pageExtraInfo.objectsWithLinking.push(linkingInfo); } };