[Commits] r1557 - in sandbox/ahocevar/playground/ux/Printing/ux: data plugins widgets widgets/form

commits at geoext.org commits at geoext.org
Fri Dec 4 22:54:31 CET 2009


Author: ahocevar
Date: 2009-12-04 22:54:31 +0100 (Fri, 04 Dec 2009)
New Revision: 1557

Added:
   sandbox/ahocevar/playground/ux/Printing/ux/data/PrintPage.js
   sandbox/ahocevar/playground/ux/Printing/ux/plugins/PrintPageField.js
   sandbox/ahocevar/playground/ux/Printing/ux/plugins/PrintProviderField.js
   sandbox/ahocevar/playground/ux/Printing/ux/widgets/form/
   sandbox/ahocevar/playground/ux/Printing/ux/widgets/form/PrintForm.js
   sandbox/ahocevar/playground/ux/Printing/ux/widgets/form/SimplePrint.js
Removed:
   sandbox/ahocevar/playground/ux/Printing/ux/plugins/PrintLayoutField.js
   sandbox/ahocevar/playground/ux/Printing/ux/plugins/PrintPageAttributeField.js
   sandbox/ahocevar/playground/ux/Printing/ux/widgets/SimplePrint.js
Modified:
   sandbox/ahocevar/playground/ux/Printing/ux/data/PrintProvider.js
Log:
finished refactoring. now add apidocs.

Added: sandbox/ahocevar/playground/ux/Printing/ux/data/PrintPage.js
===================================================================
--- sandbox/ahocevar/playground/ux/Printing/ux/data/PrintPage.js	                        (rev 0)
+++ sandbox/ahocevar/playground/ux/Printing/ux/data/PrintPage.js	2009-12-04 21:54:31 UTC (rev 1557)
@@ -0,0 +1,280 @@
+/**
+ * Copyright (c) 2008-2009 The Open Source Geospatial Foundation
+ * 
+ * Published under the BSD license.
+ * See http://svn.geoext.org/core/trunk/geoext/license.txt for the full text
+ * of the license.
+ */
+Ext.namespace("GeoExt.ux.data");
+
+/** api: (define)
+ *  module = GeoExt.ux.data
+ *  class = PrintPage
+ *  base_link = `Ext.util.Observable <http://extjs.com/deploy/dev/docs/?class=Ext.util.Observable>`_
+ */
+
+/** api: constructor
+ *  .. class:: PrintPage
+ * 
+ *  Provides a representation of a print page for
+ *  :class:`GeoExt.ux.data.PrintProvider`.
+ */
+GeoExt.ux.data.PrintPage = Ext.extend(Ext.util.Observable, {
+    
+    /** api:config[printProvider]
+     * :class:`GeoExt.ux.data.PrintProvider` The print provider to use with
+     * this page.
+     */
+    
+    /** private: property[printProvider]
+     *  :class:`GeoExt.ux.data.PrintProvider`
+     */
+    printProvider: null,
+    
+    /** api: config[layer]
+     *  ``OpenLayers.Layer.Vector`` Optional. If provided, feature and handle
+     *  will be added to that layer.
+     */
+    
+    /** api: property[feature]
+     *  ``OpenLayers.Feature.Vector`` Feature representing the page extent.
+     *  Read-only.
+     */
+    feature: null,
+    
+    /** api: property[handle]
+     *  ``OpenLayers.Feature.Vector`` Feature providing the scale/rotation
+     *  handle for the page. Read-only.
+     */
+    handle: null,
+    
+    scale: null,
+    
+    rotation: null,
+    
+    /** api:config[customParams]
+     *  ``Object`` Key-value pairs of additional parameters that the
+     *  printProvider will send to the print service for this page.
+     */
+
+    /** api: property[customParams]
+     *  ``Object`` Key-value pairs of additional parameters that the
+     *  printProvider will send to the print service for this page.
+     */
+    customParams: null,
+    
+    /** private: method[constructor]
+     *  Private constructor override.
+     */
+    constructor: function(config) {
+        this.initialConfig = config;
+        Ext.apply(this, config);
+        delete this.layer;
+        
+        if(!this.customParams) {
+            this.customParams = {};
+        }
+        
+        this.addEvents([
+            /** api: events[change]
+             *  Triggered when any of the page properties have changed
+             *  
+             *  Listener arguments:
+             *  * printPage - :class:`GeoExt.ux.data.PrintPage` this printPage
+             */
+            "change"
+        ]);
+
+        this.feature = new OpenLayers.Feature.Vector(
+            OpenLayers.Geometry.fromWKT("POLYGON((-1 -1,1 -1,1 1,-1 1,-1 -1))"));
+        this.handle = new OpenLayers.Feature.Vector(
+            new OpenLayers.Geometry.Point(0,0));
+        if(config.layer) {
+            config.layer.addFeatures([this.feature, this.handle]);
+        }
+
+        this.printProvider.on({
+            "layoutchange": function() {
+                this.updateByHandle(true);
+            },
+            scope: this
+        });
+
+        GeoExt.ux.data.PrintPage.superclass.constructor.apply(this, arguments);
+    },
+
+    /** api: method[getCenter]
+     *  :return: ``OpenLayers.LonLat``
+     *  
+     *  Returns the current page center.
+     */
+    getCenter: function() {
+        return this.feature.geometry.getBounds().getCenterLonLat();
+    },
+    
+    /** api: method[setScale]
+     *  :param scale: ``Float`` The new scale.
+     * 
+     *  Updates the page geometry to match a given scale. Since this takes the
+     *  current layout of the printProvider into account, this can be used to
+     *  update the page geometry when the layout has changed.
+     */
+    setScale: function(scale) {
+        var bounds = this.calculatePageBounds(scale);
+        var geom = bounds.toGeometry();
+        var rotation = this.rotation;
+        if(rotation != 0) {
+            geom.rotate(-rotation, geom.getCentroid());
+        }
+        this.scale = scale;
+        this.updateFeature(geom);
+    },
+    
+    /** api: method[setCenter]
+     *  :param scale: ``OpenLayers.LonLat`` The new center.
+     * 
+     *  Moves the page geometry to a new center.
+     */
+    setCenter: function(center) {
+        var geom = this.feature.geometry;
+        var oldCenter = geom.getBounds().getCenterLonLat();
+        var dx = center.lon - oldCenter.lon;
+        var dy = center.lat - oldCenter.lat;
+        geom.move(dx, dy);
+        this.updateFeature(geom);
+    },
+    
+    /** api: method[setRotation]
+     *  :param rotation: ``Float`` The new rotation.
+     *  
+     *  Sets a new rotation for the page geometry.
+     */
+    setRotation: function(rotation) {
+        var geom = this.feature.geometry;
+        geom.rotate(this.rotation - rotation, geom.getCentroid());
+        this.rotation = rotation;
+        this.updateFeature(geom);
+    },
+    
+    /** api: method[fitPage]
+     *  :param map: ``OpenLayers.Map`` The map to fit the page to.
+     * 
+     *  Fits the page layout to the current map extent, using the smallest
+     *  scale that entirely fits the extent.
+     */
+    fitPage: function(map) {
+        this.setCenter(map.getCenter());
+        var extent = map.getExtent();
+        var scale;
+        this.printProvider.scales.each(function(rec) {
+            scale = rec.get("value");
+            return !extent.containsBounds(this.calculatePageBounds(scale));
+        }, this)
+        this.setScale(scale);
+    },
+
+    /** api: method[updateByHandle]
+     *  :param updateHandle: ``Boolean`` If set to false, the handle location
+     *      will not be aligned with the feature after updating. Default is
+     *      true.
+     *  
+     *  Updates scale and rotation by the current handle location.
+     */
+    updateByHandle: function(updateHandle) {
+        var f = this.feature;
+        
+        var hLoc = this.handle.geometry.getBounds().getCenterLonLat();
+        var center = f.geometry.getBounds().getCenterLonLat();
+        var dx = hLoc.lon - center.lon;
+        var dy = hLoc.lat - center.lat;
+        var rotation = Math.round(Math.atan2(dx, dy) * 180 / Math.PI);
+
+        var geom = this.handle.geometry;
+        var dist = f.geometry.getCentroid().distanceTo(geom);
+        var scaleFits = [], distHash = {};
+        this.printProvider.scales.each(function(rec){
+            var scale = rec.get("value");
+            var bounds = this.calculatePageBounds(scale);
+            var d = Math.abs((bounds.getHeight() / 2) - dist).limitSigDigs(8);
+            scaleFits.push(d);
+            distHash[d] = scale;
+        }, this);
+        var min = scaleFits.concat().sort(function(a,b){return a<b?-1:1;})[0];
+        var scale = distHash[min];
+        
+        var bounds = this.calculatePageBounds(scale);
+        var geom = bounds.toGeometry();
+        geom.rotate(-rotation, geom.getCentroid());
+        
+        this.scale = scale;
+        this.rotation = rotation;
+        this.updateFeature(geom, updateHandle);
+    },
+
+    /** private: method[updateFeature]
+     *  :param geometry: ``OpenLayers.Geometry`` New geometry for the feature.
+     *      If not provided, the existing geometry will be left unchanged.
+     *  :param updateHandle: ``Boolean`` If set to false, only the feature
+     *      will be updated, but the handle will not be aligned. Defaults to
+     *      true.
+     *      
+     *  Updates the page feature with a new geometry and aligns the handle
+     *  with it.
+     */
+    updateFeature: function(geometry, updateHandle) {
+        var f = this.feature;
+        geometry.id = f.geometry.id;
+        f.geometry = geometry;
+        f.layer && f.layer.drawFeature(f);
+        
+        if(updateHandle !== false) {
+            this.updateHandle();
+        }
+        this.fireEvent("change", this)
+    },
+    
+    /** api: method[updateHandle]
+     *  Updates the handle position to align with the page feature.
+     */
+    updateHandle: function() {
+        var f = this.feature;
+        var h = this.handle;
+        var hLoc = this.calculateHandleLocation();
+        var geom = new OpenLayers.Geometry.Point(hLoc.lon, hLoc.lat);
+        geom.id = h.geometry.id;
+        h.geometry = geom;
+        h.layer && h.layer.drawFeature(h);
+    },
+    
+    /** private: method[calculateHandleLocation]
+     *  :return: ``OpenLayers.LonLat`` The location of the scale/rotation
+     *      handle.
+     *  
+     *  Calculates the position of the scale/rotation handle for this
+     *  page feature.
+     */
+    calculateHandleLocation: function() {
+        var c = this.feature.geometry.components[0].components;
+        var top = new OpenLayers.Geometry.LineString([c[2], c[3]]);
+        return top.getBounds().getCenterLonLat();
+    },
+
+    /** private: method[calculatePageBounds]
+     *  :param scale: ``Float`` Scale to calculate the page bounds for.
+     *  :return: ``OpenLayers.Bounds``
+     *  
+     *  Calculates the page bounds for a given scale.
+     */
+    calculatePageBounds: function(scale) {
+        var geom = this.feature.geometry;
+        var size = this.printProvider.getLayout().get("size");
+        var unitsRatio = OpenLayers.INCHES_PER_UNIT[this.printProvider.units];
+        var w = size.width / 72 / unitsRatio * scale / 2;
+        var h = size.height / 72 / unitsRatio * scale / 2;
+        var center = geom.getBounds().getCenterLonLat();
+        
+        return new OpenLayers.Bounds(center.lon - w, center.lat - h,
+            center.lon + w, center.lat + h);
+    }
+
+});
\ No newline at end of file

