Source: widgets/SpwCanvasPrinter.js

Retour à la documentation
/**
 * @class spw.widgets.SpwCanvasPrinter
 */
define(["dojo/_base/declare", "spw/api/SpwBaseTemplatedWidget", "spw/api/MessageManager",
        "dojo/_base/array", "dojo/dom", "dojo/dom-style", "dojo/_base/lang", "dojo/on",
        "dojo/i18n!./nls/SpwCanvasPrinter", "dojo/dom-construct", "spw/widgets/SpwScaleBar",
        "dojo/text!./templates/SpwCanvasPrinter.html", "spw/api/Printer", "dojo/dom-geometry",
        "dojo/dom-attr", "dojo/has","dijit/Tooltip","dojo/request","dojo/query",
        "dojox/xml/parser", "dojo/store/Memory", "dojo/data/ObjectStore",
        "dojo/sniff", "dijit/form/Button", "dijit/form/FilteringSelect"],
        function(declare, SpwBaseTemplatedWidget, MessageManager, array,
                dom, domStyle, lang, on, labels, domConstruct, SpwScaleBar,
                template, Printer, domGeom, domAttr, has,Tooltip,request,query,
                xmlParser, Memory, ObjectStore){

    return declare("spw.widgets.SpwCanvasPrinter", [SpwBaseTemplatedWidget], /** @lends spw.widgets.SpwCanvasPrinter.prototype */{

        templateString: template,
        labels: labels,

        width:"370px",
        height:"180px",

        generating: false,

        widgetTitle: labels.printLabel,
        iconClass: "spwMapPrinterIconss",

        printServerUrl: "http://sampleserver6.arcgisonline.com:80/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export Web Map Task",

        _widgetTitle: "",
        _iconClass: "",

        _savedWidgetState: null,
        _temporaryScaleBar: null,

        _displayedPrintZone: null,

        printer: null,

        printTemplates: [
            {"label":"Défaut", "mapWidth": 793, "mapHeight": 1122, "path":"" }
        ],

        /**
         * @constructs
         * @param config
         */
        constructor: function() {
            this.printer = new Printer();
        },

        buildRendering: function() {
            this.inherited(arguments);

            domConstruct.create("option", {innerHTML:labels.mapOnly, value:'mapWithScale'}, this.mapStyleSelect, "last");
//          domConstruct.create("option", {innerHTML:labels.mapWithScale, value:'mapWithScale'}, this.mapStyleSelect, "last");
//          domConstruct.create("option", {innerHTML:labels.mapWithWidgets, value:'mapWithWidgets'}, this.mapStyleSelect, "last");

            if(has("ie") < 10){
                window.postMessagePassthrough = function(s){
                    try{
                        window.postMessage(s, "*");
                    }
                    catch(e){}
                };
                if(has("ie") < 9){
                    domStyle.set(this.browserCompatibilityMessage, "display", "");
                    domAttr.set(this.autoDimension, "disabled", "disabled");
                    domAttr.remove(this.autoDimension, "checked");
                    domAttr.set(this.printZoneToggler, "disabled", "disabled");
                    domAttr.remove(this.printZoneToggler, "checked");
                }
            }
        },

        postCreate: function() {
            this.inherited(arguments);

            /*this._titlePane.toggle = function() {};
            this._titlePane._onTitleKey = function() {};*/

            this.own(
                on(this.templateSelect, 'change', lang.hitch(this, function() {
                    if (this.activated) {
                        this.togglePrintZone();
                    }
                })),
                on(this.autoDimension, 'change', lang.hitch(this, this.togglePrintZone)),
                on(this.printZoneToggler, 'change', lang.hitch(this, this.togglePrintZone))
            );

            this.templateSelect.set('store', new Memory({
                data: array.map(this.printTemplates, function(tmpl, idx) { return lang.mixin(tmpl, {id: idx}) }),
                idProperty: "id"
            }));

            this.templateSelect.set('value', 0);
        },

        onActivate: function(){
            this.inherited(arguments);
            this.togglePrintZone();
        },

        onDeactivate: function(){
            this.inherited(arguments);
            this.hidePrintZone();
        },

        generate_click: function(){
            this.generate();
        },

        generate: function() {
            if(this.generating){
                MessageManager.getInstance().notifyInfo(this.labels["alreadyPrinting"]);
            } else {
                this.generating = true;

                var tmpl = this.printTemplates[this.templateSelect.selectedIndex];

                if(has("ie") < 9)
                {
                    this.printer.getImagePrintTask(this.printServerUrl, tmpl.mapWidth, tmpl.mapHeight, lang.hitch(this, this._openTemplateWithPrintTask), lang.hitch(this, this._printTaskError));
                }
                else
                {
                    if(this.mapStyleSelect.options[this.mapStyleSelect.selectedIndex].value == 'mapWithScale')
                    {
                        this.hideMapElements();
                        this._temporaryScaleBar = new SpwScaleBar({spwViewer: this.spwViewer, position:'map', activated:true, mapPosition:{bottom:"27px", left:"10px"}});
                    }
                    this.printer.getImage(this.getPrintZone(), tmpl.mapWidth, tmpl.mapHeight, this.autoDimension.checked, lang.hitch(this, this._openTemplate));
                }

                this._widgetTitle = this.get('widgetTitle');
                this.set('widgetTitle', this.labels.generating);

                this._iconClass = this.get('iconClass');
                this.set('iconClass', "generatingIcon");
            }
        },

        _openTemplate: function(canvas) {

            this.generating = false;

            this.set('widgetTitle', this._widgetTitle);
            this.set('iconClass', this._iconClass);

            this.showMapElements();
            if(this._temporaryScaleBar){
                this._temporaryScaleBar.destroy();
                this._temporaryScaleBar = null;
            }

            var currentTemplate = this.printTemplates[this.templateSelect.selectedIndex];
            if(currentTemplate.path && currentTemplate.path != ""){
                this.performTemplating(currentTemplate.path,canvas.toDataURL());
            } else {
                window.open(canvas.toDataURL());
            }
        },

        _openTemplateWithPrintTask: function(data) {

            this.generating = false;

            this.set('widgetTitle', this._widgetTitle);
            this.set('iconClass', this._iconClass);

            var currentTemplate = this.printTemplates[this.templateSelect.selectedIndex];
            if(currentTemplate.path && currentTemplate.path != ""){
                this.performTemplating(currentTemplate.path,data.url);
            } else {
                window.open(data.url);
            }
        },

        performTemplating: function(templatePath,imageDataURL){
            request.get(templatePath).then(
                    function(response){

                        var specificPath="";
                        var domain="";
                        var regularPath="";

                        if(templatePath.indexOf("www") == -1 && templatePath.indexOf("http") == -1){
                            if(templatePath.indexOf("/") != 0){
                                regularPath = document.location.pathname;
                            }
                            specificPath = templatePath.substring(0,templatePath.lastIndexOf("/")+1);
                            domain = document.location.protocol+"//"+document.location.host;
                        }
                        else{
                            specificPath = templatePath.substring(0,templatePath.lastIndexOf("/")+1);
                        }

                        // regex for mapImage : (<\\s*[i|I][m|M][g|G][^>]*[i|I][d|D]\\s*=\\s*[\"|']\\s*mapImage\\s*[\"|'][^>]*>)
                        // regex for images : /<\\s*[i|I][m|M][g|G][^>]*[s|S][r|R][c|C]\\s*=\\s*[\"|']\\s*(\\S*)\s*[\"|'][^>]*>/g

                        var match = null;
                        var imagesUrls = new Array();


                        var regexImages = new RegExp("<\\s*[i|I][m|M][g|G][^>]*[s|S][r|R][c|C]\\s*=\\s*([\"|']\\S*[\"|'])\s*[^>]*>","g");

                        while (match = regexImages.exec(response)) {
                            if(match[1] && match[1] != '""' && match[1] != "''"){
                                imagesUrls.push(match[1]);
                            }
                        }

                        for(var i=0;i<imagesUrls.length;i++){
                            var imagePath = imagesUrls[i].substring(1, imagesUrls[i].length-1);
                            if(imagePath.indexOf("www") == -1 && imagePath.indexOf("http") == -1){
                                if(imagePath.indexOf("/") == 0){
                                    imagePath = domain+regularPath+imagePath;
                                }
                                else{
                                    imagePath = domain+regularPath+specificPath+imagePath;
                                }

                                response = response.replace(imagesUrls[i],'"'+imagePath+'"');
                            }
                        }

                        match = null;

                        var regexMapImage = new RegExp("<\\s*[i|I][m|M][g|G][^>]*[i|I][d|D]\\s*=\\s*[\"|']\\s*mapImage\\s*[\"|'][^>]*>");
                        match = regexMapImage.exec(response);
                        if(match[0]){
                            response = response.replace(match[0],"<img id=\"mapImage\" src=\""+imageDataURL+"\"/>");
                        }

                        var newWindow = window.open("");

                        newWindow.document.open();
                        newWindow.document.write(response);
                        newWindow.document.close();
                    },
                    function(error){
                        // Display the error returned
                        console.info(error);
                    }
                );
        },

        _printTaskError: function(error){
            this.generating = false;

            this.set('widgetTitle', this._widgetTitle);
            this.set('iconClass', this._iconClass);

            console.log(error);
        },

        hideMapElements: function() {
            var mapWidgets = this.spwViewer.get('spwWidgetsManager').getWidgets({position:'map'});
            if(mapWidgets && mapWidgets.length >= 0 && this.spwViewer.toolbar){
                mapWidgets.push(this.spwViewer.toolbar);
            }
            this._savedWidgetState = [];
            array.forEach(mapWidgets, lang.hitch(this, function(mapWidget){
                this._savedWidgetState.push([mapWidget, domStyle.get(mapWidget.domNode, "display")]);
                domStyle.set(mapWidget.domNode, "display", "none");
            }));
        },

        showMapElements: function() {
            if(this._savedWidgetState && this._savedWidgetState.length > 0){
                array.forEach(this._savedWidgetState, lang.hitch(this, function(savedWidgetState){
                    domStyle.set(savedWidgetState[0].domNode, "display", savedWidgetState[1]);
                }));
            }
        },

        getPrintZone: function(){
            switch (this.mapStyleSelect.options[this.mapStyleSelect.selectedIndex].value){
                case 'all': return document.body;
                case 'mapOnly': return this.spwViewer.get('spwMap').get('esriMap').root;
                case 'mapWithScale': return this.spwViewer.get('spwMap').get('esriMap').container;
                case 'mapWithWidgets':
                default: return this.spwViewer.get('spwMap').get('esriMap').container;
            }
        },

        togglePrintZone: function() {
            if(this.printZoneToggler.checked){
                this.showPrintZone();
            } else {
                this.hidePrintZone();
            }
        },

        showPrintZone: function() {
            if (!this.templateSelect.get('value')) {
                this.hidePrintZone();
                return;
            }

            var tmpl = this.printTemplates[+(this.templateSelect.get('value'))];
            var elemPos = domGeom.position(this.getPrintZone());
            if(this._displayedPrintZone) {
                this.hidePrintZone();
            }

            if(this.autoDimension.checked){
                this._displayedPrintZone = domConstruct.create("div", {style:"position: absolute;z-index: 99;border:3px dashed darkblue;box-sizing:border-box;width:"+ tmpl.mapWidth +"px; height:" + tmpl.mapHeight+"px;top:"+elemPos.y+"px;left:"+elemPos.x+"px"}, document.body);
            } else {
                var croppedZone = this.getCroppedZone(tmpl, elemPos);
                this._displayedPrintZone = domConstruct.create("div", {style:"position: absolute;z-index: 99;border:3px dashed darkblue;box-sizing:border-box;width:"+ croppedZone.width +"px; height:" + croppedZone.height+"px;top:"+elemPos.y+"px;left:"+elemPos.x+"px"}, document.body);
                if(croppedZone.qualityLoose){
                    domStyle.set(this.printQualityWarn, "display", "inline");
                }
            }
        },

        hidePrintZone: function() {
            domStyle.set(this.printQualityWarn, "display", "none");
            if(this._displayedPrintZone) {
                domConstruct.destroy(this._displayedPrintZone);
            }
        },

        getCroppedZone: function(tmpl, elemPos){
            var tw = tmpl.mapWidth;
            var th = tmpl.mapHeight;

            if(elemPos.w < tw){
                var w = tw*elemPos.w/tw;
                var h = th*elemPos.w/tw;
                if(h > elemPos.h){
                    w = w * elemPos.h/h;
                    h = h * elemPos.h/h;
                }
                return {width:w, height:h, qualityLoose: true};
            } else if(elemPos.h < th){
                var w = tw*elemPos.h/th;
                var h = th*elemPos.h/th;
                if(w > elemPos.w){
                    h = h * elemPos.w/w;
                    w = w * elemPos.w/w;
                }
                return {width:w, height:h, qualityLoose: true};
            } else {
                if(tw > th){
                    var w = elemPos.w*tw/elemPos.w;
                    var h = elemPos.h*tw/elemPos.w;
                    return {width:w, height:h};
                } else {
                    var w = tw*elemPos.h/th;
                    var h = th*elemPos.h/th;
                    return {width:w, height:h};
                }
            }
        }
    });
});