1 /**
  2  * @fileOverview  
  3  * Copyright (c) 2013 Regione Autonoma della Sardegna
  4  * Published under the GPL license.<br>
  5  * See <a href="https://sardegnageoportale.it/webgis/license.txt">https://sardegnageoportale.it/webgis/license.txt</a>
  6  * for the full text of the license.
  7  * @version 0.1
  8  */
  9 
 10 /**
 11  * @require plugins/Tool.js
 12  * @require GeoExt/widgets/Action.js
 13  */
 14 
 15 /**
 16  * @namespace framework.widgets.doublemap
 17  */
 18 Ext.ns("framework.widgets.doublemap");
 19 
 20 /** 
 21  * Class for template and map saving management.
 22  * Calls servlet for digest creation and file storing on server side.
 23  * @name_ DoubleMapLinker
 24  * @class Class for template and map saving management.
 25  * @constructor
 26  * @extends <a target="_blank" href="http://gxp.opengeo.org/master/doc/lib/plugins/Tool.html">gxp.plugins.Tool</a>
 27  */
 28 framework.widgets.doublemap.DoubleMapLinker = Ext.extend(Ext.Button,
 29   /** 
 30    * @lends framework.widgets.doublemap.DoubleMapLinker.prototype 
 31    */
 32     {
 33       doubleMapComponent: null,
 34       /**
 35        * Together with 'iconClsPrefix' define the icons of the buttons created
 36        * @public
 37        * @type String
 38        */
 39       mode: 'map',
 40       /** 
 41        * The prefix of the names of the css classes that define the icons of the buttons created 
 42        * to activate the mapLinker. You must define a class in your CSS file called with the value
 43        * of the expression this.iconClsPrefix+this.mode that specifies the above mentioned icon.
 44        * @public
 45        * @type String
 46        */
 47       iconClsPrefix: "gxp-icon-",
 48       /** 
 49        * the base Ajax Url for ajax request
 50        * default ""
 51        * @public
 52        * @type String
 53        */
 54       baseUrl: "",
 55       /** 
 56        * the custom Url for saved map
 57        * default ""
 58        * @public
 59        * @type String
 60        */
 61       customUrl: "",
 62       /**
 63        * Text for zoom in action tooltip (i18n).
 64        * @public
 65        * @type string
 66        */
 67       tooltip: "Create link map",
 68       /** 
 69        * featureLayers container
 70        * @public
 71        * @type Array(Object)
 72        */
 73       featureLayers: new Array(),
 74       
 75       /**
 76        * Css class for icon.
 77        * @public
 78        * @type String
 79       */
 80       iconCls: 'gxp-icon-map',
 81 
 82       /** Adds actions to be performed on click.
 83        * @public
 84        */
 85       handler: function() {
 86         var self = this;
 87 
 88         //aggiungo i dati relativi ai layer vettoriali
 89         if (self.mode === 'map') {
 90           self.saveMap();
 91         } else {
 92           Ext.Msg.prompt('Name', 'Nome con cui salvare il template:', function(btn, text) {
 93             if (btn == 'ok') {
 94               if (Ext.isEmpty(text)) {
 95                 Ext.Msg.alert('Errore', 'Il nome inserito è vuoto');
 96               } else {
 97                 text = text.trim().toLowerCase();
 98                 if (text === 'default') {
 99                   Ext.Msg.alert('Errore', 'Il nome template "default" è riservato');
100                 } else {
101                   self.saveTemplate(text);
102                 }
103               }
104 
105             } else {
106               Ext.Msg.alert('Info', 'Salvataggio annullato dall\'utente');
107             }
108 
109           });
110         }
111       },
112       /** 
113        * Saves a template serializing its content in json.
114        * @public
115        * @param {String} templateName name of template to be saved
116        * @param {boolan} forceWrite  write file whitout prompting even it already exists
117        */
118       saveTemplate: function(templateName, forceWrite) {
119         var self = this;
120         this.getDigest(function(digest) {
121           Ext.Ajax.request({
122             method: 'POST',
123             url: self.baseUrl + 'Save',
124             params: {hash: digest, content: self.toJson(), template: templateName, force: forceWrite},
125             success: function(response, opts) {
126               var obj = Ext.util.JSON.decode(response.responseText);
127               if (Ext.isDefined(obj.fileExists)) {
128                 Ext.MessageBox.confirm('Attenzione', templateName + ' già presente.<BR/>' +
129                   'Si desidera sovrascriverlo?', function(btn) {
130                   if (btn == 'yes') {
131                     //chiamata con force = true
132                     self.saveTemplate(templateName, true);
133                   } else {
134                     Ext.Msg.alert('Info', 'Salvataggio annullato dall\'utente');
135                   }
136                 });
137               } else {
138                 if (Ext.isDefined(obj.id)) {
139                   self.useMapConfiguration(obj.id);
140                 } else {
141                   Ext.MessageBox.alert('Errore', obj.error);
142                 }
143               }
144             },
145             failure: function(response, opts) {
146               Ext.MessageBox.alert('Errore', 'server-side failure with status code ' + response.status);
147               console.log('server-side failure with status code ' + response.status);
148             }
149           });
150         });
151       },
152       /** 
153        * Saves a map serializing its content in json creating a new map id.
154        * @public
155        */
156       saveMap: function() {
157         var self = this;
158         this.getDigest(function(digest) {
159           Ext.Ajax.request({
160             method: 'POST',
161             url: self.baseUrl + 'Save',
162             params: {hash: digest, content: self.toJson()},
163             success: function(response, opts) {
164               var obj = Ext.util.JSON.decode(response.responseText);
165               if (Ext.isDefined(obj.id)) {
166                 self.useMapConfiguration(obj.id);
167               } else {
168                 Ext.MessageBox.alert('Errore', obj.error);
169               }
170             },
171             failure: function(response, opts) {
172               Ext.MessageBox.alert('Errore', 'server-side failure with status code ' + response.status);
173               console.log('server-side failure with status code ' + response.status);
174             }
175           });
176         });
177       },
178       /** 
179        * Requests a digest based on client ip.
180        * @public
181        * @param {function} onSuccess function to be called when the digest has been received
182        */
183       getDigest: function(onSuccess) {
184         Ext.Ajax.request({
185           method: 'GET',
186           url: this.baseUrl + 'Digest',
187           success: function(response, opts) {
188             var obj = Ext.util.JSON.decode(response.responseText);
189             if (Ext.isDefined(obj.value)) {
190               onSuccess(obj.value);
191             } else {
192               Ext.MessageBox.alert('Errore', obj.error);
193             }
194           },
195           failure: function(response, opts) {
196             Ext.MessageBox.alert('Errore', 'server-side failure with status code ' + response.status);
197             console.log('server-side failure with status code ' + response.status);
198           }
199         });
200       },
201       /** 
202        * Function to be override to change the default behavior.
203        * @public
204        * @param {number} id id of current map configuration
205        */
206       useMapConfiguration: function(id) {
207         this.showLinkDialog(id);
208       },
209       /** 
210        * Shows a window containg a link for template/map sharing.
211        * @public
212        * @param {String} name Name of template/map saved
213        */
214       showLinkDialog: function(name) {
215         var link = this.doubleMapComponent.app1.getBaseUrl() + (this.customUrl?this.customUrl:'') + '?map=' + name;
216         var frame = "<iframe width='425' height='350' frameborder='0' scrolling='no' marginheight='0' marginwidth='0'" +
217           "src='" + link + "&framemode=1' class='link'></iframe>";
218         var pnl = new Ext.Panel({
219           title: this.mapInfoText,
220           html: '<div class="mapLinker">' +
221             '<h2>Link mappa</h2>' +
222             '<p>' +
223             '<input type="text" onclick="this.focus();this.select();" value="' + link + '" readonly="1" />' +
224             '</p>' +
225             '<h2>Copia e incolla l\'HTML da incorporare nel sito web</h2>' +
226             '<p>' +
227             '<textarea onclick="this.focus();this.select();" readonly="1">' + frame + '</textarea>' +
228             '</p>' +
229             '</div>',
230           height: 'auto',
231           width: 'auto'
232         });
233 
234 
235         var win = new Ext.Window({
236           title: "Condivisione mappa",
237           modal: true,
238           layout: "fit",
239           width: 342,
240           height: 230,
241           items: [pnl]
242         });
243         win.show();
244       },
245       /** 
246        * Get serialization of data to be saved.
247        * @public
248        */
249       mapToJson: function(mapviewer) {
250         var layers = mapviewer.mapPanel.map.layers;
251         var extraData = new Object();
252         extraData.backgroundColor = Ext.get(mapviewer.mapPanel.map.getViewport()).getStyle('background-color');
253         extraData.layers = new Array();
254         extraData.groups = mapviewer.layer_group;
255         if (mapviewer.mapPanel.map.searchName === 'routing' && mapviewer.tools.boxrouting && mapviewer.tools.boxrouting.routingpanel.xmlRequest.length > 0) {
256           extraData.routingSearchXmlRequest = mapviewer.tools.boxrouting.routingpanel.xmlRequest;
257           extraData.routingDestination = mapviewer.tools.boxrouting.routingpanel.endLocationCombo.lastSelectionText;
258           extraData.routingType = mapviewer.tools.boxrouting.routingpanel.routePreference;
259         }
260         if (mapviewer.photo) {
261           extraData.photo = mapviewer.photo.toJSON();
262         }
263         if (mapviewer.obliquePhoto) {
264           extraData.obliquePhoto = mapviewer.obliquePhoto;
265         }
266         var self = this;
267         Ext.each(layers, function(el, i) {
268           if (self.featureLayers.indexOf(el.name) !== -1) {
269            // extraData.layers.push({name: el.name, features: el.features, type: 'featureLayer'});
270             extraData.layers.push({name: el.name, type: 'featureLayer'});
271           }
272         });
273         mapviewer.customData = extraData;
274         return mapviewer.serializableState();
275       },
276       toJson: function() {
277         var res = new Object({
278           map1: this.mapToJson(this.doubleMapComponent.app1),
279           map2: this.mapToJson(this.doubleMapComponent.app2),
280           otherData: {
281             syncMaps: this.doubleMapComponent.isMapSyncActive(),
282             secondMapVisible: this.doubleMapComponent.secondMapVisible            
283           }
284         });
285         var json = Ext.encode(res);
286         return json;
287       }
288     }
289 
290 
291   );
292 
293   Ext.reg("framework_doublemaplinker", framework.widgets.doublemap.DoubleMapLinker);
294