Modified: sandbox/ahocevar/playground/ux/Printing/ux/data/PrintProvider.js
===================================================================
--- sandbox/ahocevar/playground/ux/Printing/ux/data/PrintProvider.js	2009-12-04 20:44:43 UTC (rev 1556)
+++ sandbox/ahocevar/playground/ux/Printing/ux/data/PrintProvider.js	2009-12-04 21:54:31 UTC (rev 1557)
@@ -20,40 +20,69 @@
  */
 GeoExt.ux.data.PrintProvider = Ext.extend(Ext.util.Observable, {
     
-    /** api:config[url]
+    /** api: config[url]
      *  ``String`` Base url of the print service. Only required if
      *  :ref:`GeoExt.ux.data.PrintProvider.capabilities` is not provided. This
      *  is usually something like ``http://path/to/mapfish/print`` for Mapfish,
      *  and ``http://path/to/geoserver/pdf`` for GeoServer with the printing
-     *  extension installed. This property is usually used when the print
-     *  service is at the same origin as the application (or accessible via
-     *  proxy), and the request method is set to ``POST`` (see
+     *  extension installed. This property is useful when the print service is
+     *  at the same origin as the application (or accessible via proxy), and
+     *  the request method is set to ``POST`` (see
      *  :ref:`GeoExt.ux.data.PrintProvider.method`).
      */
     
-    /** private:property[url]
-     *  ``String`` Base url of the print service. Will always have a trailing "/".
+    /** private:  property[url]
+     *  ``String`` Base url of the print service. Will always have a trailing
+     *  "/".
      */
     url: null,
     
-    /** api:config[capabilities]
+    /** api: config[units]
+     *  ``String`` Map units to use with this printProvider. These can e.g. be
+     *  taken from an ``OpenLayers.Map``:
+     *  
+     *  .. code-block:: javascript
+     *      units: map.baseLayer.units,
+     */
+    
+    /** api: property[units]
+     *  ``String`` Map units to use with this printProvider. Must be set
+     *  before print pages can be created. If a
+     *  :class:`GeoExt.ux.form.PrintForm` is configured with this
+     *  printProvider, this will be taken care of properly.
+     */
+    units: null,
+    
+    /** api: property[dpi]
+     *  ``String`` the name of the currently used layout. Read-only, use
+     *      :ref:`GeoExt.ux.data.PrintProvider.setDpi` to set the value.
+     */
+    dpi: null,
+
+    /** api: property[layout]
+     *  ``String`` the name of the currently used layout. Read-only, use
+     *      :ref:`GeoExt.ux.data.PrintProvider.setLayout` to set the value.
+     */
+    layout: null,
+
+    /** api: config[capabilities]
      *  ``Object`` Capabilities of the print service. Only required if
      *  :ref:`GeoExt.ux.data.PrintProvider.url` is not provided. This is the
      *  object returned by the ``info.json`` endpoint of the print service,
      *  and is usually obtained by including a script tag pointing to
      *  ``http://path/to/printservice/info.json?var=myvar`` in the head of the
      *  html document, making the capabilities accessible as ``window.myvar``.
-     *  This property is usually used when accessing a remote print service
-     *  with no proxy available, using the ``GET`` method (see
+     *  This property is useful when accessing a remote print service with no
+     *  proxy available, using the ``GET`` method (see
      *  :ref:`GeoExt.ux.data.PrintProvider.method`).
      */
     
-    /** private:property[capabilities]
+    /** private: property[capabilities]
      *  ``Object`` Capabilities as returned from the print service.
      */
     capabilities: null,
     
-    /** api:config[method]
+    /** api: config[method]
      *  ``String`` Either ``POST`` or ``GET`` (case-sensitive). Method to use
      *  when talking to the servlet. If the print service is at the same
      *  origin as the application (or accessible via proxy), then ``POST``
@@ -62,24 +91,26 @@
      *  exceeding the maximum length. Default is ``POST``.
      */
     
-    /** private:property[method]
+    /** private: property[method]
      *  ``String`` Either ``POST`` or ``GET`` (case-sensitive). Method to use
      *  when talking to the servlet.
      */
     method: "POST",
 
-    /** api:config[customData]
-     *  ``Object`` Custom data to be sent to the print service. Optional. This
-     *  is e.g. useful for complex layout definitions on the server side that
-     *  require additional parameters.
+    /** api: config[customParams]
+     *  ``Object`` Key-value pairs of custom data to be sent to the print
+     *  service. Optional. This is e.g. useful for complex layout definitions
+     *  on the server side that require additional parameters.
      */
     
-    /** private:property[customData]
-     *  ``Object`` Custom data to be sent to the print service.
+    /** api: property[customParams]
+     *  ``Object`` Key-value pairs of custom data to be sent to the print
+     *  service. Optional. This is e.g. useful for complex layout definitions
+     *  on the server side that require additional parameters.
      */
-    customData: null,
+    customParams: null,
     
-    /** api:property[scales]
+    /** api: property[scales]
      *  ``Ext.data.JsonStore`` read-only. A store representing the scales
      *  available.
      *  
@@ -89,7 +120,7 @@
      */
     scales: null,
     
-    /** api:property[dpis]
+    /** api: property[dpis]
      *  ``Ext.data.JsonStore`` read-only. A store representing the dpis
      *  available.
      *  
@@ -99,7 +130,7 @@
      */
     dpis: null,
         
-    /** api:property[layouts]
+    /** api: property[layouts]
      *  ``Ext.data.JsonStore`` read-only. A store representing the layouts
      *  available.
      *  
@@ -110,15 +141,19 @@
      */
     layouts: null,
     
-    /** private: method[constructor]
+    /** private:  method[constructor]
      *  Private constructor override.
      */
     constructor: function(config) {
         this.initialConfig = config;
         Ext.apply(this, config);
         
+        if(!this.customParams) {
+            this.customParams = {};
+        }
+
         this.addEvents([
-            /** api: events[loadcapabilities]
+            /** api: events[capabilitiesload]
              *  Triggered when the capabilities have finished loading. This
              *  event will only fire when
              *  :ref:`GeoExt.ux.data.PrintProvider.capabilities` is not
@@ -129,13 +164,32 @@
              *    PrintProvider
              *  * capabilities - ``Object`` the capabilities
              */
-            "loadcapabilities"
+            "capabilitiesload",
+            
+            /** api: events[layoutchange]
+             *  Triggered when the layout is changed.
+             *  
+             *  Listener arguments:
+             *  * printProvider - :class:`GeoExt.ux.data.PrintProvider` this
+             *    PrintProvider
+             *  * layout - ``Ext.data.Record`` the new layout
+             */
+            "layoutchange",
+
+            /** api: events[dpichange]
+             *  Triggered when the dpi value is changed.
+             *  
+             *  Listener arguments:
+             *  * printProvider - :class:`GeoExt.ux.data.PrintProvider` this
+             *    PrintProvider
+             *  * dpi - ``Ext.data.Record`` the new dpi record
+             */
+            "dpichange"
         ]);
         
-        GeoExt.ux.data.PrintProvider.superclass.constructor.apply(this, arguments);
-
         this.scales = new Ext.data.JsonStore({
             root: "scales",
+            sortInfo: {field: "value", direction: "DESC"},
             fields: ["name", {name: "value", type: "float"}]
         });
         
@@ -161,130 +215,69 @@
             }
             this.loadCapabilities();
         }
+
+        GeoExt.ux.data.PrintProvider.superclass.constructor.apply(this, arguments);
     },
     
