Index: main/plugin-cms/plugin.xml
===================================================================
--- main/plugin-cms/plugin.xml	(revision 26911)
+++ main/plugin-cms/plugin.xml	(working copy)
@@ -1140,7 +1140,7 @@
                     <file>js/org/ametys/cms/widgets/GeocodeWidget.i18n.js</file>
                     <file>js/org/ametys/cms/helper/ChooseLocation.i18n.js</file>
                     <file>js/org/ametys/cms/helper/ChooseLocation/LoadGoogleMaps.i18n.js</file>
-                    <file>js/org/ametys/cms/helper/GMapPanel.i18n.js</file>
+                    <file>js/Ext/ux/GMapPanel3.i18n.js</file>
 				</scripts>
 				<css>
 					<file>css/content/Widget.css</file>
Index: main/plugin-cms/i18n/messages_en.xml
===================================================================
--- main/plugin-cms/i18n/messages_en.xml	(revision 26911)
+++ main/plugin-cms/i18n/messages_en.xml	(working copy)
@@ -1494,6 +1494,9 @@
 	<message key="PLUGINS_CMS_GEOCODE_GMAP_ERROR">There was a problem during the geocoding handling</message>
 	<message key="PLUGINS_CMS_GEOCODE_GMAP_ZERO_RESULTS">The address was not found</message>
     
+    <message key="PLUGINS_CMS_GEOCODE_DIRECTIONS_NORTH">N</message>
+    <message key="PLUGINS_CMS_GEOCODE_DIRECTIONS_EST">E</message>
+    
    	<!-- +
    	     | LANGUAGES
    	     + -->
Index: main/plugin-cms/i18n/messages_fr.xml
===================================================================
--- main/plugin-cms/i18n/messages_fr.xml	(revision 26911)
+++ main/plugin-cms/i18n/messages_fr.xml	(working copy)
@@ -1495,6 +1495,9 @@
 	<message key="PLUGINS_CMS_GEOCODE_GMAP_ERROR">Une erreur est survenue lors du traitement de votre demande</message>
 	<message key="PLUGINS_CMS_GEOCODE_GMAP_ZERO_RESULTS">L'adresse est introuvable</message>
     
+    <message key="PLUGINS_CMS_GEOCODE_DIRECTIONS_NORTH">N</message>
+    <message key="PLUGINS_CMS_GEOCODE_DIRECTIONS_EST">E</message>
+    
     <!-- +
          | LANGUAGES
          + -->
Index: main/plugin-cms/resources/js/org/ametys/cms/widgets/GeocodeWidget.i18n.js
===================================================================
--- main/plugin-cms/resources/js/org/ametys/cms/widgets/GeocodeWidget.i18n.js	(revision 26911)
+++ main/plugin-cms/resources/js/org/ametys/cms/widgets/GeocodeWidget.i18n.js	(working copy)
@@ -23,7 +23,7 @@
  * Creates a geocode widget field.
  * @class This class provides a widget to select a map location.&lt;br&gt;
  * @extends Ext.form.TextField