-    /** private:method[loadCapabilities]
-     */
-    loadCapabilities: function() {
-        var url = this.url + "info.json";
-        Ext.Ajax.request({
-            url: url,
-            disableCaching: false,
-            success: function(response) {
-                this.capabilities = Ext.decode(response.responseText);
-                this.loadStores();
-                this.fireEvent("loadcapabilities", this.capabilities);
-            },
-            scope: this
-        });
+    getLayout: function() {
+        return this.layouts.getAt(this.layouts.find("name", this.layout));
     },
     
-    /** private:method[loadStores]
-     */
-    loadStores: function() {
-        this.scales.loadData(this.capabilities);
-        this.scales.sort("value", "DESC");
-        this.dpis.loadData(this.capabilities);
-        this.dpis.sort("value", "ASC");
-        this.layouts.loadData(this.capabilities);
+    setLayout: function(layout) {
+        this.layout = layout;
+        this.fireEvent("layoutchange", this, this.getLayout());
     },
     
-    /** api:method[print]
+    getDpi: function() {
+        return this.dpis.getAt(this.dpis.find("value", this.dpi));
+    },
+    
+    setDpi: function(dpi) {
+        this.dpi = dpi;
+        this.fireEvent("dpichange", this, this.getDpi())
+    },
+
+    /** api: method[print]
      *  :param map: ``GeoExt.MapPanel``|``OpenLayers.Map`` The map to print.
-     *      If not provided, ``GeoExt.MapPanel.guess`` will be used to.
-     *  :param options: ``Object`` Print options.
-     *  
-     *  Print options:
-     *  * layout - ``Ext.data.Record``|``String`` the layout for the page.
-     *    One of the records or the ``name`` of one of the records of the
-     *    :ref:`GeoExt.ux.PrintProvider.layouts` store.
-     *  * dpi - ``Ext.data.Record``|``Float`` the dots per inch for the page.
-     *    One of the records or the ``value`` of one of the records of the
-     *    :ref:`GeoExt.ux.PrintProvider.dpis` store.
-     *  * customData - ``Object`` Additional data that will be sent to the
-     *    print service. Optional.
-     *  * layer - ``OpenLayers.Layer.Vector`` a layer containing one or more
-     *    features with geometries and attributes set by
-     *    :ref:`GeoExt.ux.PrintProvider.updateFeature`. For each feature, a
-     *    page will be created. The center and the rotation of the page will
-     *    be determined from the feature geometry, the scale will be taken
-     *    from the feature's ``scale`` attribute. A page title can be provided
-     *    in the feature's ``title`` property, and a page comment in the
-     *    feature's ``comment`` property. If the ``layer`` option is not
-     *    provided, the following additional options will be used to create a
-     *    single page PDF:
-     *  * center - ``OpenLayers.LonLat``|``Array`` center of a single-page
-     *    map. If not provided, the center of the map will be used.
-     *  * scale - ``Ext.data.Record``|``Float`` The scale of the page. One of
-     *    the records or the ``value`` of one of the records of the
-     *    :ref:`GeoExt.ux.PrintProvider.scales`. If not provided, the smallest
-     *    scale that fits the map viewport at the current zoom level will be
-     *    used.
-     *  * rotation: ``Float`` The page rotation in degrees, counting clockwise
-     *    from North. Optional.
-     *  * title - ``String`` The page title. Optional.
-     *  * comment - ``String`` A page comment. Optional.
+     *  :param pages: ``Array`` of :class:`GeoExt.ux.data.PrintPage`` pages to
+     *      print.
      * 
      *  Sends the print command to the print service and opens a new window
      *  with the resulting PDF.
      */
-    print: function(map, options) {
-        options = options || {};
-        
-        map = map || GeoExt.MapPanel.guess();
+    print: function(map, pages) {
         if(map instanceof GeoExt.MapPanel) {
             map = map.map;
         }
         
-        var layoutName = options.layout || this.layouts.getAt(0);
-        if(layoutName instanceof Ext.data.Record) {
-            layoutName = layoutName.get("name");
-        }
-        
-        var dpi = options.dpi || this.dpis.getAt(0);
-        if(dpi instanceof Ext.data.Record) {
-            dpi = dpi.get("value");
-        }
-        
-        var pages;
-        if(options.layer) {
-            pages = this.createPages(options.layer, options.layout);
-        } else {
-            var center = options.center || map.getCenter();
-            if(center instanceof OpenLayers.LonLat) {
-                center = [center.lon, center.lat]
-            }
-            
-            var scale = options.scale || this.getBestScale(map, layoutName);
-            if(scale instanceof Ext.data.Record) {
-                scale = scale.get("value");
-            }
-
-            pages = [{
-                mapTitle: options.title || "",
-                comment: options.comment || "",
-                center: center,
-                scale: scale,
-                rotation: options.rotation
-            }];
-        }
-
-        var layers = [];
+        var pagesLayer = pages[0].feature.layer;
+        var encodedLayers = [];
         Ext.each(map.layers, function(layer){
-            if(layer !== options.layer) {
+            if(layer !== pagesLayer) {
                 var enc = this.encodeLayer(layer);
-                enc && layers.push(enc);
+                enc && encodedLayers.push(enc);
             }
         }, this);
         
+        var encodedPages = [];
+        Ext.each(pages, function(page) {
+            var center = page.getCenter();
+            encodedPages.push(Ext.apply({
+                center: [center.lon, center.lat],
+                scale: page.scale,
+                rotation: page.rotation
+            }, page.customParams));
+        }, this)
+        
         var payload = Ext.apply({
-            pages: pages,
-            dpi: dpi,
-            units: map.baseLayer.units,
+            pages: encodedPages,
+            dpi: this.dpi,
+            units: this.units,
             srs: map.baseLayer.projection.getCode(),
-            layers: layers,
-            layout: layoutName
-        }, Ext.applyIf(options.customData, this.customData));
+            layers: encodedLayers,
+            layout: this.layout
+        }, this.customParams);
+        
         if(this.method === "GET") {
             window.open(this.capabilities.printURL + "?spec=" +
                 escape(Ext.encode(payload)));
@@ -295,84 +288,38 @@
                 success: function(response) {
                     window.open(Ext.decode(response.responseText).getURL);
                 }
-            })
+            });
         }
     },
     
-    fitPage: function(feature) {
-        var id = feature.geometry.id;
-        feature.geometry = feature.layer.map.getExtent().toGeometry();
-        feature.geometry.id = id;
-        this.updateFeature(feature,
-            {scale: this.getBestScale(feature.layer.map)});
-    },
-    
-    updatePage: function(feature, handle) {
-        this.updateFeature(feature, null, handle);
-    },
-    
-    /** api:method[getRotation]
-     *  :param feature: ``OpenLayers.Feature.Vector``
-     *  :param handle: ``OpenLayers.Feature.Vector`` optional rotation handle.
-     *      If provided, the rotation of the feature relative to the handle
-     *      will be calculated. Otherwise, the rotation of the current feature
-     *      will be returned.
-     *  :return: ``Float``
-     *  
-     *  Gets the rotation of a feature with a geometry originally created
-     *  using ``OpenLayers.Bounds.toGeometry()``. Rotation is measured
-     *  clockwise from North.
+    /** private: method[loadCapabilities]
      */
-    getRotation: function(feature, handle) {
-        if(!feature.geometry) {
-            return 0;
-        }
-        var anglePoint = handle && handle.geometry ?
-            handle.geometry.getBounds().getCenterLonLat() :
-            this.getHandleLocation(feature);
-        var center = feature.geometry.getBounds().getCenterLonLat();
-        var dx = anglePoint.lon - center.lon;
-        var dy = anglePoint.lat - center.lat;
-        return Math.round((Math.atan2(dx, dy) * 180 / Math.PI));
+    loadCapabilities: function() {
+        var url = this.url + "info.json";
+        Ext.Ajax.request({
+            url: url,
+            disableCaching: false,
+            success: function(response) {
+                this.capabilities = Ext.decode(response.responseText);
+                this.loadStores();
+                this.fireEvent("loadcapabilities", this.capabilities);
+            },
+            scope: this
+        });
     },
     
-    /** private:method[getHandleLocation]
-     *  :param feature: ``OpenLayers.Feature.Vector``
-     *  :return: ``OpenLayers.LonLat``
-     *  
-     *  Calculates the scale/rotation handle location for a feature.
+    /** private: method[loadStores]
      */
-    getHandleLocation: function(feature) {
-        var points = feature.geometry.components[0].components;
-        var top = new OpenLayers.Geometry.LineString([points[2], points[3]]);
-        return top.getBounds().getCenterLonLat();
+    loadStores: function() {
+        this.scales.loadData(this.capabilities);
+        this.dpis.loadData(this.capabilities);
+        this.layouts.loadData(this.capabilities);
+        
+        this.layout = this.layouts.getAt(0).get("name");
+        this.dpi = this.dpis.getAt(0).get("value");
     },
     
-    /** private:method[createPages]
-     *  :param layer: ``OpenLayers.Layer.Vector``
-     *  :param layout: ``String``
-     *  :return: ``Array``
-     *  
-     *  Creates pages from the features of the provided layer.
-     */
-    createPages: function(layer, layout) {
-        var pages = [];
-        Ext.each(layer.features, function(feature) {
-            if(feature.attributes.layout == layout) {
-                var center = feature.geometry.getBounds().getCenterLonLat();
-                pages.push({
-                    mapTitle: feature.attributes.title || "",
-                    comment: feature.attributes.comment || "",
-                    center: [center.lon, center.lat],
-                    scale: feature.attributes.scale,
-                    rotation: feature.attributes.rotation
-                })
-            }
-        }, this);
-        return pages;
-    },
-    
-    /** private:method[encodeLayer]
+    /** private: method[encodeLayer]
      *  :param layer: ``OpenLayers.Layer``
      *  :return: ``Object``
      * 
@@ -387,162 +334,11 @@
             }
         }
         return (encLayer && encLayer.type) ? encLayer : null;
-    },
-    
-    /** private:method[getLayoutBounds]
-     *  :param map: ``OpenLayers.Map``
-     *  :param scale: ``Float``
-     *  :param layout: ``Ext.data.Record``
-     *  :param center: ``Openlayers.LonLat`` optional.
-     *  :return: ``OpenLayers.Bounds``
-     * 
-     *  gets the bounds for a given map, scale and layout
-     */
-    getLayoutBounds: function(map, scale, layout, center) {
-        var size = layout.get("size");
-
-        var unitsRatio = OpenLayers.INCHES_PER_UNIT[map.baseLayer.units];
-        var w = size.width / 72 / unitsRatio * scale / 2;
-        var h = size.height / 72 / unitsRatio * scale / 2;
-        var center = center || map.getCenter() || new OpenLayers.LonLat(0, 0);
-        return new OpenLayers.Bounds(center.lon - w, center.lat - h,
-            center.lon + w, center.lat + h);
-    },
-    
-    /** api:method[getBestScale]
-     *  :param map: ``OpenLayers.Map``
-     *  :param layoutName: ``String`` Optional layout. If not provided, the
-     *      first available layout will be used.
-     *  :return: ``Float``
-     *  
-     *  Calculates the best scale for a given map and layout. The best scale
-     *  is considered the smallest one where the print page entirely fits
-     *  the current map extent.
-     */
-    getBestScale: function(map, layoutName) {
-        if(map instanceof GeoExt.MapPanel) {
-            map = map.map;
-        }
-        var layoutIndex = layoutName ?
-            this.layouts.find("name", layoutName) : 0;
-        var layout = this.layouts.getAt(layoutIndex);
-        var extent = map.getExtent() || map.baseLayer.maxExtent;
-
-        var bounds, scale;
-        this.scales.each(function(rec) {
-            scale = rec.get("value");
-            bounds = this.getLayoutBounds(map, scale, layout);
-            if(extent.containsBounds(bounds)) {
-                return false;
-            }
-        }, this)
-        return scale;
-    },
-    
-    getScale: function(feature, handle) {
-        var layoutName = feature.attributes.layout;
-        var layout = this.layouts.getAt(
-            this.layouts.find("name", layoutName));
-        var dist = feature.geometry.getCentroid().distanceTo(handle.geometry);
-        scaleFits = [];
-        this.scales.each(function(rec){
-            var bounds = this.getLayoutBounds(
-                feature.layer.map,
-                rec.get("value"),
-                layout,
-                feature.geometry.getBounds().getCenterLonLat()
-            );
-            scaleFits.push(String(Math.abs((bounds.getHeight() / 2) - dist)));
-        }, this);
-        var min = scaleFits.concat().sort()[0];
-        var scale = this.scales.getAt(scaleFits.indexOf(min));
-        return scale.get("value");
-    },
-    
-    /** api:function[updateFeature]
-     *  :param feature: ``OpenLayers.Feature.Vector`` The feature to update.
-     *  :param attributes: ``Object`` Attributes that will be applied to the
-     *      feature, overriding existing attributes.
-     *  :param handle: ``OpenLayers.Feature.Vector`` Optional scale/rotation
-     *      handle. If provided, the handle will be used to change scale and
-     *      rotation of the feature.
-     *      
-     *  Updates a feature to represent a print page. The updated feature will
-     *  have a ``scale``, ``layout`` and ``rotation`` attribute. The geometry
-     *  will be the bounds of the print page in map units. Note that this
-     *  method only works for features that are on a layer which is on a map.
-     */
-    updateFeature: function(feature, attributes, handle) {
-        attributes = attributes || {};
-        if(handle && handle.geometry) {
-            attributes.rotation = this.getRotation(feature, handle);
-            attributes.scale = this.getScale(feature, handle);
-        }
-
-        var modified = false;
-        for(var i in attributes) {
-            if(attributes[i] != feature.attributes[i]) {
-                modified = true;
-            }
-        } 
-        if(!modified) {
-            return;
-        }
-        
-        attributes.rotation = (attributes.rotation == undefined) ?
-            this.getRotation(feature) :
-            attributes.rotation;
-        var layer = feature.layer;
-        var map = layer.map;
-        var scale = attributes.scale || feature.attributes.scale;
-        var layoutName = attributes.layout || feature.attributes.layout;
-        var layout = this.layouts.getAt(this.layouts.find("name", layoutName));
-        if(layout) {
-            var geom = this.getLayoutBounds(
-                map,
-                scale || this.getBestScale(map, layoutName),
-                layout,
-                feature.geometry ?
-                    feature.geometry.getBounds().getCenterLonLat() :
-                    map.getCenter()
-            ).toGeometry();
-            geom.rotate(-attributes.rotation, geom.getCentroid());
-            if(feature.geometry) {
-                geom.id = feature.geometry.id;
-            }
-            feature.geometry = geom;
-            layer.drawFeature(feature);
-        }
-        Ext.apply(feature.attributes, attributes);
-        feature.layer.events.triggerEvent("featuremodified", {
-            feature: feature
-        });
-    },
-    
-    /** api:method[updateHandle]
-     *  :param handle: ``OpenLayers.Feature.Vector`` The handle to update
-     *  :param feature: ``OpenLayers.Feature.Vector`` The feature to align the
-     *      handle to.
-     *      
-     *  Updates the handle position to align with a feature.
-     */
-    updateHandle: function(handle, feature) {
-        if(feature.geometry) {
-            var hLoc = this.getHandleLocation(feature); 
-            var geom = new OpenLayers.Geometry.Point(hLoc.lon, hLoc.lat);
-            if(handle.geometry) {
-                geom.id = handle.geometry.id;
-            }
-            handle.geometry = geom;
-            handle.layer.drawFeature(handle);
-
-            var layout = feature.attributes.layout;
-        }
     }
     
 });
 