- * @xtype GeocodeWidget
+ * @xtype geocodefield
  */
 org.ametys.cms.widgets.GeocodeWidget = function(config) 
 {
@@ -42,7 +42,7 @@
  * @static
  * The xtype
  */
-org.ametys.cms.widgets.GeocodeWidget.XTYPE = 'GeocodeWidget';
+org.ametys.cms.widgets.GeocodeWidget.XTYPE = 'geocodefield';
 
 Ext.extend(org.ametys.cms.widgets.GeocodeWidget, Ext.form.TextField, {
 	
@@ -377,7 +377,8 @@
 {
 	if (location &amp;&amp; location.latitude)
 	{
-		return parseFloat(location.latitude).toFixed(4) + "°N , " + parseFloat(location.longitude).toFixed(4) + "°E";
+		return parseFloat(location.latitude).toFixed(4) + "°" + "<i18n:text i18n:key='PLUGINS_CMS_GEOCODE_DIRECTIONS_NORTH'/>" + ", "
+			+ parseFloat(location.longitude).toFixed(4) + "°" + "<i18n:text i18n:key='PLUGINS_CMS_GEOCODE_DIRECTIONS_EST'/>";
 	}
 	else
 	{
Index: main/plugin-cms/resources/js/org/ametys/cms/helper/GMapPanel.i18n.js
===================================================================
--- main/plugin-cms/resources/js/org/ametys/cms/helper/GMapPanel.i18n.js	(revision 26911)
+++ main/plugin-cms/resources/js/org/ametys/cms/helper/GMapPanel.i18n.js	(working copy)
@@ -1,759 +0,0 @@
-/*
- *  Copyright 2011 Anyware Services
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-
-Ext.namespace('Ext.ux');
-
-Ext.ux.GMapPanel3 = Ext.extend(Ext.Panel, {
-    /**
-     * @cfg {Boolean} border
-     * Defaults to &lt;tt&gt;false&lt;/tt&gt;.  See {@link Ext.Panel}.&lt;code&gt;{@link Ext.Panel#border border}&lt;/code&gt;.
-     */
-    border: false,
-
-    /**
-     * @cfg {Array} respErrors
-     * An array of msg/code pairs.
-     */
-    respErrors: [{
-            code: 'UNKNOWN_ERROR',
-            //msg: 'A geocoding or directions request could not be successfully processed, yet the exact reason for the failure is not known.' 
-            msg : "<i18n:text i18n:catalogue='plugin.maps' i18n:key='PLUGINS_CMS_GEOCODE_GMAP_UNKNOWN_ERROR'/>"
-        },{
-            code: 'ERROR',
-//            msg: 'There was a problem contacting the Google servers.'
-              msg: "<i18n:text i18n:catalogue='plugin.maps' i18n:key='PLUGINS_CMS_GEOCODE_GMAP_ERROR'/>"
-        },{
-            code: 'ZERO_RESULTS',
-            //msg: 'The request did not encounter any errors but returns zero results.'
-            msg: "<i18n:text i18n:catalogue='plugin.maps' i18n:key='PLUGINS_CMS_GEOCODE_GMAP_ZERO_RESULTS'/>"
-        },{
-            code: 'INVALID_REQUEST',
-            //msg: 'This request was invalid.' 
-            msg: "<i18n:text i18n:catalogue='plugin.maps' i18n:key='PLUGINS_CMS_GEOCODE_GMAP_ERROR'/>"
-        },{
-            code: 'REQUEST_DENIED',
-            //msg: 'The webpage is not allowed to use the geocoder for some reason.' 
-            msg: "<i18n:text i18n:catalogue='plugin.maps' i18n:key='PLUGINS_CMS_GEOCODE_GMAP_ERROR'/>"
-        },{
-            code: 'OVER_QUERY_LIMIT',
-            //msg: 'The webpage has gone over the requests limit in too short a period of time.' 
-            msg: "<i18n:text i18n:catalogue='plugin.maps' i18n:key='PLUGINS_CMS_GEOCODE_GMAP_ERROR'/>"
-    }],
-    /**
-     * @cfg {Array} locationTypes
-     * An array of msg/code/level pairs.
-     */
-    locationTypes: [{
-            level: 4,
-            code: 'ROOFTOP',
-            msg: 'The returned result is a precise geocode for which we have location information accurate down to street address precision.' 
-        },{
-            level: 3,
-            code: 'RANGE_INTERPOLATED',
-            msg: 'The returned result reflects an approximation (usually on a road) interpolated between two precise points (such as intersections). Interpolated results are generally returned when rooftop geocodes are unavailable for a street address.'
-        },{
-            level: 2,
-            code: 'GEOMETRIC_CENTER',
-            msg: 'The returned result is the geometric center of a result such as a polyline (for example, a street) or polygon (region).'
-        },{
-            level: 1,
-            code: 'APPROXIMATE',
-            msg: 'The returned result is approximate.' 
-    }],
-    /**
-     * @cfg {String} respErrorTitle
-     * Defaults to &lt;tt&gt;'Error'&lt;/tt&gt;.
-     */
-    respErrorTitle : 'Error',
-    /**
-     * @cfg {String} geoErrorMsgUnable
-     * Defaults to &lt;tt&gt;'Unable to Locate the Address you provided'&lt;/tt&gt;.
-     */
-    geoErrorMsgUnable : 'Unable to Locate the Address you provided',
-    /**
-     * @cfg {String} geoErrorTitle
-     * Defaults to &lt;tt&gt;'Address Location Error'&lt;/tt&gt;.
-     */
-    geoErrorTitle : 'Address Location Error',
-    /**
-     * @cfg {String} geoErrorMsgAccuracy
-     * Defaults to &lt;tt&gt;'The address provided has a low accuracy.&lt;br&gt;&lt;br&gt;{0} Accuracy.'&lt;/tt&gt;.
-     * &lt;div class="mdetail-params"&gt;&lt;ul&gt;
-     * &lt;li&gt;&lt;b&gt;&lt;code&gt;ROOFTOP&lt;/code&gt;&lt;/b&gt; : &lt;div class="sub-desc"&gt;&lt;p&gt;
-     * The returned result is a precise geocode for which we have location information accurate down to street address precision.
-     * &lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
-     * &lt;li&gt;&lt;b&gt;&lt;code&gt;RANGE_INTERPOLATED&lt;/code&gt;&lt;/b&gt; : &lt;div class="sub-desc"&gt;&lt;p&gt;
-     * The returned result reflects an approximation (usually on a road) interpolated between two precise points (such as intersections). Interpolated results are generally returned when rooftop geocodes are unavailable for a street address.
-     * &lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
-     * &lt;li&gt;&lt;b&gt;&lt;code&gt;GEOMETRIC_CENTER&lt;/code&gt;&lt;/b&gt; : &lt;div class="sub-desc"&gt;&lt;p&gt;
-     * The returned result is the geometric center of a result such as a polyline (for example, a street) or polygon (region).
-     * &lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
-     * &lt;li&gt;&lt;b&gt;&lt;code&gt;APPROXIMATE&lt;/code&gt;&lt;/b&gt; : &lt;div class="sub-desc"&gt;&lt;p&gt;
-     * The returned result is approximate.
-     * &lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
-     * &lt;/ul&gt;&lt;/div&gt;
-     */
-    geoErrorMsgAccuracy : 'The address provided has a low accuracy.&lt;br&gt;&lt;br&gt;"{0}" Accuracy.&lt;br&gt;&lt;br&gt;{1}',
-    /**
-     * @cfg {String} gmapType
-     * The type of map to display, generic options available are: 'map', 'panorama'.
-     * Defaults to &lt;tt&gt;'map'&lt;/tt&gt;. 
-     * More specific maps can be used by specifying the google map type:
-     * &lt;div class="mdetail-params"&gt;&lt;ul&gt;
-     * &lt;li&gt;&lt;b&gt;&lt;code&gt;G_NORMAL_MAP&lt;/code&gt;&lt;/b&gt; : &lt;div class="sub-desc"&gt;&lt;p&gt;
-     * Displays the default road map view
-     * &lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
-     * &lt;li&gt;&lt;b&gt;&lt;code&gt;G_SATELLITE_MAP&lt;/code&gt;&lt;/b&gt; : &lt;div class="sub-desc"&gt;&lt;p&gt;
-     * Displays Google Earth satellite images
-     * &lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
-     * &lt;li&gt;&lt;b&gt;&lt;code&gt;G_HYBRID_MAP&lt;/code&gt;&lt;/b&gt; : &lt;div class="sub-desc"&gt;&lt;p&gt;
-     * Displays a mixture of normal and satellite views
-     * &lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
-     * &lt;li&gt;&lt;b&gt;&lt;code&gt;G_DEFAULT_MAP_TYPES&lt;/code&gt;&lt;/b&gt; : &lt;div class="sub-desc"&gt;&lt;p&gt;
-     * Contains an array of the above three types, useful for iterative processing.
-     * &lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
-     * &lt;li&gt;&lt;b&gt;&lt;code&gt;G_PHYSICAL_MAP&lt;/code&gt;&lt;/b&gt; : &lt;div class="sub-desc"&gt;&lt;p&gt;
-     * Displays a physical map based on terrain information. 
-     * &lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
-     * &lt;li&gt;&lt;b&gt;&lt;code&gt;G_MOON_ELEVATION_MAP&lt;/code&gt;&lt;/b&gt; : &lt;div class="sub-desc"&gt;&lt;p&gt;
-     * Displays a shaded terrain map of the surface of the Moon, color-coded by altitude.
-     * &lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
-     * &lt;li&gt;&lt;b&gt;&lt;code&gt;G_MOON_VISIBLE_MAP&lt;/code&gt;&lt;/b&gt; : &lt;div class="sub-desc"&gt;&lt;p&gt;
-     * Displays photographic imagery taken from orbit around the moon.
-     * &lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
-     * &lt;li&gt;&lt;b&gt;&lt;code&gt;G_MARS_ELEVATION_MAP&lt;/code&gt;&lt;/b&gt; : &lt;div class="sub-desc"&gt;&lt;p&gt;
-     * Displays a shaded terrain map of the surface of Mars, color-coded by altitude.
-     * &lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
-     * &lt;li&gt;&lt;b&gt;&lt;code&gt;G_MARS_VISIBLE_MAP&lt;/code&gt;&lt;/b&gt; : &lt;div class="sub-desc"&gt;&lt;p&gt;
-     * Displays photographs taken from orbit around Mars.
-     * &lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
-     * &lt;li&gt;&lt;b&gt;&lt;code&gt;G_MARS_INFRARED_MAP&lt;/code&gt;&lt;/b&gt; : &lt;div class="sub-desc"&gt;&lt;p&gt;
-     * Displays a shaded infrared map of the surface of Mars, where warmer areas appear brighter and colder areas appear darker.
-     * &lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
-     * &lt;li&gt;&lt;b&gt;&lt;code&gt;G_SKY_VISIBLE_MAP&lt;/code&gt;&lt;/b&gt; : &lt;div class="sub-desc"&gt;&lt;p&gt;
-     * Displays a mosaic of the sky, as seen from Earth, covering the full celestial sphere.
-     * &lt;/p&gt;&lt;/div&gt;&lt;/li&gt;
-     * &lt;/ul&gt;&lt;/div&gt;
-     * Sample usage:
-     * &lt;pre&gt;&lt;code&gt;
-     * gmapType: G_MOON_VISIBLE_MAP
-     * &lt;/code&gt;&lt;/pre&gt;
-     */
-    gmapType : 'map',
-    /**
-     * @cfg {Object} setCenter
-     * The initial center location of the map. The map needs to be centered before it can be used.
-     * A marker is not required to be specified. 
-     * More markers can be added to the map using the &lt;code&gt;{@link #markers}&lt;/code&gt; array.
-     * For example:
-     * &lt;pre&gt;&lt;code&gt;
-setCenter: {
-    geoCodeAddr: '4 Yawkey Way, Boston, MA, 02215-3409, USA',
-    marker: {title: 'Fenway Park'}
-},
-
-// or just specify lat/long
-setCenter: {
-    lat: 42.345573,
-    lng: -71.098326
-}
-     * &lt;/code&gt;&lt;/pre&gt;
-     */
-    /**
-     * @cfg {Number} zoomLevel
-     * The zoom level to initialize the map at, generally between 1 (whole planet) and 40 (street).
-     * Also used as the zoom level for panoramas, zero specifies no zoom at all.
-     * Defaults to &lt;tt&gt;3&lt;/tt&gt;.
-     */
-    zoomLevel: 3,
-    /**
-     * @cfg {Number} yaw
-     * The Yaw, or rotational direction of the users perspective in degrees. Only applies to panoramas.
-     * Defaults to &lt;tt&gt;180&lt;/tt&gt;.
-     */
-    yaw: 180,
-    /**
-     * @cfg {Number} pitch
-     * The pitch, or vertical direction of the users perspective in degrees.
-     * Defaults to &lt;tt&gt;0&lt;/tt&gt; (straight ahead). Valid values are between +90 (straight up) and -90 (straight down). 
-     */
-    pitch: 0,
-    /**
-     * @cfg {Boolean} displayGeoErrors
-     * True to display geocoding errors to the end user via a message box.
-     * Defaults to &lt;tt&gt;false&lt;/tt&gt;.
-     */
-    displayGeoErrors: false,
-    /**
-     * @cfg {Boolean} minGeoAccuracy
-     * The level to display an accuracy error below. Defaults to &lt;tt&gt;ROOFTOP&lt;/tt&gt;. For additional information
-     * see &lt;a href="http://code.google.com/apis/maps/documentation/reference.html#GGeoAddressAccuracy"&gt;here&lt;/a&gt;.
-     */
-    minGeoAccuracy: 'APPROXIMATE',
-    /**
-     * @cfg {Object} mapOpts
-     * Object of options representing map option, a full list can be found
-     * &lt;a href="http://code.google.com/intl/fr-FR/apis/maps/documentation/javascript/reference.html#MapOptions"&gt;here&lt;/a&gt;.
-     * For example:
-     * &lt;pre&gt;&lt;code&gt;
-     * mapOpts:{'mapTypeControl' : false, 'zoomControl' : true,}         
-     * &lt;/code&gt;&lt;/pre&gt;
-     */
-    /**
-     * @cfg {Array} markers
-     * Markers may be added to the map. Instead of specifying &lt;code&gt;lat&lt;/code&gt;/&lt;code&gt;lng&lt;/code&gt;,
-     * geocoding can be specified via a &lt;code&gt;geoCodeAddr&lt;/code&gt; string.
-     * For example:
-     * &lt;pre&gt;&lt;code&gt;
-markers: [{
-    //lat: 42.339641,
-    //lng: -71.094224,
-    // instead of lat/lng:
-    geoCodeAddr: '465 Huntington Avenue, Boston, MA, 02215-5597, USA',
-    marker: {title: 'Boston Museum of Fine Arts'},
-    listeners: {
-        click: function(e){
-            Ext.Msg.alert('Its fine', 'and its art.');
-        }
-    }
-},{
-    lat: 42.339419,
-    lng: -71.09077,
-    marker: {title: 'Northeastern University'}
-}]
-     * &lt;/code&gt;&lt;/pre&gt;
-     */
-    // private
-    mapDefined: false,
-    // private
-    mapDefinedGMap: false,
-    initComponent : function(){
-        
-        this.addEvents(
-            /**
-             * @event mapready
-             * Fires when the map is ready for interaction
-             * @param {GMapPanel} this
-             * @param {GMap} map
-             */
-            'mapready',
-            /**
-             * @event apiready
-             * Fires when the Google Maps API is loaded
-             */
-            'apiready'
-        );
-        
-        Ext.applyIf(this,{
-          markers: [],
-          cache: {
-              marker: [],
-              polyline: [],
-              polygon: [],
-              infowindow: []
-          }
-        });
-        
-        Ext.ux.GMapPanel3.superclass.initComponent.call(this);        
-
-        if (window.google &amp;&amp; window.google.maps){
-          this.on('afterrender', this.apiReady, this);
-        }else{
-          window.gmapapiready = this.apiReady.createDelegate(this);
-          this.buildScriptTag('//maps.google.com/maps/api/js?sensor=false&amp;callback=gmapapiready');
-        }
-
-    },
-    apiReady: function() {
-        
-        if (this.rendered)
-        {
-          
-          if (!this.zoomLevel)
-            this.zoomLevel = 1;
-          
-          (function(){
-          var mapOptions = {
-             zoom:this.zoomLevel,
-            mapTypeId: this.mapTypeId
-          };
-          
-          if(this.mapOpts &amp;&amp; typeof this.mapOpts === 'object'){
-            Ext.applyIf(mapOptions, this.mapOpts);
-          }
-          
-          
-          if (this.gmapType === 'map'){
-              this.gmap = new google.maps.Map(this.body.dom, mapOptions);
-              this.mapDefined = true;
-              this.mapDefinedGMap = true;
-          }
-          
-          if (this.gmapType === 'panorama'){
-              this.gmap = new GStreetviewPanorama(this.body.dom);
-              this.mapDefined = true;
-          }
-  
-          if (!this.mapDefined &amp;&amp; this.gmapType){
-             this.gmap = new google.maps.Map(this.body.dom, mapOptions);
-             this.gmap.setMapTypeId(this.gmapType);
-             this.mapDefined = true;
-             this.mapDefinedGMap = true;
-          }
-          
-          google.maps.event.addListenerOnce(this.getMap(), 'tilesloaded', this.onMapReady.createDelegate(this));
-          google.maps.event.addListener(this.getMap(), 'dragend', this.dragEnd.createDelegate(this));
-          
-          if (typeof this.setCenter === 'object') {
-              if (typeof this.setCenter.geoCodeAddr === 'string'){
-                if(this.setCenter.geoCodeAddr == 'currentLocation'){
-                  this.centerOnClientLocation();
-                }
-                else {
-                  this.geoCodeLookup(this.setCenter.geoCodeAddr, this.setCenter.marker, false, true, this.setCenter.listeners);
-                }
-              }else{
-                  if (this.gmapType === 'map'){
-                      var point = new google.maps.LatLng(this.setCenter.lat,this.setCenter.lng);
-                      this.getMap().setCenter(point, this.zoomLevel);
-                      this.lastCenter = point;  
-                  }
-                  if (typeof this.setCenter.marker === 'object' &amp;&amp; typeof point === 'object') {
-                      this.addMarker(point, this.setCenter.marker, this.setCenter.marker.clear);
-                  }
-              }
-              if (this.gmapType === 'panorama'){
-                  this.getMap().setLocationAndPOV(new google.maps.LatLng(this.setCenter.lat,this.setCenter.lng), {yaw: this.yaw, pitch: this.pitch, zoom: this.zoomLevel});
-              }
-          } else {
-            //no center defined center on greenwitch
-            var point = new google.maps.LatLng(0.0,0.0);
-            this.zoomLevel = 1;
-            this.getMap().setCenter(point, this.zoomLevel);
-            this.lastCenter = point;
-          }         
-          
-          }).defer(200,this);
-          
-        }else{
-          this.on('afterrender', this.apiReady, this);
-        }
-    },
-    // private
-    afterRender : function(){
-        
-        var wh = this.ownerCt.getSize();
-        Ext.applyIf(this, wh);
-        
-        Ext.ux.GMapPanel3.superclass.afterRender.call(this);
-
-    },
-    // private
-    buildScriptTag: function(filename, callback) {
-        var script  = document.createElement('script'),
-        	head    = document.getElementsByTagName("head")[0];
-        script.type = "text/javascript";
-        script.src  = filename;    
-        
-        return head.appendChild(script);
-    },
-    // private
-    onMapReady : function(){
-                        
-        this.addMarkers(this.markers);
-        
-        this.fireEvent('mapready', this, this.getMap());
-        
-    },
-    // private
-    onResize : function(w, h){
-        
-    	Ext.ux.GMapPanel3.superclass.onResize.call(this, w, h);
-
-        // check for the existance of the google map in case the onResize fires too early
-        if (typeof this.getMap() == 'object') {
-            google.maps.event.trigger(this.getMap(), 'resize');
-            if (this.lastCenter){
-              this.getMap().setCenter(this.lastCenter, this.zoomLevel);
-            }
-        }
-    },
-    // private
-    setSize : function(width, height, animate) {
-        
-    	Ext.ux.GMapPanel3.superclass.setSize.call(this, width, height, animate);
-
-        // check for the existance of the google map in case setSize is called too early
-        if (Ext.isObject(this.getMap())) {
-            google.maps.event.trigger(this.getMap(), 'resize');
-            if (this.lastCenter){
-              this.getMap().setCenter(this.lastCenter, this.zoomLevel);
-            }
-        }
-        
-    },
-    // private
-    dragEnd: function(){
-      this.lastCenter = this.getMap().getCenter();
-    },
-    /**
-     * Returns the current google map which can be used to call Google Maps API specific handlers.
-     * @return {GMap} this
-     */
-    getMap : function(){
-        
-        return this.gmap;
-        
-    },
-    /**
-     * Returns the maps center as a GLatLng object
-     * @return {GLatLng} this
-     */
-    getCenter : function(){
-        
-        return this.getMap().getCenter();
-        
-    },
-    /**
-     * Returns the maps center as a simple object
-     * @return {Object} this has lat and lng properties only
-     */
-    getCenterLatLng : function(){
-        
-        var ll = this.getCenter();
-        return {lat: ll.lat(), lng: ll.lng()};
-        
-    },
-    /**
-     * Creates markers from the array that is passed in. Each marker must consist of at least
-     * &lt;code&gt;lat&lt;/code&gt; and &lt;code&gt;lng&lt;/code&gt; properties or a &lt;code&gt;geoCodeAddr&lt;/code&gt;.
-     * @param {Array} markers an array of marker objects
-     */
-    addMarkers : function(markers) {
-        if (Ext.isArray(markers)){
-            for (var i = 0; i &lt; markers.length; i++) {
-                if (markers[i]) {
-                    if (typeof markers[i].geoCodeAddr == 'string') {
-                        this.geoCodeLookup(markers[i].geoCodeAddr, markers[i].marker, false, markers[i].setCenter, markers[i].listeners);
-                    } else {
-                        var mkr_point = new google.maps.LatLng(markers[i].lat, markers[i].lng);
-                        this.addMarker(mkr_point, markers[i].marker, false, markers[i].setCenter, markers[i].listeners);
-                    }
-                }
-            }
-        }
-        
-    },
-    /**
-     * Creates a single marker.
-     * @param {Object} point a GLatLng point
-     * @param {Object} marker a marker object consisting of at least lat and lng
-     * @param {Boolean} clear clear other markers before creating this marker
-     * @param {Boolean} center true to center the map on this marker
-     * @param {Object} listeners a listeners config
-     */
-    addMarker : function(point, marker, clear, center, listeners){
-        
-        Ext.applyIf(marker,{});
-
-        if (clear === true){
-            this.clearMarkers();
-        }
-        if (center === true) {
-            this.getMap().setCenter(point, this.zoomLevel)
-            this.lastCenter = point;
-        }
-
-        var mark = new google.maps.Marker(Ext.apply(marker, {
-            position: point
-        }));
-        
-        if (marker.infoWindow){
-            this.createInfoWindow(marker.infoWindow, point, mark);
-        }
-        
-        this.cache.marker.push(mark);
-        mark.setMap(this.getMap());
-
-        if (typeof listeners === 'object'){
-            for (evt in listeners) {
-                google.maps.event.addListener(mark, evt, listeners[evt]);
-            }
-        }
-        
-        return mark;
-        
-    },
-    /**
-     * Creates a single polyline.
-     * @param {Array} points an array of polyline points
-     * @param {Object} linestyle an object defining the line style to use
-     */
-    addPolyline : function(points, linestyle){
-        
-        var plinepnts = new google.maps.MVCArray, pline, linestyle = linestyle ? linestyle : {
-            strokeColor: '#FF0000',
-            strokeOpacity: 1.0,
-            strokeWeight: 2
-        };
-        
-        Ext.each(points, function(point){
-            plinepnts.push(new google.maps.LatLng(point.lat, point.lng));
-        }, this);
-        
-        var pline = new google.maps.Polyline(Ext.apply({
-          path: plinepnts
-        },linestyle));
-        
-        this.cache.polyline.push(pline);
-        
-        pline.setMap(this.getMap());
-
-    },
-    
-   /**
-     * Creates a single polygon.
-     * @param {Array} points an array of polygone points
-     * @param {Object} polygonOptions an object defining the style to use
-     */
-    addPolygon : function(points, polygonOptions, listeners){
-        var polygonPoints = new google.maps.MVCArray();
-
-        Ext.applyIf(polygonOptions,{
-            strokeColor: '#FF0000',
-            strokeOpacity: 1.0,
-            strokeWeight: 2,
-            fillColor: "#FF0000",
-            fillOpacity: 0.4
-        });
-        
-        var latLng;
-        var bounds = new google.maps.LatLngBounds();
-        Ext.each(points, function(point){
-            latLng = new google.maps.LatLng(point.lat, point.lng)
-            polygonPoints.push(latLng);
-            bounds.extend(latLng);
-        }, this);
-
-        var polygon = new google.maps.Polygon(Ext.apply({
-          path: polygonPoints
-        }, polygonOptions));
-        
-        
-        if (polygonOptions.infoWindow){
-            this.createInfoWindow(polygonOptions.infoWindow, bounds.getCenter(), polygon);
-        }        
-
-        this.cache.polygon.push(polygon);
-        
-        polygon.setMap(this.getMap());
-                
-        if (typeof listeners === 'object'){
-            for (evt in listeners) {
-                google.maps.event.addListener(polygon, evt, listeners[evt]);
-            }
-        }
-        
-        return polygon;
-
-    },
-    
-    /**
-     * Creates an Info Window.
-     * @param {Object} inwin an Info Window configuration
-     * @param {GLatLng} point the point to show the Info Window at
-     * @param {GMarker} marker a marker to attach the Info Window to
-     */
-    createInfoWindow : function(inwin, point, marker){
-        
-        var me = this, infoWindow = new google.maps.InfoWindow({
-            content: inwin.content,
-            position: point
-        });
-        
-        if (marker) {
-            google.maps.event.addListener(marker, 'click', function(){
-                me.hideAllInfoWindows();
-                infoWindow.open(me.getMap());
-            });
-        }
-        
-        this.cache.infowindow.push(infoWindow);
-
-        return infoWindow;
-
-    },
-    // private
-    hideAllInfoWindows : function(){
-        for (var i = 0; i &lt; this.cache.infowindow.length; i++) {
-            this.cache.infowindow[i].close();
-        }
-    },
-    // private
-    clearMarkers : function(){
-        
-        this.hideAllInfoWindows();
-        this.hideMarkers();
-
-    },
-    // private
-    hideMarkers : function(){
-        Ext.each(this.cache.marker, function(mrk){
-            mrk.setMap(null);
-        });
-    },
-    // private
-    showMarkers : function(){
-        Ext.each(this.cache.marker, function(mrk){
-            mrk.setMap(this.getMap());
-        },this);
-    },
-    /**
-     * Looks up and address and optionally add a marker, center the map to this location, or
-     * clear other markers. Sample usage:
-     * &lt;pre&gt;&lt;code&gt;
-buttons: [
-    {
-        text: 'Fenway Park',
-        handler: function(){
-            var addr = '4 Yawkey Way, Boston, MA, 02215-3409, USA';
-            Ext.getCmp('my_map').geoCodeLookup(addr, undefined, false, true, undefined);
-        }
-    },{
-        text: 'Zoom Fenway Park',
-        handler: function(){
-            Ext.getCmp('my_map').zoomLevel = 19;
-            var addr = '4 Yawkey Way, Boston, MA, 02215-3409, USA';
-            Ext.getCmp('my_map').geoCodeLookup(addr, undefined, false, true, undefined);
-        }
-    },{
-        text: 'Low Accuracy',
-        handler: function(){
-            Ext.getCmp('my_map').geoCodeLookup('Paris, France', undefined, false, true, undefined);
-        }
-    },{
-
-        text: 'Bogus Address',
-        handler: function(){
-            var addr = 'Some Fake, Address, For, Errors';
-            Ext.getCmp('my_map').geoCodeLookup(addr, undefined, false, true, undefined);
-        }
-    }
-]
-     * &lt;/code&gt;&lt;/pre&gt;
-     * @param {String} addr the address to lookup.
-     * @param {Object} marker the marker to add (optional).
-     * @param {Boolean} clear clear other markers before creating this marker
-     * @param {Boolean} center true to set this point as the center of the map.
-     * @param {Object} listeners a listeners config
-     * @param {Boolean} adaptZoom true to set the zoom to position accuracy
-     */
-    geoCodeLookup : function(addr, marker, clear, center, listeners, adaptZoom) {
-        
-        if (!this.geocoder) {
-            this.geocoder = new google.maps.Geocoder();
-        }
-        this.geocoder.geocode({
-    			address: addr
-    		}, this.addAddressToMap.createDelegate(this, [addr, marker, clear, center, listeners, adaptZoom], true));
-        
-    },
-  	// private 
-  	centerOnClientLocation : function(){
-  		this.getClientLocation(function(loc){
-  			var point = new google.maps.LatLng(loc.latitude,loc.longitude);
-        this.getMap().setCenter(point, this.zoomLevel);
-        this.lastCenter = point;
-  		});
-  	},
-  	// private
-  	getClientLocation : function(fn, errorFn){
-  		if (!errorFn) {
-          errorFn = Ext.emptyFn;
-      }
-  		if (!this.clientGeo) {
-  			this.clientGeo = google.gears.factory.create('beta.geolocation');
-  		}
-  		geo.getCurrentPosition(fn.createDelegate(this), errorFn);
-  	},
-    // private
-    addAddressToMap: function(response, status, addr, marker, clear, center, listeners, adaptZoom){
-        if (!response || status !== 'OK') {
-            this.respErrorMsg(status);
-        }
-        else
-        {
-            var place = response[0].geometry.location,
-			    accuracy = this.getLocationTypeInfo(response[0].geometry.location_type,'level'),
-			    reqAccuracy = this.getLocationTypeInfo(this.minGeoAccuracy,'level');
-            if (accuracy === 0) {
-                this.geoErrorMsg(this.geoErrorTitle, this.geoErrorMsgUnable);
-            }else{
-                if (accuracy &lt; reqAccuracy) {
-                    this.geoErrorMsg(this.geoErrorTitle, String.format(this.geoErrorMsgAccuracy, response[0].geometry.location_type, this.getLocationTypeInfo(response[0].geometry.location_type,'msg')));
-                }else{
-                  
-                    if(adaptZoom){                      
-                      this.getMap().setZoom(accuracy*10);
-                      this.zoomLevel = accuracy*8;
-                    }                  
-                                      
-                    point = new google.maps.LatLng(place.lat(),place.lng());
-                    if (center){
-                        this.getMap().setCenter(point, this.zoomLevel);
-                        this.lastCenter = point;
-                    }
-                    if (marker &amp;&amp; typeof marker === 'object') {
-                        if (!marker.title){
-                            marker.title = response.formatted_address;
-                        }
-                        var mkr = this.addMarker(point, marker, clear, false, listeners);
-                        if (marker.callback){
-                          marker.callback.call(this, mkr, point);
-                        }
-                    }
-                }
-            }
-        }
-        
-    },
-    // private
-    geoErrorMsg : function(title,msg){
-        if (this.displayGeoErrors) {
-            Ext.MessageBox.alert(title,msg);
-        }
-    },
-    // private
-    respErrorMsg : function(code){
-        Ext.each(this.respErrors, function(obj){
-            if (code == obj.code){
-                Ext.MessageBox.alert(this.respErrorTitle, obj.msg);
-            }
-        }, this);
-    },
-    // private
-    getLocationTypeInfo: function(location_type,property){
-      var val = 0;
-      Ext.each(this.locationTypes, function(itm){
-        if (itm.code === location_type){
-          val = itm[property];
-        }
-      });
-      return val;
-    }
-});
-
-Ext.reg('gmappanel', Ext.ux.GMapPanel3);
Index: main/plugin-cms/resources/js/Ext/ux/GMapPanel3.i18n.js
===================================================================
--- main/plugin-cms/resources/js/Ext/ux/GMapPanel3.i18n.js	(revision 0)
+++ main/plugin-cms/resources/js/Ext/ux/GMapPanel3.i18n.js	(working copy)
@@ -30,27 +30,27 @@
     respErrors: [{
             code: 'UNKNOWN_ERROR',
             //msg: 'A geocoding or directions request could not be successfully processed, yet the exact reason for the failure is not known.' 
-            msg : "<i18n:text i18n:catalogue='plugin.maps' i18n:key='PLUGINS_CMS_GEOCODE_GMAP_UNKNOWN_ERROR'/>"
+            msg : "<i18n:text i18n:catalogue='plugin.cms' i18n:key='PLUGINS_CMS_GEOCODE_GMAP_UNKNOWN_ERROR'/>"
         },{
             code: 'ERROR',
 //            msg: 'There was a problem contacting the Google servers.'
-              msg: "<i18n:text i18n:catalogue='plugin.maps' i18n:key='PLUGINS_CMS_GEOCODE_GMAP_ERROR'/>"
+              msg: "<i18n:text i18n:catalogue='plugin.cms' i18n:key='PLUGINS_CMS_GEOCODE_GMAP_ERROR'/>"
         },{
             code: 'ZERO_RESULTS',
             //msg: 'The request did not encounter any errors but returns zero results.'
-            msg: "<i18n:text i18n:catalogue='plugin.maps' i18n:key='PLUGINS_CMS_GEOCODE_GMAP_ZERO_RESULTS'/>"
+            msg: "<i18n:text i18n:catalogue='plugin.cms' i18n:key='PLUGINS_CMS_GEOCODE_GMAP_ZERO_RESULTS'/>"
         },{
             code: 'INVALID_REQUEST',
             //msg: 'This request was invalid.' 
-            msg: "<i18n:text i18n:catalogue='plugin.maps' i18n:key='PLUGINS_CMS_GEOCODE_GMAP_ERROR'/>"
+            msg: "<i18n:text i18n:catalogue='plugin.cms' i18n:key='PLUGINS_CMS_GEOCODE_GMAP_ERROR'/>"
         },{
             code: 'REQUEST_DENIED',
             //msg: 'The webpage is not allowed to use the geocoder for some reason.' 
-            msg: "<i18n:text i18n:catalogue='plugin.maps' i18n:key='PLUGINS_CMS_GEOCODE_GMAP_ERROR'/>"
+            msg: "<i18n:text i18n:catalogue='plugin.cms' i18n:key='PLUGINS_CMS_GEOCODE_GMAP_ERROR'/>"
         },{
             code: 'OVER_QUERY_LIMIT',
             //msg: 'The webpage has gone over the requests limit in too short a period of time.' 
-            msg: "<i18n:text i18n:catalogue='plugin.maps' i18n:key='PLUGINS_CMS_GEOCODE_GMAP_ERROR'/>"
+            msg: "<i18n:text i18n:catalogue='plugin.cms' i18n:key='PLUGINS_CMS_GEOCODE_GMAP_ERROR'/>"
     }],
     /**
      * @cfg {Array} locationTypes

Property changes on: main\plugin-cms\resources\js\Ext\ux\GMapPanel3.i18n.js
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native

Index: main/plugin-cms/src/org/ametys/cms/workflow/EditContentFunction.java
===================================================================
--- main/plugin-cms/src/org/ametys/cms/workflow/EditContentFunction.java	(revision 26911)
+++ main/plugin-cms/src/org/ametys/cms/workflow/EditContentFunction.java	(working copy)
@@ -796,6 +796,12 @@
                     geocodeValues[i] = Double.parseDouble(values[i]);
                     i++;
                     geocodeValues[i] = Double.parseDouble(values[i]);
+                    
+                    // TODO [Comment from LTE] Validate metadata. Need a DoubleValidator ??
+                    if (_validateMetadata(cType, metadataDefinition, metadataPath, allErrors, geocodeValues))
+                    {
+                        form.setField(metadataName, geocodeValues);
+                    }
                 }
                 catch (NumberFormatException e)
                 {
@@ -805,12 +811,6 @@
                 }
             }
         }
-        
-        // TODO [Comment from LTE] Validate metadata. Need a DoubleValidator ??
-        if (_validateMetadata(cType, metadataDefinition, metadataPath, allErrors, geocodeValues))
-        {
-            form.setField(metadataName, geocodeValues);
-        }
     }
 
     /**
Index: main/plugin-cms/src/org/ametys/cms/lucene/MetadataIndexer.java
===================================================================
--- main/plugin-cms/src/org/ametys/cms/lucene/MetadataIndexer.java	(revision 26911)
+++ main/plugin-cms/src/org/ametys/cms/lucene/MetadataIndexer.java	(working copy)
@@ -231,6 +231,9 @@
             case DATETIME: // index only alone
                 indexDateTimeMetadata(metadata, prefix, document, name, fieldName);
                 break;
+            case GEOCODE: // index latitude and longitude
+                indexGeocodeMetadata(metadata, prefix, document, name, fieldName);
+                break;
             default:
                 // do not index REFERENCE
                 break;
@@ -372,6 +375,39 @@
     }
     
     /**
+     * Index a datetime metadata
+     * @param metadata
+     * @param prefix The path of parent metadata 
+     * @param document
+     * @param name
+     * @param fieldName 
+     */
+    public void indexGeocodeMetadata(CompositeMetadata metadata, String prefix, Document document, String name, String fieldName)
+    {
+        CompositeMetadata values = metadata.getCompositeMetadata(name);
+        if (values != null)
+        {
+            if (values.hasMetadata("latitude") && values.hasMetadata("longitude"))
+            {
+                String latitude = values.getString("latitude");
+                String longitude = values.getString("longitude");
+                document.add(new Field(FieldNames.GEOCODE_COORDINATES, latitude + ',' + longitude, Store.YES, Index.NOT_ANALYZED));
+                
+                document.add(new Field(prefix + fieldName + "$latitude", latitude, Store.YES, Index.NOT_ANALYZED));
+                document.add(new Field(prefix + fieldName + "$longitude", longitude, Store.YES, Index.NOT_ANALYZED));
+                
+            }
+            else
+            {
+                if (_logger.isWarnEnabled())
+                {
+                    _logger.warn("The geocode must contain 2 values.");
+                }
+            }
+        }
+    }
+    
+    /**
      * Index a file metadata
      * @param parentPath The path of parent metadata
      * @param metadata
Index: main/plugin-cms/src/org/ametys/cms/lucene/FieldNames.java
===================================================================
--- main/plugin-cms/src/org/ametys/cms/lucene/FieldNames.java	(revision 26911)
+++ main/plugin-cms/src/org/ametys/cms/lucene/FieldNames.java	(working copy)
@@ -44,4 +44,7 @@
     public static final String MIME_TYPES = "mime-types";
     /** The length of a resource. */
     public static final String LENGTH = "length";
+    
+    /** Coordinate field name (bound to geocode) */
+    public static final String GEOCODE_COORDINATES = "geocode-coordinates";
 }
Index: main/plugin-cms/src/org/ametys/cms/contenttype/MetadataManager.java
===================================================================
--- main/plugin-cms/src/org/ametys/cms/contenttype/MetadataManager.java	(revision 26911)
+++ main/plugin-cms/src/org/ametys/cms/contenttype/MetadataManager.java	(working copy)
@@ -514,33 +514,22 @@
             CompositeMetadata values = metadata.getCompositeMetadata(metadataName);
             if (values != null)
             {
-                try
+                if (values.hasMetadata("latitude") && values.hasMetadata("longitude"))
                 {
-                    Double latitude = null;
-                    Double longitude = null;
-                    if (values.hasMetadata("latitude")) 
-                    {
-                        latitude = values.getDouble("latitude");
-                    }
-                    if (values.hasMetadata("longitude")) 
-                    {
-                        longitude = values.getDouble("longitude");
-                    }
-
-                    if (longitude != null && latitude != null)
-                    {
-                        String[] latLng = new String[] {String.valueOf(latitude), String.valueOf(longitude)};
-                        
-                        AttributesImpl attrs = new AttributesImpl();
-                        attrs.addCDATAAttribute("latitude", latLng[0]);
-                        attrs.addCDATAAttribute("longitude", latLng[1]);
-
-                        XMLUtils.createElement(contentHandler, metadataName, attrs, StringUtils.join(latLng, ','));
-                    }
+                    String[] latLng = new String[] {values.getString("latitude"), values.getString("longitude")};
+                    
+                    AttributesImpl attrs = new AttributesImpl();
+                    attrs.addCDATAAttribute("latitude", latLng[0]);
+                    attrs.addCDATAAttribute("longitude", latLng[1]);
+                    
+                    XMLUtils.createElement(contentHandler, metadataName, attrs, StringUtils.join(latLng, ','));
                 }
-                catch (ArrayIndexOutOfBoundsException e)
+                else
                 {
-                    getLogger().warn("The geocode must contain 2 values.", e);
+                    if (getLogger().isWarnEnabled())
+                    {
+                        getLogger().warn("The geocode must contain 2 values.");
+                    }
                 }
             }
         }