-/** private:property[encode]
+/** private: property[encode]
  *  Sn object providing encoding functions for different layer types.
  */
 GeoExt.ux.data.PrintProvider.encode = {
@@ -586,8 +382,7 @@
             baseURL: Ext.DomHelper.overwrite(document.createElement("a"),
                 {tag: "a", href: url}).href,
             opacity: (layer.opacity != null) ? layer.opacity : 1.0,
-            singleTile: layer.singleTile,
-            customParams: {}
+            singleTile: layer.singleTile
         };
     },
     "Image": function(layer) {
@@ -656,4 +451,5 @@
             };
         }
     }
+    
 };
\ No newline at end of file

Deleted: sandbox/ahocevar/playground/ux/Printing/ux/plugins/PrintLayoutField.js
===================================================================
--- sandbox/ahocevar/playground/ux/Printing/ux/plugins/PrintLayoutField.js	2009-12-04 20:44:43 UTC (rev 1556)
+++ sandbox/ahocevar/playground/ux/Printing/ux/plugins/PrintLayoutField.js	2009-12-04 21:54:31 UTC (rev 1557)
@@ -1,36 +0,0 @@
-Ext.namespace("GeoExt.ux.plugins");
-
-GeoExt.ux.plugins.PrintLayoutField = Ext.extend(Ext.util.Observable, {
-    
-    printProvider: null,
-    
-    layer: null,
-    
-    /** private: method[constructor]
-     */
-    constructor: function(config) {
-        this.initialConfig = config;
-        Ext.apply(this, config);
-        
-        GeoExt.ux.plugins.PrintLayoutField.superclass.constructor.apply(this, arguments);
-    },
-    
-    init: function(target) {
-        target.on({
-            "valid": this.onUpdate,
-            scope: this
-        });
-    },
-    
-    onUpdate: function(field) {
-        var value = field.getValue();
-        Ext.each(this.layer.features, function(feature){
-            if(feature.attributes.layout !== undefined) {
-                this.printProvider.updateFeature(feature, {layout: value});
-            }
-        }, this);
-    }
-});
-
-/** api: ptype = gx-printlayoutfield */
-Ext.preg && Ext.preg("gx-printlayoutfield", GeoExt.ux.plugins.PrintLayoutField);

Deleted: sandbox/ahocevar/playground/ux/Printing/ux/plugins/PrintPageAttributeField.js
===================================================================
--- sandbox/ahocevar/playground/ux/Printing/ux/plugins/PrintPageAttributeField.js	2009-12-04 20:44:43 UTC (rev 1556)
+++ sandbox/ahocevar/playground/ux/Printing/ux/plugins/PrintPageAttributeField.js	2009-12-04 21:54:31 UTC (rev 1557)
@@ -1,64 +0,0 @@
-Ext.namespace("GeoExt.ux.plugins");
-
-GeoExt.ux.plugins.PrintPageAttributeField = Ext.extend(Ext.util.Observable, {
-    
-    printProvider: null,
-    
-    target: null,
-    
-    pageFeature: null,
-    
-    handle: null,
-    
-    attribute: null,
-    
-    /** private: method[constructor]
-     */
-    constructor: function(config) {
-        this.initialConfig = config;
-        Ext.apply(this, config);
-        
-        GeoExt.ux.plugins.PrintPageAttributeField.superclass.constructor.apply(this, arguments);
-    },
-    
-    init: function(target) {
-        this.target = target;
-        target.on({
-            "valid": this.onFieldUpdate,
-            scope: this
-        });
-        this.pageFeature.layer.events.on({
-            "featuremodified": this.onFeatureUpdate,
-            scope: this
-        });
-    },
-    
-    onFieldUpdate: function(field) {
-        var value = field.getValue();
-        // make sure we send the *valueField* to updateFeature
-        if(field instanceof Ext.form.ComboBox && field.valueField) {
-            var index = field.store.find(field.displayField, value);
-            if(index !== -1) {
-                value = field.store.getAt(index).get(field.valueField);
-            }
-        }
-        var attributes = {};
-        attributes[this.attribute] = value;
-        this.printProvider.updateFeature(this.pageFeature, attributes);
-        this.printProvider.updateHandle(this.handle, this.pageFeature);
-    },
-    
-    onFeatureUpdate: function(e) {
-        if(e.feature === this.pageFeature) {
-            var value = e.feature.attributes[this.attribute];
-            if(value && value != this.target.getValue()) {
-                this.target.suspendEvents();
-                this.target.setValue(value);
-                this.target.resumeEvents();
-            }
-        }
-    }
-});
-
-/** api: ptype = gx-printpageattributefield */
-Ext.preg && Ext.preg("gx-printpageattributefield", GeoExt.ux.plugins.PrintPageAttributeField);

Added: sandbox/ahocevar/playground/ux/Printing/ux/plugins/PrintPageField.js
===================================================================
--- sandbox/ahocevar/playground/ux/Printing/ux/plugins/PrintPageField.js	                        (rev 0)
+++ sandbox/ahocevar/playground/ux/Printing/ux/plugins/PrintPageField.js	2009-12-04 21:54:31 UTC (rev 1557)
@@ -0,0 +1,59 @@
+Ext.namespace("GeoExt.ux.plugins");
+
+GeoExt.ux.plugins.PrintPageField = Ext.extend(Ext.util.Observable, {
+    
+    page: null,
+    
+    target: null,
+    
+    /** private: method[constructor]
+     */
+    constructor: function(config) {
+        this.initialConfig = config;
+        Ext.apply(this, config);
+        
+        GeoExt.ux.plugins.PrintPageField.superclass.constructor.apply(this, arguments);
+    },
+    
+    init: function(target) {
+        this.target = target;
+        target.on({
+            "valid": this.onFieldChange,
+            scope: this
+        });
+        this.page.on({
+            "change": this.onPageChange,
+            scope: this
+        });
+    },
+
+    onFieldChange: function(field) {
+        var printProvider = this.page.printProvider;
+        var value = field.getValue();
+        if(field.store === printProvider.scales) {
+            var i = printProvider.scales.find(field.displayField, value);
+            this.page.setScale(printProvider.scales.getAt(i).get("value"));
+        } else if(field.name == "rotation") {
+            this.page.setRotation(value);
+        } else {
+            this.page.customParams[field.name] = value;
+        }
+    },
+
+    onPageChange: function(page) {
+        var t = this.target;
+        t.suspendEvents();
+        var printProvider = this.page.printProvider;
+        if(t.store === printProvider.scales) {
+            var i = t.store.find("value", this.page.scale);
+            t.setValue(t.store.getAt(i).get("name"));
+        } else if(t.name == "rotation") {
+            t.setValue(this.page.rotation);
+        }
+        t.resumeEvents();
+    }
+
+});
+
+/** api: ptype = gx-printpagefield */
+Ext.preg && Ext.preg("gx-printpagefield", GeoExt.ux.plugins.PrintPageField);

Added: sandbox/ahocevar/playground/ux/Printing/ux/plugins/PrintProviderField.js
===================================================================
--- sandbox/ahocevar/playground/ux/Printing/ux/plugins/PrintProviderField.js	                        (rev 0)
+++ sandbox/ahocevar/playground/ux/Printing/ux/plugins/PrintProviderField.js	2009-12-04 21:54:31 UTC (rev 1557)
@@ -0,0 +1,62 @@
+Ext.namespace("GeoExt.ux.plugins");
+
+GeoExt.ux.plugins.PrintProviderField = Ext.extend(Ext.util.Observable, {
+    
+    /** private: method[constructor]
+     */
+    constructor: function(config) {
+        this.initialConfig = config;
+        Ext.apply(this, config);
+        
+        GeoExt.ux.plugins.PrintProviderField.superclass.constructor.apply(this, arguments);
+    },
+    
+    init: function(target) {
+        target.on({
+            "valid": this.onFieldChange,
+            "render": this.onRender,
+            scope: this
+        });
+    },
+    
+    onRender: function(field) {
+        var printProvider = field.ownerCt.printProvider;
+        if(field.store === printProvider.layouts) {
+            field.setValue(printProvider.layout);
+            printProvider.on({
+                "layoutchange": function(printProvider, layout) {
+                    printProvider.suspendEvents();
+                    field.setValue(layout.get("name"));
+                    printProvider.resumeEvents();
+                }
+            });
+        } else if(field.store === printProvider.dpis) {
+            field.setValue(printProvider.dpi);
+            printProvider.on({
+                "dpichange": function(printProvider, dpi) {
+                    printProvider.suspendEvents();
+                    field.setValue(dpi.get("value"));
+                    printProvider.resumeEvents();
+                }
+            });
+        } else {
+            field.setValue(printProvider.customParams[field.name]);
+        }
+    },
+    
+    onFieldChange: function(field) {
+        var printProvider = field.ownerCt.printProvider;
+        var value = field.getValue();
+        if(field.store === printProvider.layouts) {
+            printProvider.setLayout(value);
+        } else if(field.store === printProvider.dpis) {
+            var i = printProvider.dpis.find(field.displayField, value);
+            printProvider.setDpi(printProvider.dpis.getAt(i).get("value"));
+        } else {
+            printProvider.customParams[field.name] = value;
+        }
+    }
+});
+
+/** api: ptype = gx-printproviderfield */
+Ext.preg && Ext.preg("gx-printproviderfield", GeoExt.ux.plugins.PrintProviderField);

Deleted: sandbox/ahocevar/playground/ux/Printing/ux/widgets/SimplePrint.js
===================================================================
--- sandbox/ahocevar/playground/ux/Printing/ux/widgets/SimplePrint.js	2009-12-04 20:44:43 UTC (rev 1556)
+++ sandbox/ahocevar/playground/ux/Printing/ux/widgets/SimplePrint.js	2009-12-04 21:54:31 UTC (rev 1557)
@@ -1,177 +0,0 @@
-Ext.namespace("GeoExt.ux")
-
-GeoExt.ux.SimplePrint = Ext.extend(Ext.form.FormPanel, {
-    
-    layoutText: "Layout",
-    dpiText: "DPI",
-    scaleText: "Scale",
-    rotationText: "Rotation",
-    printText: "Print",
-    
-    printProvider: null,
-    
-    map: null,
-    
-    layer: null,
-    
-    control: null,
-    
-    pageFeature: null,
-    
-    handleFeature: null,
-    
-    initComponent: function() {
-        GeoExt.ux.SimplePrint.superclass.initComponent.call(this);
-        if(this.map instanceof GeoExt.MapPanel) {
-            this.map = this.map.map;
-        }
-                        
-        this.initLayer();
-        this.initControl();
-        this.map.addLayer(this.layer);
-        this.control.activate();
-
-        if(this.printProvider.capabilities) {
-            this.initForm();
-        } else {
-            this.printProvider.on({
-                "loadcapabilities": this.initForm,
-                scope: this
-            });
-        }
-
-        this.on({
-            "show": function() {
-                this.layer.setVisibility(true);
-                this.control.activate();
-                this.printProvider.fitPage(this.pageFeature);
-            },
-            "hide": function() {
-                this.control.deactivate();
-                this.layer.setVisibility(false);
-            }
-        });
-    },
-    
-    initLayer: function() {
-        if(!this.layer) {
-            this.layer = new OpenLayers.Layer.Vector(null, {
-                displayInLayerSwitcher: false
-            })
-        };
-        if(!this.pageFeature) {
-            this.pageFeature = new OpenLayers.Feature.Vector(null, {
-            layout: null});
-        }
-        this.handleFeature = new OpenLayers.Feature.Vector();
-        this.layer.addFeatures([this.pageFeature, this.handleFeature]);
-    },
-    
-    initControl: function() {
-        this.control = new OpenLayers.Control.DragFeature(this.layer, {
-            onDrag: function(feature) {
-                if(feature === this.pageFeature) {
-                    this.printProvider.updateHandle(this.handleFeature,
-                        this.pageFeature);
-                } else if(feature === this.handleFeature) {
-                    this.printProvider.updatePage(this.pageFeature,
-                        this.handleFeature);
-                }
-            }.createDelegate(this),
-            onComplete: this.printProvider.updateHandle.createDelegate(
-                this.printProvider, [this.handleFeature, this.pageFeature])
-        });
-        this.map.addControl(this.control);
-    },
-    
-    initForm: function() {
-        var items = [{
-            xtype: this.pageLayout ? "hidden" : "combo",
-            fieldLabel: this.layoutText,
-            name: "layout",
-            store: this.printProvider.layouts,
-            value: this.pageLayout ||
-                this.printProvider.layouts.getAt(0).get("name"),
-            displayField: "name",
-            typeAhead: true,
-            mode: "local",
-            forceSelection: true,
-            triggerAction: "all",
-            selectOnFocus: true,
-            plugins: new GeoExt.ux.plugins.PrintLayoutField({
-                printProvider: this.printProvider,
-                layer: this.layer
-            })
-        }, {
-            xtype: this.dpi ? "hidden" : "combo",
-            fieldLabel: this.dpiText,
-            name: "dpi",
-            store: this.printProvider.dpis,
-            value: this.dpi ||
-                this.printProvider.dpis.getAt(0).get("value"),
-            displayField: "name",
-            valueField: "value",
-            typeAhead: true,
-            mode: "local",
-            forceSelection: true,
-            triggerAction: "all",
-            selectOnFocus: true,
-            valueField: "value",
-            displayField: "name"
-        }, {
-            xtype: "combo",
-            fieldLabel: this.scaleText,
-            store: this.printProvider.scales,
-            value: this.printProvider.scales.getAt(0).get("value"),
-            displayField: "name",
-            valueField: "value",
-            typeAhead: true,
-            mode: "local",
-            forceSelection: true,
-            triggerAction: "all",
-            selectOnFocus: true,
-            plugins: new GeoExt.ux.plugins.PrintPageAttributeField({
-                printProvider: this.printProvider,
-                attribute: "scale",
-                pageFeature: this.pageFeature,
-                handle: this.handleFeature
-            })
-        }, {
-            xtype: "textfield",
-            fieldLabel: this.rotationText,
-            value: 0,
-            enableKeyEvents: true,
-            validator: function(v) {
-                return !isNaN(v)
-            },
-            plugins: new GeoExt.ux.plugins.PrintPageAttributeField({
-                printProvider: this.printProvider,
-                attribute: "rotation",
-                pageFeature: this.pageFeature,
-                handle: this.handleFeature
-            })
-        }];
-        Ext.each(items, function(item){
-            this.add(item);
-        }, this);
-
-        this.addButton({
-            text: this.printText,
-            handler: function() {
-                var options = {
-                    layer: this.layer
-                }
-                this.items.each(function(field){
-                    if(field.name) {
-                        options[field.name] = field.getValue();
-                    }
-                }, this);
-                this.printProvider.print(this.map, options);
-            },
-            scope: this
-        });
-
-        this.doLayout();
-    }
-    
-});

Added: sandbox/ahocevar/playground/ux/Printing/ux/widgets/form/PrintForm.js
===================================================================
--- sandbox/ahocevar/playground/ux/Printing/ux/widgets/form/PrintForm.js	                        (rev 0)
+++ sandbox/ahocevar/playground/ux/Printing/ux/widgets/form/PrintForm.js	2009-12-04 21:54:31 UTC (rev 1557)
@@ -0,0 +1,73 @@
+Ext.namespace("GeoExt.ux.form")
+
+GeoExt.ux.form.PrintForm = Ext.extend(Ext.form.FormPanel, {
+    
+    printProvider: null,
+    
+    map: null,
+    
+    layer: null,
+    
+    control: null,
+    
+    pages: null,
+    
+    initComponent: function() {
+        GeoExt.ux.form.PrintForm.superclass.initComponent.call(this);
+        if(this.map instanceof GeoExt.MapPanel) {
+            this.map = this.map.map;
+        }
+        this.printProvider.units = this.map.baseLayer.units;
+        
+        if(!this.pages) {
+            this.pages = [];
+        }
+                        
+        this.initLayer();
+        this.initControl();
+        this.map.addLayer(this.layer);
+        this.control.activate();
+
+        this.on({
+            "show": function() {
+                this.layer.setVisibility(true);
+                this.control.activate();
+            },
+            "hide": function() {
+                this.control.deactivate();
+                this.layer.setVisibility(false);
+            }
+        });
+    },
+    
+    initLayer: function() {
+        this.layer = new OpenLayers.Layer.Vector(null, {
+            displayInLayerSwitcher: false
+        })
+    },
+    
+    initControl: function() {
+        var pages = this.pages;
+        var updateHandles = function() {
+            for(var i=0, len=pages.length; i<len; ++i) {
+                pages[i].updateHandle();
+            };
+        }
+        this.control = new OpenLayers.Control.DragFeature(this.layer, {
+            onDrag: function(feature) {
+                if(feature.geometry instanceof OpenLayers.Geometry.Polygon) {
+                    // a page geometry was dragged
+                    updateHandles();
+                } else if(feature.geometry instanceof OpenLayers.Geometry.Point) {
+                    // a scale/rotation handle was dragged
+                    for(var i=0, len=pages.length; i<len; ++i) {
+                        pages[i].updateByHandle(false);
+                    }
+                }
+            },
+            onComplete: updateHandles
+        });
+        this.map.addControl(this.control);
+    }
+    
+});

Copied: sandbox/ahocevar/playground/ux/Printing/ux/widgets/form/SimplePrint.js (from rev 1548, sandbox/ahocevar/playground/ux/Printing/ux/widgets/SimplePrint.js)
===================================================================
--- sandbox/ahocevar/playground/ux/Printing/ux/widgets/form/SimplePrint.js	                        (rev 0)
+++ sandbox/ahocevar/playground/ux/Printing/ux/widgets/form/SimplePrint.js	2009-12-04 21:54:31 UTC (rev 1557)
@@ -0,0 +1,87 @@
+Ext.namespace("GeoExt.ux.form")
+
+GeoExt.ux.form.SimplePrint = Ext.extend(GeoExt.ux.form.PrintForm, {
+    
+    layoutText: "Layout",
+    dpiText: "DPI",
+    scaleText: "Scale",
+    rotationText: "Rotation",
+    printText: "Print",
+    
+    showLayoutField: true,
+    
+    initComponent: function() {
+        GeoExt.ux.form.SimplePrint.superclass.initComponent.call(this);
+        
+        this.pages.push(new GeoExt.ux.data.PrintPage({
+            printProvider: this.printProvider,
+            layer: this.layer
+        }));
+
+        this.initForm();
+    },
+    
+    initForm: function() {
+        var items = [{
+            xtype: this.showLayoutField ? "combo" : "hidden",
+            fieldLabel: this.layoutText,
+            store: this.printProvider.layouts,
+            displayField: "name",
+            typeAhead: true,
+            mode: "local",
+            forceSelection: true,
+            triggerAction: "all",
+            selectOnFocus: true,
+            plugins: new GeoExt.ux.plugins.PrintProviderField()
+        }, {
+            xtype: this.dpi ? "hidden" : "combo",
+            fieldLabel: this.dpiText,
+            store: this.printProvider.dpis,
+            displayField: "name",
+            typeAhead: true,
+            mode: "local",
+            forceSelection: true,
+            triggerAction: "all",
+            selectOnFocus: true,
+            plugins: new GeoExt.ux.plugins.PrintProviderField()
+        }, {
+            xtype: "combo",
+            fieldLabel: this.scaleText,
+            store: this.printProvider.scales,
+            displayField: "name",
+            typeAhead: true,
+            mode: "local",
+            forceSelection: true,
+            triggerAction: "all",
+            selectOnFocus: true,
+            plugins: new GeoExt.ux.plugins.PrintPageField({
+                page: this.pages[0]
+            })
+        }, {
+            xtype: "textfield",
+            fieldLabel: this.rotationText,
+            name: "rotation",
+            enableKeyEvents: true,
+            validator: function(v) {
+                return !isNaN(v)
+            },
+            plugins: new GeoExt.ux.plugins.PrintPageField({
+                page: this.pages[0]
+            })
+        }];
+        Ext.each(items, function(item){
+            this.add(item);
+        }, this);
+
+        this.addButton({
+            text: this.printText,
+            handler: function() {
+                this.printProvider.print(this.map, this.pages);
+            },
+            scope: this
+        });
+
+        this.doLayout();
+    }
+    
+});



More information about the Commits mailing list