[Commits] r1165 - in apps/opengeo/geoexplorer/trunk: . build lib lib/Ext/grid script src src/html src/script src/script/app src/script/app/GeoExplorer src/script/ux src/theme src/theme/app

commits at geoext.org commits at geoext.org
Tue Jun 30 00:12:56 CEST 2009


Author: tschaub
Date: 2009-06-30 00:12:56 +0200 (Tue, 30 Jun 2009)
New Revision: 1165

Added:
   apps/opengeo/geoexplorer/trunk/build/build.xml
   apps/opengeo/geoexplorer/trunk/src/
   apps/opengeo/geoexplorer/trunk/src/html/
   apps/opengeo/geoexplorer/trunk/src/html/about.html
   apps/opengeo/geoexplorer/trunk/src/html/debug.html
   apps/opengeo/geoexplorer/trunk/src/html/embed-debug.html
   apps/opengeo/geoexplorer/trunk/src/html/embed-example.html
   apps/opengeo/geoexplorer/trunk/src/html/embed.html
   apps/opengeo/geoexplorer/trunk/src/html/index.html
   apps/opengeo/geoexplorer/trunk/src/script/
   apps/opengeo/geoexplorer/trunk/src/script/app/
   apps/opengeo/geoexplorer/trunk/src/script/app/GeoExplorer.js
   apps/opengeo/geoexplorer/trunk/src/script/app/GeoExplorer/
   apps/opengeo/geoexplorer/trunk/src/script/app/loader.js
   apps/opengeo/geoexplorer/trunk/src/script/ux/
   apps/opengeo/geoexplorer/trunk/src/script/ux/RowExpander.js
   apps/opengeo/geoexplorer/trunk/src/theme/
   apps/opengeo/geoexplorer/trunk/src/theme/app/
Removed:
   apps/opengeo/geoexplorer/trunk/about.html
   apps/opengeo/geoexplorer/trunk/debug.html
   apps/opengeo/geoexplorer/trunk/embed-debug.html
   apps/opengeo/geoexplorer/trunk/embed-example.html
   apps/opengeo/geoexplorer/trunk/embed.html
   apps/opengeo/geoexplorer/trunk/index.html
   apps/opengeo/geoexplorer/trunk/lib/Ext/grid/RowExpander.js
   apps/opengeo/geoexplorer/trunk/lib/GeoExplorer.js
   apps/opengeo/geoexplorer/trunk/lib/GeoExplorer/
   apps/opengeo/geoexplorer/trunk/script/GeoExplorer-debug.js
   apps/opengeo/geoexplorer/trunk/theme/
Modified:
   apps/opengeo/geoexplorer/trunk/src/script/app/GeoExplorer/Full.js
   apps/opengeo/geoexplorer/trunk/src/theme/app/geoexplorer.css
Log:
Restructuring things.  Putting differences between build profiles in the build config file.  Going with ant to simplify use as an extension and allow cross-platform building.  Only development implemented.

Deleted: apps/opengeo/geoexplorer/trunk/about.html
===================================================================
--- apps/opengeo/geoexplorer/trunk/about.html	2009-06-29 16:48:53 UTC (rev 1164)
+++ apps/opengeo/geoexplorer/trunk/about.html	2009-06-29 22:12:56 UTC (rev 1165)
@@ -1,35 +0,0 @@
-<html>
-    <head>
-        <title>About GeoExplorer</title>
-        <link rel="stylesheet" type="text/css" href="theme/about.css"/>    </head>
-    <body>
-    <div class="logo"></div>
-    <h2> GeoExplorer </h2>
-    <div class="versioninfo">Version 0.1</div>
-    <h3> Engineering & Design by OpenGeo </h3>
-    <a href="http://opengeo.org/">http://opengeo.org/</a>
-    &copy; 2009, OpenGeo under the BSD license.
-
-    <h3> GeoExt Framework </h3>
-    <a href="http://geoext.org/">http://geoext.org/</a>
-    &copy; 2009, OSGeo under the BSD license.
-
-    <h3> GeoSilk Icons </h3>
-    <a href="http://projects.opengeo.org/geosilk/">http://projects.opengeo.org/geosilk/</a>
-    &copy; 2009, OpenGeo under CC-BY 3.0.
-
-    <h3> Silk Icons </h3>
-    <a href="http://famfamfam.com/lab/icons/silk/">http://famfamfam.com/lab/icons/silk/</a>
-    &copy; Mark James under CC-BY 3.0.
-
-    <h3> Contributors </h3>
-    <ul>
-    <li>Tim Schaub</li>
-    <li>David Winslow</li>
-    <li>Sebastian Benthall</li>
-    <li>Andreas Hocevar</li>
-    <li>Tim Coulter</li>
-    <li>Rolando Pe&ntilde;ate</li>
-    </ul>
-    </body>
-</html>

Added: apps/opengeo/geoexplorer/trunk/build/build.xml
===================================================================
--- apps/opengeo/geoexplorer/trunk/build/build.xml	                        (rev 0)
+++ apps/opengeo/geoexplorer/trunk/build/build.xml	2009-06-29 22:12:56 UTC (rev 1165)
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="GeoExplorer" default="dist" basedir=".">
+
+    <description>
+        GeoExplorer Build File
+    </description>
+
+    <property name="src" location="../src"/>
+    <property name="build" location="GeoExplorer"/>
+
+    <target name="init">
+        <tstamp/>
+        <mkdir dir="${build}"/>
+    </target>
+    
+    <target name="dev" depends="clean, init" description="set up development build">
+        <echo>Setting up development build.</echo>
+
+        <filterset id="debug-replacements">
+            <filter token="title" value="GeoExplorer (debug)"/>
+            <!-- Ext Resources -->
+            <filter token="ext-all.js" value="ext-all-debug.js"/>
+            <!-- OpenLayers Resources -->
+            <filter token="ol-style.css" value="../../externals/openlayers/theme/default/style.css"/>
+            <filter token="OpenLayers.js" value="../../externals/openlayers/lib/OpenLayers.js"/>
+            <!-- GeoExt Resources -->
+            <filter token="geoext-all.css" value="../../externals/geoext/resources/css/geoext-all-debug.css"/>
+            <filter token="gxtheme-gray.css" value="../../externals/geoext/resources/css/gxtheme-gray.css"/>
+            <filter token="GeoExt.js" value="../../externals/geoext/lib/GeoExt.js"/>
+            <!-- GeoExplorer Resources -->
+            <filter token="geoexplorer.css" value="../../src/theme/app/geoexplorer.css"/>
+            <filter token="ie.css" value="../../src/theme/app/ie.css"/>
+            <filter token="about.css" value="../../src/theme/app/about.css"/>
+            <filter token="GeoExplorer.js" value="../../src/script/app/loader.js"/>
+            <filter token="ux.js" value="../../src/script/ux/RowExpander.js"/>
+        </filterset>
+
+        <copy file="${src}/html/debug.html" toFile="${build}/index.html">
+            <filterset refid="debug-replacements"/>
+        </copy>
+        <copy file="${src}/html/embed-debug.html" toFile="${build}/embed.html">
+            <filterset refid="debug-replacements"/>
+        </copy>
+        <copy file="${src}/html/about.html" toFile="${build}/about.html">
+            <filterset refid="debug-replacements"/>
+        </copy>
+
+    </target>
+
+    <target name="dist" depends="clean, init" description="prepare app for distribution">
+        <echo>Preparing for distribution.</echo>
+        <copy file="${src}/html/index.html" toFile="${build}/index.html">
+            <filterset>
+                <filter token="body_content" value="Hello world!"/>
+            </filterset>
+        </copy>
+        <echo>Not yet implemented.</echo>
+    </target>
+
+    <target name="zip" depends="dist" description="create zip archive of app">
+        <echo>Preparing zip archive.</echo>
+        <echo>Not yet implemented.</echo>
+    </target>
+    
+    <target name="clean" description="remove previous build">
+        <delete dir="${build}"/>
+    </target>
+
+</project>
+

Deleted: apps/opengeo/geoexplorer/trunk/debug.html
===================================================================
--- apps/opengeo/geoexplorer/trunk/debug.html	2009-06-29 16:48:53 UTC (rev 1164)
+++ apps/opengeo/geoexplorer/trunk/debug.html	2009-06-29 22:12:56 UTC (rev 1165)
@@ -1,69 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
-    <head>
-        <title>GeoExplorer (debug)</title>
-        
-        <!-- IE 8 Compatibility -->
-        <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
-        
-        <!-- Ext resources -->
-        <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/resources/css/ext-all.css" />
-        <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/resources/css/xtheme-gray.css" />
-        <script type="text/javascript" src="http://extjs.cachefly.net/ext-2.2.1/adapter/ext/ext-base.js"></script>
-        <script type="text/javascript" src="http://extjs.cachefly.net/ext-2.2.1/ext-all-debug.js"></script>
-
-        <!-- OpenLayers resources -->
-        <link rel="stylesheet" type="text/css" href="externals/openlayers/theme/default/style.css" />
-        <script type="text/javascript" src="externals/openlayers/lib/OpenLayers.js"></script>
-
-        <!-- GeoExt resources -->
-        <script type="text/javascript" src="externals/geoext/lib/GeoExt.js"></script> 
-        <link rel="stylesheet" type="text/css" href="externals/geoext/resources/css/geoext-all-debug.css" />
-        <link rel="stylesheet" type="text/css" href="externals/geoext/resources/css/gxtheme-gray.css" />
-
-        <!-- GeoExplorer resources -->
-        <link rel="stylesheet" type="text/css" href="theme/geoexplorer.css" />
-        <!--[if IE]>
-        <link rel="stylesheet" type="text/css" href="theme/ie.css"/><![endif]-->
-
-        
-        <script type="text/javascript" src="script/GeoExplorer-debug.js"></script>
-
-        <script>
-            Ext.BLANK_IMAGE_URL = "theme/img/blank.gif";
-            var app = new GeoExplorer.Full({
-                proxy: "/proxy/?url=",
-                about: {
-                    title: 'Example Map',
-                    "abstract": 'A description of the map\'s contents',
-                    keywords: "example, test, development",
-                    contact: "Georj the Robot, Representative, OpenGeo, http://opengeo.org/"
-                },
-                ows: {
-                    "demo": "http://demo.opengeo.org/geoserver/ows/"
-                },
-                map: {
-                    layers: [{
-                        name: "nurc:Img_Sample",
-                        ows: "demo"
-                    },{
-                        name: "topp:states",
-                        ows: "demo",
-                        background: true,
-                        visibility:true
-                    },{
-                        name: "topp:bluemarble",
-                        ows: "demo",
-                        visibility: false,
-                        background: true  
-                    }],
-                    center: [-96.7, 37.6],
-                    zoom: 4
-                }
-            });
-        </script>
-
-    </head>
-    <body>
-    </body>
-</html>

Deleted: apps/opengeo/geoexplorer/trunk/embed-debug.html
===================================================================
--- apps/opengeo/geoexplorer/trunk/embed-debug.html	2009-06-29 16:48:53 UTC (rev 1164)
+++ apps/opengeo/geoexplorer/trunk/embed-debug.html	2009-06-29 22:12:56 UTC (rev 1165)
@@ -1,69 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
-    <head>
-        <title>GeoExplorer Embedded (debug)</title>
-        
-        <!-- IE 8 Compatibility -->
-        <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
-        
-        <!-- This file is expected to go into an iframe. -->
-        <script type="text/javascript" src="externals/openlayers/lib/Firebug/firebug.js"></script>
-        
-        <!-- Ext resources -->
-        <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/resources/css/ext-all.css" />
-        <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/resources/css/xtheme-gray.css" />
-        <script type="text/javascript" src="http://extjs.cachefly.net/ext-2.2.1/adapter/ext/ext-base.js"></script>
-        <script type="text/javascript" src="http://extjs.cachefly.net/ext-2.2.1/ext-all-debug.js"></script>
-
-        <!-- OpenLayers resources -->
-        <link rel="stylesheet" type="text/css" href="externals/openlayers/theme/default/style.css" />
-        <script type="text/javascript" src="externals/openlayers/lib/OpenLayers.js"></script>
-
-        <!-- GeoExt resources -->
-        <script type="text/javascript" src="externals/geoext/lib/GeoExt.js"></script> 
-        <link rel="stylesheet" type="text/css" href="externals/geoext/resources/css/geoext-all-debug.css" />
-        <link rel="stylesheet" type="text/css" href="externals/geoext/resources/css/gxtheme-gray.css" />
-
-        <!-- GeoExplorer resources -->
-        <link rel="stylesheet" type="text/css" href="theme/geoexplorer.css" />
-        <!--[if IE]>
-        <link rel="stylesheet" type="text/css" href="theme/ie.css"/><![endif]-->
-
-        <script type="text/javascript" src="script/GeoExplorer-debug.js"></script>
-
-        <script>
-            Ext.BLANK_IMAGE_URL = "theme/img/blank.gif";
-            var app = new GeoExplorer.Embed({
-                proxy: "/proxy/?url=",
-                about: {
-                    title: 'Example Map',
-                    "abstract": 'A description of the map\'s contents',
-                    keywords: "example, test, development",
-                    contact: "Georj the Robot, Outreach Tribe Leader, OpenGeo, http://opengeo.org/"
-                },
-                ows: {
-                    "demo": "http://demo.opengeo.org/geoserver/ows"
-                },
-                map: {
-                    layers: [{
-                        name: "openstreetmap",
-                        ows: "demo",
-                        background: true  
-                    },{
-                        name: "nurc:Img_Sample",
-                        ows: "demo"
-                    },{
-                        name: "topp:states",
-                        ows: "demo",
-                        background: true  
-                    }],
-                    center: [-96.7, 37.6],
-                    zoom: 4
-                }
-            });
-        </script>
-
-    </head>
-    <body>
-    </body>
-</html>

Deleted: apps/opengeo/geoexplorer/trunk/embed-example.html
===================================================================
--- apps/opengeo/geoexplorer/trunk/embed-example.html	2009-06-29 16:48:53 UTC (rev 1164)
+++ apps/opengeo/geoexplorer/trunk/embed-example.html	2009-06-29 22:12:56 UTC (rev 1165)
@@ -1,14 +0,0 @@
-<html>
-    <head>
-    <title> Embedded GeoExplorer Example </title>
-    <!-- look ma, no <script> tags -->
-    </head>
-    <body>
-        <h2> Embedded GeoExplorer </h2>
-        <p> You can embed a GeoExplorer application inside of other web pages, using the <code> GeoExplorer.Embed </code> class.  This supports all of the persisted options available in the full version, including layers, styles, tools, and metadata, but with GUI components optimized for inclusion in a larger page such as a blog post.
-        </p>
-        <iframe style="height: 400px; width: 600px; border: 0px" src="embed-debug.html">
-        If you see this text, your browser doesn't handle frames properly.  Try a recent version of <a href="http://www.mozilla.com/en-US/firefox/">Firefox</a>.
-        </iframe>
-    </body>
-</html>

Deleted: apps/opengeo/geoexplorer/trunk/embed.html
===================================================================
--- apps/opengeo/geoexplorer/trunk/embed.html	2009-06-29 16:48:53 UTC (rev 1164)
+++ apps/opengeo/geoexplorer/trunk/embed.html	2009-06-29 22:12:56 UTC (rev 1165)
@@ -1,62 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
-    <head>
-        <title>GeoExplorer Embedded (debug)</title>
-        
-        <!-- This file is expected to go into an iframe. -->
-        
-        <!-- Ext resources -->
-        <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/resources/css/ext-all.css" />
-        <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/resources/css/xtheme-gray.css" />
-        <script type="text/javascript" src="http://extjs.cachefly.net/ext-2.2.1/adapter/ext/ext-base.js"></script>
-        <script type="text/javascript" src="http://extjs.cachefly.net/ext-2.2.1/ext-all.js"></script>
-
-        <!-- OpenLayers resources -->
-        <link rel="stylesheet" type="text/css" href="externals/openlayers/theme/default/style.css" />
-        <script type="text/javascript" src="externals/openlayers/lib/OpenLayers.js"></script>
-
-        <!-- GeoExt resources -->
-        <script type="text/javascript" src="externals/geoext/lib/GeoExt.js"></script> 
-        <script type="text/javascript" src="externals/geoext/lib/GeoExt-LegendPanel.js"></script> 
-        <link rel="stylesheet" type="text/css" href="externals/geoext/resources/css/geoext-all-debug.css" />
-        <link rel="stylesheet" type="text/css" href="externals/geoext/resources/css/gxtheme-gray.css" />
-
-        <!-- GeoExplorer resources -->
-        <link rel="stylesheet" type="text/css" href="theme/geoexplorer.css" />
-        <!--[if IE]>
-        <link rel="stylesheet" type="text/css" href="theme/ie.css"/><![endif]-->
-
-        <script type="text/javascript" src="script/GeoExplorer.js"></script>
-
-        <script>
-            Ext.BLANK_IMAGE_URL = "theme/img/blank.gif";
-            var app = new GeoExplorer.Embed({
-                proxy: "/proxy/?url=",
-                ows: {
-                    "demo": "http://demo.opengeo.org/geoserver/ows/"
-                },
-                map: {
-                    layers: [{
-                        name: "nurc:Img_Sample",
-                        ows: "demo"
-                    },{
-                        name: "topp:states",
-                        ows: "demo",
-                        background: true,
-                        visibility:true
-                    },{
-                        name: "topp:bluemarble",
-                        ows: "demo",
-                        visibility: false,
-                        background: true  
-                    }],
-                    center: [-96.7, 37.6],
-                    zoom: 4
-                }
-            });
-        </script>
-
-    </head>
-    <body>
-    </body>
-</html>

Deleted: apps/opengeo/geoexplorer/trunk/index.html
===================================================================
--- apps/opengeo/geoexplorer/trunk/index.html	2009-06-29 16:48:53 UTC (rev 1164)
+++ apps/opengeo/geoexplorer/trunk/index.html	2009-06-29 22:12:56 UTC (rev 1165)
@@ -1,57 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
-    <head>
-        <title>GeoExplorer</title>
-        
-        <!-- IE 8 Compatibility -->
-        <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
-        
-        <!-- Ext resources -->
-        <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/resources/css/ext-all.css" />
-        <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/resources/css/xtheme-gray.css" />
-        <script type="text/javascript" src="http://extjs.cachefly.net/ext-2.2.1/adapter/ext/ext-base.js"></script>
-        <script type="text/javascript" src="http://extjs.cachefly.net/ext-2.2.1/ext-all.js"></script>
-
-        <!-- OpenLayers resources -->
-        <link rel="stylesheet" type="text/css" href="externals/openlayers/theme/default/style.css" />
-        <script type="text/javascript" src="script/OpenLayers.js"></script>
-
-        <!-- GeoExt resources -->
-        <script type="text/javascript" src="script/GeoExt.js"></script>
-        <script type="text/javascript" src="script/GeoExt-LegendPanel.js"></script>
-        <link rel="stylesheet" type="text/css" href="externals/geoext/resources/css/geoext-all-debug.css" />
-        <link rel="stylesheet" type="text/css" href="externals/geoext/resources/css/gxtheme-gray.css" />
-
-        <!-- GeoExplorer resources -->
-        <link rel="stylesheet" type="text/css" href="theme/geoexplorer.css" />
-        <!--[if IE]>
-        <link rel="stylesheet" type="text/css" href="theme/ie.css"/><![endif]-->
-
-        <script type="text/javascript" src="script/GeoExplorer.js"></script> 
-
-        <script>
-            Ext.BLANK_IMAGE_URL = "theme/img/blank.gif";
-            var app = new GeoExplorer.Full({
-                proxy: "/proxy/?url=",
-                ows: {
-                    "demo": "http://demo.opengeo.org/geoserver/ows"
-                },
-                map: {
-                    layers: [{
-                        name: "openstreetmap",
-                        ows: "demo",
-                        isBaseLayer: true  
-                    },{
-                        name: "nurc:Img_Sample",
-                        ows: "demo"
-                    }],
-                    center: [-96.7, 37.6],
-                    zoom: 4
-                }
-            });
-        </script>
-
-    </head>
-    <body>
-    </body>
-</html>

Deleted: apps/opengeo/geoexplorer/trunk/lib/Ext/grid/RowExpander.js
===================================================================
--- apps/opengeo/geoexplorer/trunk/lib/Ext/grid/RowExpander.js	2009-06-29 16:48:53 UTC (rev 1164)
+++ apps/opengeo/geoexplorer/trunk/lib/Ext/grid/RowExpander.js	2009-06-29 22:12:56 UTC (rev 1165)
@@ -1,136 +0,0 @@
-/*
- * Ext JS Library 2.2.1
- * Copyright(c) 2006-2009, Ext JS, LLC.
- * licensing at extjs.com
- * 
- * http://extjs.com/license
- */
-
-Ext.grid.RowExpander = function(config){
-    Ext.apply(this, config);
-
-    this.addEvents({
-        beforeexpand : true,
-        expand: true,
-        beforecollapse: true,
-        collapse: true
-    });
-
-    Ext.grid.RowExpander.superclass.constructor.call(this);
-
-    if(this.tpl){
-        if(typeof this.tpl == 'string'){
-            this.tpl = new Ext.Template(this.tpl);
-        }
-        this.tpl.compile();
-    }
-
-    this.state = {};
-    this.bodyContent = {};
-};
-
-Ext.extend(Ext.grid.RowExpander, Ext.util.Observable, {
-    header: "",
-    width: 20,
-    sortable: false,
-    fixed:true,
-    menuDisabled:true,
-    dataIndex: '',
-    id: 'expander',
-    lazyRender : true,
-    enableCaching: true,
-
-    getRowClass : function(record, rowIndex, p, ds){
-        p.cols = p.cols-1;
-        var content = this.bodyContent[record.id];
-        if(!content && !this.lazyRender){
-            content = this.getBodyContent(record, rowIndex);
-        }
-        if(content){
-            p.body = content;
-        }
-        return this.state[record.id] ? 'x-grid3-row-expanded' : 'x-grid3-row-collapsed';
-    },
-
-    init : function(grid){
-        this.grid = grid;
-
-        var view = grid.getView();
-        view.getRowClass = this.getRowClass.createDelegate(this);
-
-        view.enableRowBody = true;
-
-        grid.on('render', function(){
-            view.mainBody.on('mousedown', this.onMouseDown, this);
-        }, this);
-    },
-
-    getBodyContent : function(record, index){
-        if(!this.enableCaching){
-            return this.tpl.apply(record.data);
-        }
-        var content = this.bodyContent[record.id];
-        if(!content){
-            content = this.tpl.apply(record.data);
-            this.bodyContent[record.id] = content;
-        }
-        return content;
-    },
-
-    onMouseDown : function(e, t){
-        if(t.className == 'x-grid3-row-expander'){
-            e.stopEvent();
-            var row = e.getTarget('.x-grid3-row');
-            this.toggleRow(row);
-        }
-    },
-
-    renderer : function(v, p, record){
-        p.cellAttr = 'rowspan="2"';
-        return '<div class="x-grid3-row-expander">&#160;</div>';
-    },
-
-    beforeExpand : function(record, body, rowIndex){
-        if(this.fireEvent('beforeexpand', this, record, body, rowIndex) !== false){
-            if(this.tpl && this.lazyRender){
-                body.innerHTML = this.getBodyContent(record, rowIndex);
-            }
-            return true;
-        }else{
-            return false;
-        }
-    },
-
-    toggleRow : function(row){
-        if(typeof row == 'number'){
-            row = this.grid.view.getRow(row);
-        }
-        this[Ext.fly(row).hasClass('x-grid3-row-collapsed') ? 'expandRow' : 'collapseRow'](row);
-    },
-
-    expandRow : function(row){
-        if(typeof row == 'number'){
-            row = this.grid.view.getRow(row);
-        }
-        var record = this.grid.store.getAt(row.rowIndex);
-        var body = Ext.DomQuery.selectNode('tr:nth(2) div.x-grid3-row-body', row);
-        if(this.beforeExpand(record, body, row.rowIndex)){
-            this.state[record.id] = true;
-            Ext.fly(row).replaceClass('x-grid3-row-collapsed', 'x-grid3-row-expanded');
-            this.fireEvent('expand', this, record, body, row.rowIndex);
-        }
-    },
-
-    collapseRow : function(row){
-        if(typeof row == 'number'){
-            row = this.grid.view.getRow(row);
-        }
-        var record = this.grid.store.getAt(row.rowIndex);
-        var body = Ext.fly(row).child('tr:nth(1) div.x-grid3-row-body', true);
-        if(this.fireEvent('beforecollapse', this, record, body, row.rowIndex) !== false){
-            this.state[record.id] = false;
-            Ext.fly(row).replaceClass('x-grid3-row-expanded', 'x-grid3-row-collapsed');
-            this.fireEvent('collapse', this, record, body, row.rowIndex);
-        }
-    }
-});

Deleted: apps/opengeo/geoexplorer/trunk/lib/GeoExplorer.js
===================================================================
--- apps/opengeo/geoexplorer/trunk/lib/GeoExplorer.js	2009-06-29 16:48:53 UTC (rev 1164)
+++ apps/opengeo/geoexplorer/trunk/lib/GeoExplorer.js	2009-06-29 22:12:56 UTC (rev 1165)
@@ -1,1463 +0,0 @@
-/**
- * Copyright (c) 2009 The Open Planning Project
- */
- 
-/*
- * @requires GeoExplorer/util.js
- * @requires GeoExplorer/GroupContainer.js
- * @requires GeoExplorer/MapToolSplitToggle.js
- * @requires GeoExplorer/CapabilitiesGrid.js
- * @requires GeoExplorer/NewSourceWindow.js
- */
-
-/**
- * api: (define)
- * module = GeoExplorer
- * extends = Ext.Observable
- */
-
-/** api: constructor
- *  .. class:: GeoExplorer(config)
- *     Create a new GeoExplorer application.
- *
- *     Parameters:
- *     config - {Object} Optional application configuration properties.
- *
- *     Valid config properties:
- *     map - {Object} Map configuration object.
- *     ows - {String} OWS URL
- *     alignToGrid - {boolean} if true, align tile requests to the grid 
- *         enforced by tile caches such as GeoWebCache or Tilecache
- *
- *     Valid map config properties:
- *         layers - {Array} A list of layer configuration objects.
- *         center - {Array} A two item array with center coordinates.
- *         zoom - {Number} An initial zoom level.
- *
- *     Valid layer config properties:
- *     name - {String} Required WMS layer name.
- *     title - {String} Optional title to display for layer.
- *
- */
-var GeoExplorer = Ext.extend(Ext.util.Observable, {
-    
-    /** api: property[map]
-     * :class:`OpenLayers.Map` The application's map.
-     */
-    map: null,
-    
-    /** private: property[layers]
-     * A :class:`GeoExt.data.LayerStore` containing a record for each layer
-     * on the map.
-     */
-    layers: null,
-
-    /**
-     * private: property[mapPanel]
-     * the :class:`GeoExt.MapPanel` instance for the main viewport
-     */
-    mapPanel: null,
-
-    /**
-     * api: config[alignToGrid]
-     * A boolean indicating whether or not to restrict tile request to tiled
-     * mapping service recommendation.  
-     *
-     * True => align to grid 
-     * False => unrestrained tile requests
-     */
-    alignToGrid: false,
-
-    /**
-     * private: property[capGrid]
-     * :class:`Ext.Window` The window containing the CapabilitiesGrid panel to 
-     * use when the user is adding new layers to the map.
-     */
-    capGrid: null,
-
-    /**
-     * private: property[popupCache]
-     * :class:`Object` An object containing references to visible popups so that
-     * we can insert responses from multiple requests.
-     *
-     * ..seealso:: :method:`GeoExplorer.displayPopup()`
-     */
-    popupCache: null,
-    
-    /** api: property[layerSources]
-     * A :class:`Ext.data.Store` containing one 
-     * :class:`GeoExt.data.WMSCapabilitiesStore` for each WMS service in use by
-     * the application, along with service-specific metadata like the service 
-     * name.
-     */
-    layerSources: null,
-
-    constructor: function(config) {
-        this.popupCache = {};
-
-        var query = Ext.urlDecode(document.location.search.substr(1));
-        var queryConfig = Ext.util.JSON.decode(query.q);
-        
-        this.initialConfig = Ext.apply({}, queryConfig, config);
-        Ext.apply(this, this.initialConfig);
-        
-        // add any custom application events
-        this.addEvents(
-            /**
-             * Event: ready
-             * Fires when application is ready for user interaction.
-             */
-            "ready");
-        
-        // pass on any proxy config to OpenLayers
-        if(this.proxy) {
-            OpenLayers.ProxyHost = this.proxy;
-        }
-        
-        this.load();
-    },
-
-    /**
-     * private: method[load]
-     * Called at the end of construction.  This initiates the sequence that
-     * prepares the application for use, including tasks such as loading 
-     * capabilities from remote servers, populating the map, etc.
-     */
-    load: function() {
-        this.layerSources = new Ext.data.SimpleStore({
-            fields: ["identifier", "name", "store", "url"],
-            data: []
-        });
-        
-        var dispatchQueue = [
-            // create layout as soon as Ext says ready
-            function(done) {
-                Ext.onReady(function() {
-                    this.createLayout();
-                    done();
-                }, this);
-            }
-        ];
-        
-        for (var id in this.ows) {
-            // Load capabilities for each ows passed through the configuration.
-            dispatchQueue.push(
-                (function(id) {
-                    // Create a new scope for 'id'.
-                    return function(done){
-                        this.addSource(this.ows[id], id, done, done);
-                    }; 
-                })(id));
-        }
-        
-        GeoExplorer.util.dispatch(
-            dispatchQueue,
-            
-            // activate app when the above are both done
-            this.activate, 
-            this);
-    },
-    
-    /** private: method[addSource]
-     * Add a new WMS server to GeoExplorer. The id parameter is optional,
-     * and will be given a default if not specified; success and fail 
-     * are also optional, and scope only applies if success or fail
-     * is passed in.
-     */
-    addSource: function(url, id, success, fail, scope) {
-        scope = scope || this;
-        success = OpenLayers.Function.bind(success, scope);
-        fail = OpenLayers.Function.bind(fail, scope);
-        
-        id = id || OpenLayers.Util.createUniqueID("source");
-        var capsURL = this.createWMSCapabilitiesURL(url);
-                        var store = new GeoExt.data.WMSCapabilitiesStore();
-
-        OpenLayers.Request.GET({
-            proxy: this.proxy, 
-            url: capsURL,
-            success: function(request){
-                var store = new GeoExt.data.WMSCapabilitiesStore({
-                            fields:  [
-                                {name: "name", type: "string"},
-                                {name: "abstract", type: "string"},
-                                {name: "queryable", type: "boolean"},
-                                {name: "formats"},
-                                {name: "styles"},
-                                {name: "llbbox"},
-                                {name: "minScale"},
-                                {name: "maxScale"},
-                                {name: "prefix"},
-                                
-                                // Added for GeoExplorer.
-                                {name: "background", type: "boolean"},
-                                {name: "source_id", type: "string"}
-                            ]
-                        });
-                var xml = request.responseXML;
-                var data = (xml && xml.documentElement) ?
-                    xml : request.responseText;
-                
-                try {
-                    // Read the response. It's important to note that the
-                    // WMSCapabilitiesStore reads the data as well, though
-                    // we need to do it ourselves in order to maintain
-                    // low coupling.
-                    var format = new OpenLayers.Format.WMSCapabilities();
-                    var extractedData = format.read(data);
-                    
-                    store.loadData(data);
-                } catch(err) {
-                    OpenLayers.Console.error("Could not load source: " + url);
-                    fail();
-                    return;
-                }
-                
-                // MODERATELY LARGE DIRTY HACK!
-                // Tell each layer where it came from.
-                store.each(function(record) {
-                    record.set("source_id", id);
-                }, this);
-                
-                var record = new this.layerSources.recordType({
-                    url: url,
-                    store: store,
-                    identifier: id,
-                    name: extractedData.service.title || id
-                });
-                
-                this.layerSources.add(record);
-                success(record);
-            },
-            failure: function(){
-                OpenLayers.Console.error("Couldn't get capabilities document for ows '" + id + "'.");
-                fail();
-            },
-            scope: this
-        });
-    },
-    
-    /** private: method[createWMSCapabilitiesURL]
-     * Given the URL to an OWS service endpoint, generate a GET request URL for
-     * the service's WMS capabilities.
-     */
-    createWMSCapabilitiesURL: function(url) {
-        var args = {
-            SERVICE: "WMS",
-            REQUEST: "GetCapabilities"
-        };
-        var argIndex = url.indexOf("?");
-        if(argIndex > -1) {
-            var search = url.substring(url.indexOf("?")+1);
-            url = url.replace(search, Ext.urlEncode(Ext.apply(
-                Ext.urlDecode(search), args)));
-        } else {
-            url = url + "?" + Ext.urlEncode(args);
-        }
-
-        return url;
-    },
-    
-    /** private: method[createLayout]
-     * Create the various parts that compose the layout.
-     */
-    createLayout: function() {
-        
-        // create the map
-        // TODO: check this.initialConfig.map for any map options
-        this.map = new OpenLayers.Map({
-            allOverlays: true,
-            controls: [new OpenLayers.Control.PanPanel(),
-                       new OpenLayers.Control.ZoomPanel()]
-        });
-
-        //** Remove this code when OpenLayers #2069 is closed **
-        var onDoubleClick = function(ctrl, evt) { 
- 	        OpenLayers.Event.stop(evt ? evt : window.event); 
-        };
-        var controls = this.map.controls[0].controls;
-        for(var i = 0; i < controls.length; i++){
-            OpenLayers.Event.observe(controls[i].panel_div, "dblclick",  
- 	                             OpenLayers.Function.bind(onDoubleClick, this.map.controls[0], controls[i])); 
-        }        
-        //******************************************************
-
-        //TODO: make this more configurable
-        this.map.events.on({
-            "preaddlayer" : function(evt){
-                if(evt.layer.mergeNewParams){
-                    var maxExtent = evt.layer.maxExtent;
-                    evt.layer.mergeNewParams({
-                        transparent: true,
-                        format: "image/png",
-                        tiled: true,
-                        tilesorigin: [maxExtent.left, maxExtent.bottom]
-                    });
-                }
-            },
-            scope : this
-        });
-        
-
-        // place map in panel
-        var mapConfig = this.initialConfig.map || {};
-        this.mapPanel = new GeoExt.MapPanel({
-            layout: "anchor",
-            border: true,
-            region: "center",
-            map: this.map,
-            // TODO: update the OpenLayers.Map constructor to accept an initial center
-            center: mapConfig.center && new OpenLayers.LonLat(mapConfig.center[0], mapConfig.center[1]),
-            // TODO: update the OpenLayers.Map constructor to accept an initial zoom
-            zoom: mapConfig.zoom,
-            items: [
-                {
-                    xtype: "gx_zoomslider",
-                    vertical: true,
-                    height: 100,
-                    plugins: new GeoExt.ZoomSliderTip({
-                        template: "<div>Zoom Level: {zoom}</div>"
-                    })
-                },
-                this.createMapOverlay()
-            ]
-        });
-        
-        // create layer store
-        this.layers = this.mapPanel.layers;
-        this.registerBackgroundListeners();                       
-
-        var addLayerButton = new Ext.Button({
-            tooltip : "Add Layers",
-            disabled: true,
-            iconCls: "icon-addlayers",
-            handler : this.showCapabilitiesGrid,
-            scope: this
-        });
-        this.on("ready", function() {addLayerButton.enable();});
-
-        var addBaseLayerButton = new Ext.Button({
-            tooltip : "Add Base Layers",
-            disabled: true,
-            iconCls: "icon-addlayers",
-            handler: this.showBaseCapabilitiesGrid,
-            scope: this
-        });
-        this.on("ready", function() {addBaseLayerButton.enable();});
-
-
-        //allow user to select only one layer at a time
-        //by sharing selection model
-        var selectionModel = new Ext.tree.DefaultSelectionModel({
-            listeners: {
-                beforeselect: function() {
-                    removeLayerAction.enable();
-                }
-            }
-        });
-
-        var baseSelectionModel = new Ext.tree.DefaultSelectionModel({
-            listeners: {
-                beforeselect: function() {
-                    removeBaseLayerAction.enable();
-                }
-            }
-        });
-
-        var removeLayerAction = new Ext.Action({
-            text: "Remove Layer",
-            iconCls: "icon-removelayers",
-            disabled: true,
-            tooltip: "Remove Layer",
-            handler: function() {
-                var node = selectionModel.getSelectedNode();
-                if(node && node.layer) {
-                    var layer = node.layer;
-                    var store = node.layerStore;
-                    var record = store.getAt(store.findBy(function(record) {
-                        return record.get("layer") === layer;
-                    }));
-                    store.remove(record);
-                    removeLayerAction.disable();
-                }
-            }
-        });
-
-        var removeBaseLayerAction = new Ext.Action({
-            text: "Remove Base Layer",
-            iconCls: "icon-removelayers",
-            disabled: true,
-            tooltip: "Remove Base Layer",
-            handler: function() {
-                var node = baseSelectionModel.getSelectedNode();
-                if(node && node.layer) {
-                    var layer = node.layer;
-                    var store = node.layerStore;
-                    var record = store.getAt(store.findBy(function(record) {
-                        return record.get("layer") === layer;
-                    }));
-                    store.remove(record);
-                    removeBaseLayerAction.disable();
-                }
-            }
-        });
-
-        var layerTreeConfig = {
-            border:false,
-            rootVisible: false,
-            autoScroll: true,
-            split: true,
-            listeners: {
-                contextmenu: function(node, e) {
-                    node.select();
-                    var c = node.getOwnerTree().contextMenu;
-                    c.contextNode = node;
-                    c.showAt(e.getXY());
-                },
-                scope: this
-            },
-            contextMenu: new Ext.menu.Menu({
-                items: [
-                    {
-                        text: "Zoom to Layer Extent",
-                        iconCls: "icon-zoom-visible",
-                        handler: function(){
-                            var node = selectionModel.getSelectedNode();
-                            if(node && node.layer) {
-                                this.map.zoomToExtent(node.layer.restrictedExtent);
-                            }
-                        },
-                        scope: this
-                    },
-                    removeLayerAction
-                ]
-            })
-        };        
-
-        var overlayLayerTree = new Ext.tree.TreePanel(
-            Ext.apply(
-                {
-                    title: "Layers",
-                    tbar: [
-                        addLayerButton,
-                        Ext.apply(new Ext.Button(removeLayerAction), {text: ""})
-                    ],
-                    selModel: selectionModel,
-                    root: new GeoExplorer.GroupContainer({
-                        background: false,
-                        layerStore: this.layerStore
-                    }),
-                    ddGroup: "OverlayLayerDD",
-                    height: 'auto',
-                    region: 'center',
-                    enableDD: true
-                }, 
-                layerTreeConfig));
-        
-        var baseLayerTree = new Ext.tree.TreePanel(
-            Ext.apply(
-                {
-                    title: 'Base Layers',
-                    tbar: [
-                        addBaseLayerButton,
-                        Ext.apply(new Ext.Button(removeBaseLayerAction), {text: ""})
-                    ],
-                    root: new GeoExplorer.GroupContainer({
-                        background: true,
-                        layerStore: this.layerStore
-                    }), 
-                    selModel: baseSelectionModel,
-                    ddGroup: "BaseLayerDD",
-                    height: 160,
-                    region: 'south',
-                    contextMenu: new Ext.menu.Menu({
-                    items: [
-                        {
-                            text: "Zoom to Layer Extent",
-                            iconCls: "icon-zoom-visible",
-                            handler: function(){
-                                var node = selectionModel.getSelectedNode();
-                                if(node && node.layer) {
-                                    this.map.zoomToExtent(node.layer.restrictedExtent);
-                                }
-                            },
-                            scope: this
-                        },
-                        removeBaseLayerAction
-                    ]
-            })
-        }, 
-        layerTreeConfig));
-
-        var layersContainer = new Ext.Panel({
-            border: false,
-            region: 'center',
-            layout: 'border',
-            items: [overlayLayerTree, baseLayerTree]
-        });
-
-        var legendContainer = new GeoExt.LegendPanel({
-            title: "Legend",
-            border: false,
-            region: 'south',
-            height: 200,
-            collapsible: true,
-            split: true,
-            autoScroll: true,
-            ascending: false,
-            map: this.map,
-            childDefaults: {border: false, cls: 'legend-title'}
-        });
-
-        var westPanel = new Ext.Panel({
-            border: true,
-            layout: "border",
-            region: "west",
-            width: 250,
-            split: true,
-            collapsible: true,
-            collapseMode: "mini",
-            items: [
-                layersContainer, legendContainer
-            ]
-        });
-        
-        var toolbar = new Ext.Toolbar({
-            xtype: "toolbar",
-            region: "north",
-            disabled: true,
-            items: this.createTools()
-        });
-        this.on("ready", function() {
-            // enable only those items that were not specifically disabled
-            var disabled = toolbar.items.filterBy(function(item) {
-                return item.initialConfig && item.initialConfig.disabled;
-            });
-            toolbar.enable();
-            disabled.each(function(item) {
-                item.disable();
-            });
-        });
-        
-        var viewport = new Ext.Viewport({
-            layout: "fit",
-            hideBorders: true,
-            items: {
-                layout: "border",
-                deferredRender: false,
-                items: [
-                    toolbar,
-                    this.mapPanel,
-                    westPanel
-                ]
-            }
-        });    
-    },
-
-    registerBackgroundListeners: function() {
-        
-        var updateBackground = function(store, candidate) {
-
-            var vis = [], all = [];
-            store.each(function(record) {
-                if(record.get("background")) {
-                    all.push(record);
-                    if(record.get("layer").getVisibility()) {
-                        vis.push(record);
-                    }
-                }
-            });
-            
-            if(all.length) {
-                candidate = candidate || all[0];
-                if(vis.length === 0) {
-                    candidate.get("layer").setVisibility(true);
-                } else if(vis.length > 1) {
-                    Ext.each(vis, function(r) {
-                        if(r !== candidate) {
-                            window.setTimeout(function() {
-                                r.get("layer").setVisibility(false);
-                            }, 0);
-                            return false;
-                        }
-                    });
-                }
-            }
-        };
-
-        // make sure one base layer is always visible after add, remove or update
-        this.layers.on({
-            add: function(store, records, index) {
-                var candidate;
-                Ext.each(records, function(r) {
-                    if(r.get("background")) {
-                        candidate = r;
-                        return false;
-                    }
-                });
-                if(candidate) {
-                    updateBackground(store, candidate);
-                }
-            },
-            remove: function(store, record, index) {
-                if(record.get("background")) {
-                    updateBackground(store);
-                }
-            },
-            update: function(store, record, op) {
-                if(record.get("background")) {
-                    updateBackground(store, record);
-                }
-            }
-        });
-
-    },
-    
-    /** private: method[activate]
-     * Activate the application.  Call after application is configured.
-     */
-    activate: function() {
-        
-        // add any layers from config
-        this.addLayers();
-
-        // initialize tooltips
-        Ext.QuickTips.init();
-        
-        this.fireEvent("ready");
-
-    },
-    
-    /** private: method[addLayers]
-     * Construct the layer store to be used with the map (referenced as 
-     * :attr:`GeoExplorer.layers`).
-     */
-    addLayers: function() {
-        var mapConfig = this.initialConfig.map;
-
-        if(mapConfig && mapConfig.layers) {
-            var records = [];
-            
-            for(var i = 0; i < mapConfig.layers.length; ++i) {
-                var conf = mapConfig.layers[i];
-                var index = this.layerSources.find("identifier", conf.ows);
-                
-                if (index == -1) {
-                    continue;
-                }
-                
-                var storeRecord = this.layerSources.getAt(index);
-                var store = storeRecord.data.store;
-
-                var id = store.find("name", conf.name);
-                
-                var record;
-                var base;
-                if (id >= 0) {
-                    record = store.getAt(id).copy();
-
-                    layer = record.get("layer");
-                    
-                    // set layer max extent from capabilities
-                    // TODO: make this SRS independent
-                    layer.restrictedExtent = OpenLayers.Bounds.fromArray(record.get("llbbox"));
-                    
-                    if (this.alignToGrid) {
-                        layer.maxExtent = new OpenLayers.Bounds(-180, -90, 180, 90);
-                    } else {
-                        layer.maxExtent = layer.restrictedExtent;
-                    }
-
-                    layer = layer.clone();
-                    record.set("layer", null); //need to do this because record.set compares String(value) to determine equality (dumb)
-                    record.set("layer", layer);
-
-                    // set layer visibility from config
-                    layer.visibility = ("visibility" in conf) ? conf.visibility : true;
-                    
-                    // set layer title from config
-                    if (conf.title) {
-                        layer.name = conf.title;
-                    }
-
-                    record.set("background", ("background" in conf ? 
-                                              conf.background : false));
-                    
-                    // set any other layer configuration
-                    // ensures that background layers are on the bottom
-                    if(record.get("background")){
-                        records.unshift(record);
-                    } else {
-                        records.push(record);
-                    }
-                }
-                
-            }
-            
-            this.layers.add(records);
-
-            // set map center
-            if(this.mapPanel.center) {
-                // zoom does not have to be defined
-                this.map.setCenter(this.mapPanel.center, this.mapPanel.zoom);
-            } else if (this.mapPanel.extent) {
-                this.map.zoomToExtent(this.mapPanel.extent);
-            } else {
-                this.map.zoomToMaxExtent();
-            }
-            
-        }
-    },
-
-    /**
-     * private: method[initCapGrid]
-     * Constructs a window with a capabilities grid.
-     */
-    initCapGrid: function(){
-
-        // TODO: Might be nice to subclass some of these things into
-        // into their own classes.
-
-        var firstSource = this.layerSources.getAt(0);
-
-        var capGridConfig = {
-            store: firstSource.data.store,
-            mapPanel : this.mapPanel,
-            layout: 'fit',
-            region: 'center',
-            autoScroll: true,
-            alignToGrid: this.alignToGrid,
-            listeners: {
-                rowdblclick: function(panel, index, evt) {
-                    panel.addLayers();
-                }
-            }
-        };
-
-        var capGridPanel = new GeoExplorer.CapabilitiesGrid(capGridConfig);
-        var baseCapGridPanel = new GeoExplorer.CapabilitiesGrid(capGridConfig);
-
-        var sourceComboConfig = {
-            store: this.layerSources,
-            valueField: "identifier",
-            displayField: "name",
-            triggerAction: "all",
-            editable: false,
-            allowBlank: false,
-            forceSelection: true,
-            mode: "local",
-            value: firstSource.data.identifier
-        };
-
-        var sourceComboBox = new Ext.form.ComboBox(sourceComboConfig);
-        sourceComboBox.on("select", function(combo, record, index) {
-            capGridPanel.reconfigure(record.data.store, capGridPanel.getColumnModel());
-        }, this);
-
-        var baseSourceComboBox = new Ext.form.ComboBox(sourceComboConfig);
-        baseSourceComboBox.on("select", function(combo, record, index) {
-            capGridPanel.reconfigure(record.data.store, baseCapGridPanel.getColumnModel());
-        }, this);
-
-        var capGridToolbar = null;
-        var baseCapGridToolbar = null;
-
-        if (this.proxy || this.layerSources.getCount() > 1) {
-            capGridToolbar = [
-                new Ext.Toolbar.TextItem({
-                    text: "View available data from:"
-                }),
-                sourceComboBox
-            ];
-            baseCapGridToolbar = [
-                new Ext.Toolbar.TextItem({
-                    text: "View available data from:"
-                }),
-                baseSourceComboBox
-            ];
-        }
-
-        if (this.proxy) {
-            capGridToolbar.push(new Ext.Button({
-                text: "or add a new server.",
-                handler: function() {
-                    newSourceWindow.show();
-                }
-            }));
-            baseCapGridToolbar.push(new Ext.Button({
-                text: "or add a new server.",
-                handler: function() {
-                    newSourceWindow.show();
-                }
-            }));
-        }
-
-        var newSourceWindow = new GeoExplorer.NewSourceWindow();
-        
-        newSourceWindow.on("server-added", function(url) {
-            newSourceWindow.setLoading();
-            
-            var success = function(record) {
-                // The combo box will automatically update when a new item
-                // is added to the layerSources store. Now all we have to
-                // do is select it. Note: There's probably a better way to do this, 
-                // but there doesn't seem to be another way to get the select event
-                // to fire.
-                var index = this.layerSources.find("identifier", record.data.identifier);
-                sourceComboBox.fireEvent("select", sourceComboBox, record, index);
-                
-                // Close the new source window.
-                newSourceWindow.hide();
-            };
-            
-            var failure = function() {
-                newSourceWindow.setError("Error contacting server.\nPlease check the url and try again.");
-            };
-            
-            this.addSource(url, null, success, failure, this);
-        }, this);
-        
-        this.capGrid = new Ext.Window({
-            title: "Available Layers",
-            closeAction: 'hide',
-            layout: 'border',
-            height: 300,
-            width: 600,
-            modal: true,
-            items: [
-                capGridPanel
-            ],
-            tbar: capGridToolbar,
-            bbar: [
-                "->",
-                new Ext.Button({
-                    text: "Add Layers",
-                    iconCls: "icon-addlayers",
-                    handler: function(){
-                        capGridPanel.addLayers();
-                    },
-                    scope : this
-                }),
-                new Ext.Button({
-                    text: "Done",
-                    handler: function() {
-                        this.capGrid.hide();
-                    },
-                    scope: this
-                })
-            ],
-            listeners: {
-                hide: function(win){
-                    capGridPanel.getSelectionModel().clearSelections();
-                }
-            }
-        });
-
-        this.baseCapGrid = new Ext.Window({
-            title: "Available Base Layers",
-            closeAction: 'hide',
-            layout: 'border',
-            height: 300,
-            width: 600,
-            modal: true,
-            items: [
-                baseCapGridPanel
-            ],
-            tbar: baseCapGridToolbar,
-            bbar: [
-                "->",
-                new Ext.Button({
-                    text: "Add Base Layers",
-                    iconCls: "icon-addlayers",
-                    handler: function(){
-                        baseCapGridPanel.addLayers(true);
-                    },
-                    scope : this
-                }),
-                new Ext.Button({
-                    text: "Done",
-                    handler: function() {
-                        this.baseCapGrid.hide();
-                    },
-                    scope: this
-                })
-            ]
-        });
- 
-    },
-
-    /** private: method[showCapabilitiesGrid]
-     * Shows the window with a capabilities grid.
-     */
-    showBaseCapabilitiesGrid: function() {
-        if(!this.capGrid) {
-            this.initCapGrid();
-        }
-        this.baseCapGrid.show();
-    },
-
-    /** private: method[showCapabilitiesGrid]
-     * Shows the window with a capabilities grid.
-     */
-    showCapabilitiesGrid: function() {
-        if(!this.capGrid) {
-            this.initCapGrid();
-        }
-        this.capGrid.show();
-    },
-
-    /** private: method[createMapOverlay]
-     * Builds the :class:`Ext.Panel` containing components to be overlaid on the
-     * map, setting up the special configuration for its layout and 
-     * map-friendliness.
-     */
-    createMapOverlay: function() {
-        var scaleLinePanel = new Ext.Panel({
-            cls: 'olControlScaleLine overlay-element overlay-scaleline',
-            border: false
-        });
-
-        scaleLinePanel.on('render', function(){
-            var scaleLine = new OpenLayers.Control.ScaleLine({
-                div: scaleLinePanel.body.dom
-            });
-
-            this.map.addControl(scaleLine);
-            scaleLine.activate();
-        }, this);
-
-        var zoomStore = new GeoExt.data.ScaleStore({
-            map: this.map
-        });
-
-        var zoomSelector = new Ext.form.ComboBox({
-            emptyText: 'Zoom level',
-            tpl: '<tpl for="."><div class="x-combo-list-item">1 : {[parseInt(values.scale)]}</div></tpl>',
-            editable: false,
-            triggerAction: 'all',
-            mode: 'local',
-            store: zoomStore,
-            width: 110
-        });
-
-        zoomSelector.on('click', function(evt){evt.stopEvent();});
-        zoomSelector.on('mousedown', function(evt){evt.stopEvent();});
-
-        zoomSelector.on('select', function(combo, record, index) {
-                this.map.zoomTo(record.data.level);
-            },
-            this);
-
-        var zoomSelectorWrapper = new Ext.Panel({
-            items: [zoomSelector],
-            cls: 'overlay-element overlay-scalechooser',
-            border: false });
-
-        this.map.events.register('zoomend', this, function() {
-            var scale = zoomStore.queryBy(function(record){
-                return this.map.getZoom() == record.data.level;
-            });
-
-            if (scale.length > 0) {
-                scale = scale.items[0];
-                zoomSelector.setValue("1 : " + parseInt(scale.data.scale, 10));
-            } else {
-                if (!zoomSelector.rendered) return;
-                zoomSelector.clearValue();
-            }
-        });
-
-        var mapOverlay = new Ext.Panel({
-            // title: "Overlay",
-            cls: 'map-overlay',
-            items: [
-                scaleLinePanel,
-                zoomSelectorWrapper
-            ]
-        });
-
-
-        mapOverlay.on("afterlayout", function(){
-            scaleLinePanel.body.dom.style.position = 'relative';
-            scaleLinePanel.body.dom.style.display = 'inline';
-
-            mapOverlay.getEl().on("click", function(x){x.stopEvent();});
-            mapOverlay.getEl().on("mousedown", function(x){x.stopEvent();});
-        }, this);
-
-        return mapOverlay;
-    },
-
-    /** private: method[createTools]
-     * Create the toolbar configuration for the main panel.  This method can be 
-     * overridden in derived explorer classes such as :class:`GeoExplorer.Full`
-     * or :class:`GeoExplorer.Embed` to provide specialized controls.
-     */
-    createTools: function() {
-
-        var toolGroup = "toolGroup";
-
-        // create a navigation control
-        var navAction = new GeoExt.Action({
-            tooltip: "Pan Map",
-            iconCls: "icon-pan",
-            enableToggle: true,
-            pressed: true,
-            allowDepress: false,
-            control: new OpenLayers.Control.Navigation(),
-            map: this.map,
-            toggleGroup: toolGroup
-        });
-
-        // create a navigation history control
-        var historyControl = new OpenLayers.Control.NavigationHistory();
-        this.map.addControl(historyControl);
-
-        // create actions for previous and next
-        var navPreviousAction = new GeoExt.Action({
-            tooltip: "Zoom to Previous Extent",
-            iconCls: "icon-zoom-previous",
-            disabled: true,
-            control: historyControl.previous
-        });
-        
-        var navNextAction = new GeoExt.Action({
-            tooltip: "Zoom to Next Extent",
-            iconCls: "icon-zoom-next",
-            disabled: true,
-            control: historyControl.next
-        });
-
-        var toolGroup = "toolGroup";
-        
-        // create a get feature info control
-        var info = {controls: []};
-        var infoButton = new Ext.Button({
-            tooltip: "Get Feature Info",
-            iconCls: "icon-getfeatureinfo",
-            toggleGroup: toolGroup,
-            enableToggle: true,
-            allowDepress: false,
-            toggleHandler: function(button, pressed) {
-                for (var i = 0, len = info.controls.length; i < len; i++){
-                    if(pressed) {
-                        info.controls[i].activate();
-                    } else {
-                        info.controls[i].deactivate();
-                    }
-                }
-            }
-        });
-
-        var updateInfo = function() {
-            var queryableLayers = this.mapPanel.layers.queryBy(function(x){
-                return x.get("queryable");
-            });
-
-            var map = this.mapPanel.map;
-            var control;
-            for (var i = 0, len = info.controls.length; i < len; i++){
-                control = info.controls[i];
-                control.deactivate();  // TODO: remove when http://trac.openlayers.org/ticket/2130 is closed
-                control.destroy();
-            }
-
-            info.controls = [];
-            queryableLayers.each(function(x){
-                var control = new OpenLayers.Control.WMSGetFeatureInfo({
-                    url: x.get("layer").url,
-                    queryVisible: true,
-                    layers: [x.get("layer")],
-                    eventListeners: {
-                        getfeatureinfo: function(evt) {
-                            this.displayPopup(evt, x.get("title") || x.get("name"));
-                        },
-                        scope: this
-                    }
-                });
-                map.addControl(control);
-                info.controls.push(control);
-                if(infoButton.pressed) {
-                    control.activate();
-                }
-            }, this);
-        };
-
-        this.mapPanel.layers.on("update", updateInfo, this);
-        this.mapPanel.layers.on("add", updateInfo, this);
-        this.mapPanel.layers.on("remove", updateInfo, this);
-
-        // create length measure control
-        var measureLength = this.createMeasureTool(
-            OpenLayers.Handler.Path, 'Length');
-        this.map.addControl(measureLength);
-        
-        // create area measure control
-        var measureArea = this.createMeasureTool(
-            OpenLayers.Handler.Polygon, 'Area');
-        this.map.addControl(measureArea);
-
-        var tools = [
-            navAction,
-            infoButton,
-            new GeoExplorer.MapToolSplitToggle({
-                tooltip: "Measure",
-                iconCls: "icon-measure-length",
-                defaultTool: measureLength,
-                allowDepress: false,
-                tools: [
-                    {text: 'Length', tool: measureLength, iconCls: 'icon-measure-length'}, 
-                    {text: 'Area', tool: measureArea, iconCls: 'icon-measure-area'}
-                ],
-                enableToggle: true,
-                toggleGroup: toolGroup 
-            }),
-            "-",
-            new Ext.Button({
-                handler: function(){
-                    this.map.zoomIn();
-                },
-                tooltip: "Zoom In",
-                iconCls: "icon-zoom-in",
-                scope: this
-            }),
-            new Ext.Button({
-                tooltip: "Zoom Out",
-                handler: function(){
-                    this.map.zoomOut();
-                },
-                iconCls: "icon-zoom-out",
-                scope: this
-            }),
-            navPreviousAction,
-            navNextAction,
-            new Ext.Button({
-                tooltip: "Zoom to Visible Extent",
-                iconCls: "icon-zoom-visible",
-                handler: function() {
-                    var extent, layer;
-                    for(var i=0, len=this.map.layers.length; i<len; ++i) {
-                        layer = this.map.layers[i];
-                        if(layer.getVisibility()) {
-                            if(extent) {
-                                extent.extend(layer.maxExtent);
-                            } else {
-                                extent = layer.maxExtent.clone();
-                            }
-                        }
-                    }
-                    if(extent) {
-                        this.map.zoomToExtent(extent);
-                    }
-                },
-                scope: this
-            })
-        ];
-
-        return tools;
-    },
-
-    /** private: method[createMeasureTool]
-     * :param: handlerType: the :class:`OpenLayers.Handler` for the measurement
-     *     operation
-     * :param: title: the string label to display alongside results
-     *
-     * Convenience method for creating a :class:`OpenLayers.Control.Measure` 
-     * control
-     */
-    createMeasureTool: function(handlerType, title) {
-        
-        var styleMap = new OpenLayers.StyleMap({
-            "default": new OpenLayers.Style(null, {
-                rules: [new OpenLayers.Rule({
-                    symbolizer: {
-                        "Point": {
-                            pointRadius: 4,
-                            graphicName: "square",
-                            fillColor: "white",
-                            fillOpacity: 1,
-                            strokeWidth: 1,
-                            strokeOpacity: 1,
-                            strokeColor: "#333333"
-                        },
-                        "Line": {
-                            strokeWidth: 3,
-                            strokeOpacity: 1,
-                            strokeColor: "#666666",
-                            strokeDashstyle: "dash"
-                        },
-                        "Polygon": {
-                            strokeWidth: 2,
-                            strokeOpacity: 1,
-                            strokeColor: "#666666",
-                            fillColor: "white",
-                            fillOpacity: 0.3
-                        }
-                    }
-                })]
-            })
-        });
-
-        var cleanup = function() {
-            if (measureToolTip) {
-                measureToolTip.destroy();
-            }   
-        };
-
-        var makeString = function(metricData) {
-            var metric = metricData.measure;
-            var metricUnit = metricData.units;
-            
-            measureControl.displaySystem = "english";
-            
-            var englishData = metricData.geometry.CLASS_NAME.indexOf("LineString") > -1 ?
-            measureControl.getBestLength(metricData.geometry) :
-            measureControl.getBestArea(metricData.geometry);
-
-            var english = englishData[0];
-            var englishUnit = englishData[1];
-            
-            measureControl.displaySystem = "metric";
-            var dim = metricData.order == 2 ? 
-            '<sup>2</sup>' :
-            '';
-            
-            return metric.toFixed(2) + " " + metricUnit + dim + "<br>" + 
-                english.toFixed(2) + " " + englishUnit + dim;
-        };
-        
-        var measureToolTip; 
-        var measureControl = new OpenLayers.Control.Measure(handlerType, {
-            persist: true,
-            handlerOptions: {layerOptions: {styleMap: styleMap}},
-            eventListeners: {
-                measurepartial: function(event) {
-                    cleanup();
-                    measureToolTip = new Ext.ToolTip({
-                        html: makeString(event),
-                        title: title,
-                        autoHide: false,
-                        closable: true,
-                        draggable: false,
-                        mouseOffset: [0, 0],
-                        showDelay: 1,
-                        listeners: {hide: cleanup}
-                    });
-                    if(event.measure > 0) {
-                        var px = measureControl.handler.lastUp;
-                        var p0 = this.mapPanel.getPosition();
-                        measureToolTip.targetXY = [p0[0] + px.x, p0[1] + px.y];
-                        measureToolTip.show();
-                    }
-                },
-                measure: function(event) {
-                    cleanup();                    
-                    measureToolTip = new Ext.ToolTip({
-                        target: Ext.getBody(),
-                        html: makeString(event),
-                        title: title,
-                        autoHide: false,
-                        closable: true,
-                        draggable: false,
-                        mouseOffset: [0, 0],
-                        showDelay: 1,
-                        listeners: {
-                            hide: function() {
-                                measureControl.cancel();
-                                cleanup();
-                            }
-                        }
-                    });
-                },
-                deactivate: cleanup,
-                scope: this
-            }
-        });
-
-        return measureControl;
-    },
-
-    /** private: method[displayPopup]
-     * :param: evt: the event object from a 
-     *     :class:`OpenLayers.Control.GetFeatureInfo` control
-     * :param: title: a String to use for the title of the results section 
-     *     reporting the info to the user
-     */
-    displayPopup: function(evt, title) {
-        var popup;
-        var popupKey = evt.xy.x + "." + evt.xy.y;
-
-        if (!(popupKey in this.popupCache)) {
-            var lonlat = this.map.getLonLatFromPixel(evt.xy);
-            popup = new GeoExt.Popup({
-                title: "Feature Info",
-                lonlat: lonlat,
-                map: this.mapPanel,
-                width: 250,
-                height: 300,
-                autoScroll: true,
-                listeners: {
-                    close: (function(key) {
-                        return function(panel){
-                            delete this.popupCache[key];
-                        };
-                    })(popupKey),
-                    scope: this
-                }
-            });
-            popup.show();
-            this.popupCache[popupKey] = popup;
-        } else {
-            popup = this.popupCache[popupKey];
-        }
-
-        var html = evt.text;
-        if (!(html === '' || html.match(/<body>\s*<\/body>/))) {
-            popup.add({
-                title: title,
-                html: html,
-                autoScroll: true,
-                collapsible: true
-            });
-        }
-
-        popup.doLayout();
-    },
-
-
-    /**
-     * private: method[bookmark]
-     * :return: the URL :class:`String` that was displayed to the user
-     *
-     * Creates a window that shows the user a URL that can be used to
-     * reload the map in its current configuration.
-     */ 
-    bookmark: function(){
-        var config = this.extractConfiguration();
-
-        var query = Ext.urlEncode({q: Ext.util.JSON.encode(config)});
-
-        var url = 
-            document.location.protocol + "//" +
-            document.location.hostname +
-            document.location.pathname + "?" + query;
-
-        var win = new Ext.Window({
-            title: "Bookmark URL",
-            layout: 'form',
-            items: [{
-                xtype: 'textfield',
-                fieldLabel: 'Permalink',
-                readOnly: true,
-                value: url
-            }],
-            width: 300
-        });
-
-        win.show();
-
-        return url;
-    },
-    
-    /**
-     * private: method[extractConfiguration]
-     * :return: an :class:`Object` representing the app's current configuration.
-     */ 
-    extractConfiguration: function() {
-        var config = {
-            ows: {}
-        };
-
-        // Map configuration
-
-        var center = this.map.getCenter();
-        
-        config.map = {
-            center: [center.lon, center.lat],
-            zoom: this.map.zoom
-        };
-
-        var sourcesUsed = {};
-
-        //Layers configuration
-        config.map.layers = [];
-        
-        this.layers.each(function(layerRecord){
-            var layer = layerRecord.get('layer');
-            if (layer.displayInLayerSwitcher) {
-                
-                // Get the source of this layer.
-                var index = this.layerSources.find("identifier", layerRecord.get("source_id"));
-                var source = this.layerSources.getAt(index);
-                
-                if (source === null) {
-                    OpenLayers.Console.error("Could not find source for layer '" + layerRecord.get("name") + "'");
-                    
-                    // Return; error gracefully. (This is debatable.)
-                    return;
-                }
-
-                sourcesUsed[source.get("identifier")] = source.get("url");
-                
-                var c = {
-                    name: layerRecord.get("name"),
-                    visibility: layer.getVisibility(),
-                    background: layerRecord.get('background'),
-                    ows: source.get("identifier")
-                };
-
-                config.map.layers.push(c);
-            }
-        }, this);
-        
-        // Source configuration
-        for (identifier in sourcesUsed) {
-            config.ows[identifier] = sourcesUsed[identifier];
-        }
-        
-        return config;
-    },
-
-    /** private: method[displayAppInfo]
-     * Display an informational dialog about the application.
-     */
-    displayAppInfo: function() {
-        var appInfo = new Ext.Panel({
-            title: "GeoExplorer",
-            html: "<iframe style=\"border: none; height: 100%; width: 100%\" src=\"about.html\"><a target=\"_blank\" href=\"about.html\">About GeoExplorer</a> </iframe>"
-        });
-
-        var about = Ext.applyIf(this.about, {
-            title: '', 
-            "abstract": '', 
-            keywords: '',
-            contact: ''
-        });
-
-        var mapInfo = new Ext.Panel({
-            title: "Map Info",
-            html: '<div class="gx-info-panel">' 
-            + '<h2> Title </h2> <p>' + about.title 
-            + '</p> <h2> Abstract </h2> <p>' + about['abstract'] 
-            + '</p> <h2> Keywords </h2> <p>' + about.keywords 
-            + '</p> <h2> Contact </h2> <p>' + about.contact +' </p> </div>',
-            height: 'auto',
-            width: 'auto'
-        });
-
-        var tabs = new Ext.TabPanel({
-            activeTab: 0,
-            width: 300,
-            height: 350,
-            items:[mapInfo, appInfo]
-        });
-
-        var win = new Ext.Window({
-            title: "About this Map",
-            modal: true,
-            items: [tabs]
-        });
-        win.show();
-    }
-});
-

Deleted: apps/opengeo/geoexplorer/trunk/script/GeoExplorer-debug.js
===================================================================
--- apps/opengeo/geoexplorer/trunk/script/GeoExplorer-debug.js	2009-06-29 16:48:53 UTC (rev 1164)
+++ apps/opengeo/geoexplorer/trunk/script/GeoExplorer-debug.js	2009-06-29 22:12:56 UTC (rev 1165)
@@ -1,42 +0,0 @@
-(function() {
-
-    // Since the applications are located one directory down from
-    // the base, all these includes must be prefixed by a ../
-    var jsfiles = new Array(
-        "lib/GeoExplorer.js",
-        "lib/GeoExplorer/util.js",
-        "lib/Ext/grid/RowExpander.js",
-        "lib/GeoExplorer/MapToolToggle.js",
-        "lib/GeoExplorer/MapToolSplitToggle.js",
-        "lib/GeoExplorer/MapToolMenu.js",
-        "lib/GeoExplorer/Wizard.js",
-        "lib/GeoExplorer/LayerMenuItem.js",
-        "lib/GeoExplorer/CapabilitiesGrid.js",
-        "lib/GeoExplorer/GroupContainer.js",
-        "lib/GeoExplorer/Full.js",
-        "lib/GeoExplorer/Embed.js",
-        "lib/GeoExplorer/NewSourceWindow.js"
-    );
-
-    var appendable = !(/MSIE/.test(navigator.userAgent) ||
-                       /Safari/.test(navigator.userAgent));
-    var pieces = new Array(jsfiles.length);
-
-    var element = document.getElementsByTagName("head").length ?
-                    document.getElementsByTagName("head")[0] :
-                    document.body;
-    var script;
-
-    for(var i=0; i<jsfiles.length; i++) {
-        if(!appendable) {
-            pieces[i] = "<script src='" + jsfiles[i] + "'></script>"; 
-        } else {
-            script = document.createElement("script");
-            script.src = jsfiles[i];
-            element.appendChild(script);
-        }
-    }
-    if(!appendable) {
-        document.write(pieces.join(""));
-    }
-})();

Copied: apps/opengeo/geoexplorer/trunk/src/html/about.html (from rev 1164, apps/opengeo/geoexplorer/trunk/about.html)
===================================================================
--- apps/opengeo/geoexplorer/trunk/src/html/about.html	                        (rev 0)
+++ apps/opengeo/geoexplorer/trunk/src/html/about.html	2009-06-29 22:12:56 UTC (rev 1165)
@@ -0,0 +1,36 @@
+<html>
+    <head>
+        <title>About GeoExplorer</title>
+        <link rel="stylesheet" type="text/css" href="@about.css@"/>
+    </head>
+    <body>
+    <div class="logo"></div>
+    <h2> GeoExplorer </h2>
+    <div class="versioninfo">Version 0.1</div>
+    <h3> Engineering & Design by OpenGeo </h3>
+    <a href="http://opengeo.org/">http://opengeo.org/</a>
+    &copy; 2009, OpenGeo under the BSD license.
+
+    <h3> GeoExt Framework </h3>
+    <a href="http://geoext.org/">http://geoext.org/</a>
+    &copy; 2009, OSGeo under the BSD license.
+
+    <h3> GeoSilk Icons </h3>
+    <a href="http://projects.opengeo.org/geosilk/">http://projects.opengeo.org/geosilk/</a>
+    &copy; 2009, OpenGeo under CC-BY 3.0.
+
+    <h3> Silk Icons </h3>
+    <a href="http://famfamfam.com/lab/icons/silk/">http://famfamfam.com/lab/icons/silk/</a>
+    &copy; Mark James under CC-BY 3.0.
+
+    <h3> Contributors </h3>
+    <ul>
+    <li>Tim Schaub</li>
+    <li>David Winslow</li>
+    <li>Sebastian Benthall</li>
+    <li>Andreas Hocevar</li>
+    <li>Tim Coulter</li>
+    <li>Rolando Pe&ntilde;ate</li>
+    </ul>
+    </body>
+</html>


Property changes on: apps/opengeo/geoexplorer/trunk/src/html/about.html
___________________________________________________________________
Name: svn:mergeinfo
   + 

Copied: apps/opengeo/geoexplorer/trunk/src/html/debug.html (from rev 1164, apps/opengeo/geoexplorer/trunk/debug.html)
===================================================================
--- apps/opengeo/geoexplorer/trunk/src/html/debug.html	                        (rev 0)
+++ apps/opengeo/geoexplorer/trunk/src/html/debug.html	2009-06-29 22:12:56 UTC (rev 1165)
@@ -0,0 +1,67 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+    <head>
+        <title>@title@</title>
+        
+        <!-- IE 8 Compatibility -->
+        <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
+        
+        <!-- Ext resources -->
+        <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/resources/css/ext-all.css" />
+        <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/resources/css/xtheme-gray.css" />
+        <script type="text/javascript" src="http://extjs.cachefly.net/ext-2.2.1/adapter/ext/ext-base.js"></script>
+        <script type="text/javascript" src="http://extjs.cachefly.net/ext-2.2.1/@ext-all.js@"></script>
+
+        <!-- OpenLayers resources -->
+        <link rel="stylesheet" type="text/css" href="@ol-style.css@" />
+        <script type="text/javascript" src="@OpenLayers.js@"></script>
+
+        <!-- GeoExt resources -->
+        <link rel="stylesheet" type="text/css" href="@geoext-all.css@" />
+        <link rel="stylesheet" type="text/css" href="@gxtheme-gray.css@" />
+        <script type="text/javascript" src="@GeoExt.js@"></script> 
+
+        <!-- GeoExplorer resources -->
+        <link rel="stylesheet" type="text/css" href="@geoexplorer.css@" />
+        <!--[if IE]><link rel="stylesheet" type="text/css" href="@ie.css@"/><![endif]-->        
+        <script type="text/javascript" src="@GeoExplorer.js@"></script>
+        <script type="text/javascript" src="@ux.js@"></script>
+
+        <script>
+            Ext.BLANK_IMAGE_URL = "../../theme/img/blank.gif";
+            var app = new GeoExplorer.Full({
+                proxy: "/proxy/?url=",
+                about: {
+                    title: "Example Map",
+                    "abstract": "A description of the map's contents",
+                    keywords: "example, test, development",
+                    contact: "Georj the Robot, Representative, OpenGeo, http://opengeo.org/"
+                },
+                ows: {
+                    "demo": "http://demo.opengeo.org/geoserver/ows/"
+                },
+                map: {
+                    layers: [{
+                        name: "nurc:Img_Sample",
+                        ows: "demo"
+                    },{
+                        name: "topp:states",
+                        ows: "demo",
+                        background: true,
+                        visibility:true
+                    },{
+                        name: "topp:bluemarble",
+                        ows: "demo",
+                        visibility: false,
+                        background: true  
+                    }],
+                    center: [-96.7, 37.6],
+                    zoom: 4
+                }
+            });
+        </script>
+
+    </head>
+    <body>
+    </body>
+</html>


Property changes on: apps/opengeo/geoexplorer/trunk/src/html/debug.html
___________________________________________________________________
Name: svn:mergeinfo
   + 

Copied: apps/opengeo/geoexplorer/trunk/src/html/embed-debug.html (from rev 1164, apps/opengeo/geoexplorer/trunk/embed-debug.html)
===================================================================
--- apps/opengeo/geoexplorer/trunk/src/html/embed-debug.html	                        (rev 0)
+++ apps/opengeo/geoexplorer/trunk/src/html/embed-debug.html	2009-06-29 22:12:56 UTC (rev 1165)
@@ -0,0 +1,64 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+    <head>
+        <title>@title@</title>
+        
+        <!-- IE 8 Compatibility -->
+        <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
+        
+        <!-- Ext resources -->
+        <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/resources/css/ext-all.css" />
+        <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/resources/css/xtheme-gray.css" />
+        <script type="text/javascript" src="http://extjs.cachefly.net/ext-2.2.1/adapter/ext/ext-base.js"></script>
+        <script type="text/javascript" src="http://extjs.cachefly.net/ext-2.2.1/@ext-all.js@"></script>
+
+        <!-- OpenLayers resources -->
+        <link rel="stylesheet" type="text/css" href="@ol-style.css@" />
+        <script type="text/javascript" src="@OpenLayers.js@"></script>
+
+        <!-- GeoExt resources -->
+        <link rel="stylesheet" type="text/css" href="@geoext-all.css@" />
+        <link rel="stylesheet" type="text/css" href="@gxtheme-gray.css@" />
+        <script type="text/javascript" src="@GeoExt.js@"></script> 
+
+        <!-- GeoExplorer resources -->
+        <link rel="stylesheet" type="text/css" href="@geoexplorer.css@" />
+        <!--[if IE]><link rel="stylesheet" type="text/css" href="@ie.css@"/><![endif]-->        
+        <script type="text/javascript" src="@GeoExplorer.js@"></script>
+
+        <script>
+            Ext.BLANK_IMAGE_URL = "theme/img/blank.gif";
+            var app = new GeoExplorer.Embed({
+                proxy: "/proxy/?url=",
+                about: {
+                    title: 'Example Map',
+                    "abstract": 'A description of the map\'s contents',
+                    keywords: "example, test, development",
+                    contact: "Georj the Robot, Outreach Tribe Leader, OpenGeo, http://opengeo.org/"
+                },
+                ows: {
+                    "demo": "http://demo.opengeo.org/geoserver/ows"
+                },
+                map: {
+                    layers: [{
+                        name: "openstreetmap",
+                        ows: "demo",
+                        background: true  
+                    },{
+                        name: "nurc:Img_Sample",
+                        ows: "demo"
+                    },{
+                        name: "topp:states",
+                        ows: "demo",
+                        background: true  
+                    }],
+                    center: [-96.7, 37.6],
+                    zoom: 4
+                }
+            });
+        </script>
+
+    </head>
+    <body>
+    </body>
+</html>


Property changes on: apps/opengeo/geoexplorer/trunk/src/html/embed-debug.html
___________________________________________________________________
Name: svn:mergeinfo
   + 

Copied: apps/opengeo/geoexplorer/trunk/src/html/embed-example.html (from rev 1164, apps/opengeo/geoexplorer/trunk/embed-example.html)
===================================================================
--- apps/opengeo/geoexplorer/trunk/src/html/embed-example.html	                        (rev 0)
+++ apps/opengeo/geoexplorer/trunk/src/html/embed-example.html	2009-06-29 22:12:56 UTC (rev 1165)
@@ -0,0 +1,14 @@
+<html>
+    <head>
+    <title> Embedded GeoExplorer Example </title>
+    <!-- look ma, no <script> tags -->
+    </head>
+    <body>
+        <h2> Embedded GeoExplorer </h2>
+        <p> You can embed a GeoExplorer application inside of other web pages, using the <code> GeoExplorer.Embed </code> class.  This supports all of the persisted options available in the full version, including layers, styles, tools, and metadata, but with GUI components optimized for inclusion in a larger page such as a blog post.
+        </p>
+        <iframe style="height: 400px; width: 600px; border: 0px" src="embed-debug.html">
+        If you see this text, your browser doesn't handle frames properly.  Try a recent version of <a href="http://www.mozilla.com/en-US/firefox/">Firefox</a>.
+        </iframe>
+    </body>
+</html>


Property changes on: apps/opengeo/geoexplorer/trunk/src/html/embed-example.html
___________________________________________________________________
Name: svn:mergeinfo
   + 

Copied: apps/opengeo/geoexplorer/trunk/src/html/embed.html (from rev 1164, apps/opengeo/geoexplorer/trunk/embed.html)
===================================================================
--- apps/opengeo/geoexplorer/trunk/src/html/embed.html	                        (rev 0)
+++ apps/opengeo/geoexplorer/trunk/src/html/embed.html	2009-06-29 22:12:56 UTC (rev 1165)
@@ -0,0 +1,62 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+    <head>
+        <title>GeoExplorer Embedded (debug)</title>
+        
+        <!-- This file is expected to go into an iframe. -->
+        
+        <!-- Ext resources -->
+        <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/resources/css/ext-all.css" />
+        <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/resources/css/xtheme-gray.css" />
+        <script type="text/javascript" src="http://extjs.cachefly.net/ext-2.2.1/adapter/ext/ext-base.js"></script>
+        <script type="text/javascript" src="http://extjs.cachefly.net/ext-2.2.1/ext-all.js"></script>
+
+        <!-- OpenLayers resources -->
+        <link rel="stylesheet" type="text/css" href="externals/openlayers/theme/default/style.css" />
+        <script type="text/javascript" src="externals/openlayers/lib/OpenLayers.js"></script>
+
+        <!-- GeoExt resources -->
+        <script type="text/javascript" src="externals/geoext/lib/GeoExt.js"></script> 
+        <script type="text/javascript" src="externals/geoext/lib/GeoExt-LegendPanel.js"></script> 
+        <link rel="stylesheet" type="text/css" href="externals/geoext/resources/css/geoext-all-debug.css" />
+        <link rel="stylesheet" type="text/css" href="externals/geoext/resources/css/gxtheme-gray.css" />
+
+        <!-- GeoExplorer resources -->
+        <link rel="stylesheet" type="text/css" href="theme/geoexplorer.css" />
+        <!--[if IE]>
+        <link rel="stylesheet" type="text/css" href="theme/ie.css"/><![endif]-->
+
+        <script type="text/javascript" src="script/GeoExplorer.js"></script>
+
+        <script>
+            Ext.BLANK_IMAGE_URL = "theme/img/blank.gif";
+            var app = new GeoExplorer.Embed({
+                proxy: "/proxy/?url=",
+                ows: {
+                    "demo": "http://demo.opengeo.org/geoserver/ows/"
+                },
+                map: {
+                    layers: [{
+                        name: "nurc:Img_Sample",
+                        ows: "demo"
+                    },{
+                        name: "topp:states",
+                        ows: "demo",
+                        background: true,
+                        visibility:true
+                    },{
+                        name: "topp:bluemarble",
+                        ows: "demo",
+                        visibility: false,
+                        background: true  
+                    }],
+                    center: [-96.7, 37.6],
+                    zoom: 4
+                }
+            });
+        </script>
+
+    </head>
+    <body>
+    </body>
+</html>


Property changes on: apps/opengeo/geoexplorer/trunk/src/html/embed.html
___________________________________________________________________
Name: svn:mergeinfo
   + 

Copied: apps/opengeo/geoexplorer/trunk/src/html/index.html (from rev 1164, apps/opengeo/geoexplorer/trunk/index.html)
===================================================================
--- apps/opengeo/geoexplorer/trunk/src/html/index.html	                        (rev 0)
+++ apps/opengeo/geoexplorer/trunk/src/html/index.html	2009-06-29 22:12:56 UTC (rev 1165)
@@ -0,0 +1,57 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+    <head>
+        <title>GeoExplorer</title>
+        
+        <!-- IE 8 Compatibility -->
+        <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
+        
+        <!-- Ext resources -->
+        <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/resources/css/ext-all.css" />
+        <link rel="stylesheet" type="text/css" href="http://extjs.cachefly.net/ext-2.2.1/resources/css/xtheme-gray.css" />
+        <script type="text/javascript" src="http://extjs.cachefly.net/ext-2.2.1/adapter/ext/ext-base.js"></script>
+        <script type="text/javascript" src="http://extjs.cachefly.net/ext-2.2.1/ext-all.js"></script>
+
+        <!-- OpenLayers resources -->
+        <link rel="stylesheet" type="text/css" href="externals/openlayers/theme/default/style.css" />
+        <script type="text/javascript" src="script/OpenLayers.js"></script>
+
+        <!-- GeoExt resources -->
+        <script type="text/javascript" src="script/GeoExt.js"></script>
+        <script type="text/javascript" src="script/GeoExt-LegendPanel.js"></script>
+        <link rel="stylesheet" type="text/css" href="externals/geoext/resources/css/geoext-all-debug.css" />
+        <link rel="stylesheet" type="text/css" href="externals/geoext/resources/css/gxtheme-gray.css" />
+
+        <!-- GeoExplorer resources -->
+        <link rel="stylesheet" type="text/css" href="theme/geoexplorer.css" />
+        <!--[if IE]>
+        <link rel="stylesheet" type="text/css" href="theme/ie.css"/><![endif]-->
+
+        <script type="text/javascript" src="script/GeoExplorer.js"></script> 
+
+        <script>
+            Ext.BLANK_IMAGE_URL = "theme/img/blank.gif";
+            var app = new GeoExplorer.Full({
+                proxy: "/proxy/?url=",
+                ows: {
+                    "demo": "http://demo.opengeo.org/geoserver/ows"
+                },
+                map: {
+                    layers: [{
+                        name: "openstreetmap",
+                        ows: "demo",
+                        isBaseLayer: true  
+                    },{
+                        name: "nurc:Img_Sample",
+                        ows: "demo"
+                    }],
+                    center: [-96.7, 37.6],
+                    zoom: 4
+                }
+            });
+        </script>
+
+    </head>
+    <body>
+    </body>
+</html>


Property changes on: apps/opengeo/geoexplorer/trunk/src/html/index.html
___________________________________________________________________
Name: svn:keywords
   + Id Author Date Revision
Name: svn:mergeinfo
   + 
Name: svn:eol-style
   + native

Copied: apps/opengeo/geoexplorer/trunk/src/script/app/GeoExplorer (from rev 1164, apps/opengeo/geoexplorer/trunk/lib/GeoExplorer)


Property changes on: apps/opengeo/geoexplorer/trunk/src/script/app/GeoExplorer
___________________________________________________________________
Name: svn:mergeinfo
   + 

Modified: apps/opengeo/geoexplorer/trunk/src/script/app/GeoExplorer/Full.js
===================================================================
--- apps/opengeo/geoexplorer/trunk/lib/GeoExplorer/Full.js	2009-06-29 16:48:53 UTC (rev 1164)
+++ apps/opengeo/geoexplorer/trunk/src/script/app/GeoExplorer/Full.js	2009-06-29 22:12:56 UTC (rev 1165)
@@ -113,7 +113,7 @@
             var query = Ext.urlEncode({q: Ext.util.JSON.encode(config)}); 
 
             // TODO: configurablize!!!1!!!!!111!!!!!!
-            var pathname = document.location.pathname.replace(/\/[^\/]*$/, '/embed-debug.html'); 
+            var pathname = document.location.pathname.replace(/\/[^\/]*$/, '/embed.html'); 
             var url = 
                 document.location.protocol + "//" +
                 document.location.hostname +

Copied: apps/opengeo/geoexplorer/trunk/src/script/app/GeoExplorer.js (from rev 1164, apps/opengeo/geoexplorer/trunk/lib/GeoExplorer.js)
===================================================================
--- apps/opengeo/geoexplorer/trunk/src/script/app/GeoExplorer.js	                        (rev 0)
+++ apps/opengeo/geoexplorer/trunk/src/script/app/GeoExplorer.js	2009-06-29 22:12:56 UTC (rev 1165)
@@ -0,0 +1,1463 @@
+/**
+ * Copyright (c) 2009 The Open Planning Project
+ */
+ 
+/*
+ * @requires GeoExplorer/util.js
+ * @requires GeoExplorer/GroupContainer.js
+ * @requires GeoExplorer/MapToolSplitToggle.js
+ * @requires GeoExplorer/CapabilitiesGrid.js
+ * @requires GeoExplorer/NewSourceWindow.js
+ */
+
+/**
+ * api: (define)
+ * module = GeoExplorer
+ * extends = Ext.Observable
+ */
+
+/** api: constructor
+ *  .. class:: GeoExplorer(config)
+ *     Create a new GeoExplorer application.
+ *
+ *     Parameters:
+ *     config - {Object} Optional application configuration properties.
+ *
+ *     Valid config properties:
+ *     map - {Object} Map configuration object.
+ *     ows - {String} OWS URL
+ *     alignToGrid - {boolean} if true, align tile requests to the grid 
+ *         enforced by tile caches such as GeoWebCache or Tilecache
+ *
+ *     Valid map config properties:
+ *         layers - {Array} A list of layer configuration objects.
+ *         center - {Array} A two item array with center coordinates.
+ *         zoom - {Number} An initial zoom level.
+ *
+ *     Valid layer config properties:
+ *     name - {String} Required WMS layer name.
+ *     title - {String} Optional title to display for layer.
+ *
+ */
+var GeoExplorer = Ext.extend(Ext.util.Observable, {
+    
+    /** api: property[map]
+     * :class:`OpenLayers.Map` The application's map.
+     */
+    map: null,
+    
+    /** private: property[layers]
+     * A :class:`GeoExt.data.LayerStore` containing a record for each layer
+     * on the map.
+     */
+    layers: null,
+
+    /**
+     * private: property[mapPanel]
+     * the :class:`GeoExt.MapPanel` instance for the main viewport
+     */
+    mapPanel: null,
+
+    /**
+     * api: config[alignToGrid]
+     * A boolean indicating whether or not to restrict tile request to tiled
+     * mapping service recommendation.  
+     *
+     * True => align to grid 
+     * False => unrestrained tile requests
+     */
+    alignToGrid: false,
+
+    /**
+     * private: property[capGrid]
+     * :class:`Ext.Window` The window containing the CapabilitiesGrid panel to 
+     * use when the user is adding new layers to the map.
+     */
+    capGrid: null,
+
+    /**
+     * private: property[popupCache]
+     * :class:`Object` An object containing references to visible popups so that
+     * we can insert responses from multiple requests.
+     *
+     * ..seealso:: :method:`GeoExplorer.displayPopup()`
+     */
+    popupCache: null,
+    
+    /** api: property[layerSources]
+     * A :class:`Ext.data.Store` containing one 
+     * :class:`GeoExt.data.WMSCapabilitiesStore` for each WMS service in use by
+     * the application, along with service-specific metadata like the service 
+     * name.
+     */
+    layerSources: null,
+
+    constructor: function(config) {
+        this.popupCache = {};
+
+        var query = Ext.urlDecode(document.location.search.substr(1));
+        var queryConfig = Ext.util.JSON.decode(query.q);
+        
+        this.initialConfig = Ext.apply({}, queryConfig, config);
+        Ext.apply(this, this.initialConfig);
+        
+        // add any custom application events
+        this.addEvents(
+            /**
+             * Event: ready
+             * Fires when application is ready for user interaction.
+             */
+            "ready");
+        
+        // pass on any proxy config to OpenLayers
+        if(this.proxy) {
+            OpenLayers.ProxyHost = this.proxy;
+        }
+        
+        this.load();
+    },
+
+    /**
+     * private: method[load]
+     * Called at the end of construction.  This initiates the sequence that
+     * prepares the application for use, including tasks such as loading 
+     * capabilities from remote servers, populating the map, etc.
+     */
+    load: function() {
+        this.layerSources = new Ext.data.SimpleStore({
+            fields: ["identifier", "name", "store", "url"],
+            data: []
+        });
+        
+        var dispatchQueue = [
+            // create layout as soon as Ext says ready
+            function(done) {
+                Ext.onReady(function() {
+                    this.createLayout();
+                    done();
+                }, this);
+            }
+        ];
+        
+        for (var id in this.ows) {
+            // Load capabilities for each ows passed through the configuration.
+            dispatchQueue.push(
+                (function(id) {
+                    // Create a new scope for 'id'.
+                    return function(done){
+                        this.addSource(this.ows[id], id, done, done);
+                    }; 
+                })(id));
+        }
+        
+        GeoExplorer.util.dispatch(
+            dispatchQueue,
+            
+            // activate app when the above are both done
+            this.activate, 
+            this);
+    },
+    
+    /** private: method[addSource]
+     * Add a new WMS server to GeoExplorer. The id parameter is optional,
+     * and will be given a default if not specified; success and fail 
+     * are also optional, and scope only applies if success or fail
+     * is passed in.
+     */
+    addSource: function(url, id, success, fail, scope) {
+        scope = scope || this;
+        success = OpenLayers.Function.bind(success, scope);
+        fail = OpenLayers.Function.bind(fail, scope);
+        
+        id = id || OpenLayers.Util.createUniqueID("source");
+        var capsURL = this.createWMSCapabilitiesURL(url);
+                        var store = new GeoExt.data.WMSCapabilitiesStore();
+
+        OpenLayers.Request.GET({
+            proxy: this.proxy, 
+            url: capsURL,
+            success: function(request){
+                var store = new GeoExt.data.WMSCapabilitiesStore({
+                            fields:  [
+                                {name: "name", type: "string"},
+                                {name: "abstract", type: "string"},
+                                {name: "queryable", type: "boolean"},
+                                {name: "formats"},
+                                {name: "styles"},
+                                {name: "llbbox"},
+                                {name: "minScale"},
+                                {name: "maxScale"},
+                                {name: "prefix"},
+                                
+                                // Added for GeoExplorer.
+                                {name: "background", type: "boolean"},
+                                {name: "source_id", type: "string"}
+                            ]
+                        });
+                var xml = request.responseXML;
+                var data = (xml && xml.documentElement) ?
+                    xml : request.responseText;
+                
+                try {
+                    // Read the response. It's important to note that the
+                    // WMSCapabilitiesStore reads the data as well, though
+                    // we need to do it ourselves in order to maintain
+                    // low coupling.
+                    var format = new OpenLayers.Format.WMSCapabilities();
+                    var extractedData = format.read(data);
+                    
+                    store.loadData(data);
+                } catch(err) {
+                    OpenLayers.Console.error("Could not load source: " + url);
+                    fail();
+                    return;
+                }
+                
+                // MODERATELY LARGE DIRTY HACK!
+                // Tell each layer where it came from.
+                store.each(function(record) {
+                    record.set("source_id", id);
+                }, this);
+                
+                var record = new this.layerSources.recordType({
+                    url: url,
+                    store: store,
+                    identifier: id,
+                    name: extractedData.service.title || id
+                });
+                
+                this.layerSources.add(record);
+                success(record);
+            },
+            failure: function(){
+                OpenLayers.Console.error("Couldn't get capabilities document for ows '" + id + "'.");
+                fail();
+            },
+            scope: this
+        });
+    },
+    
+    /** private: method[createWMSCapabilitiesURL]
+     * Given the URL to an OWS service endpoint, generate a GET request URL for
+     * the service's WMS capabilities.
+     */
+    createWMSCapabilitiesURL: function(url) {
+        var args = {
+            SERVICE: "WMS",
+            REQUEST: "GetCapabilities"
+        };
+        var argIndex = url.indexOf("?");
+        if(argIndex > -1) {
+            var search = url.substring(url.indexOf("?")+1);
+            url = url.replace(search, Ext.urlEncode(Ext.apply(
+                Ext.urlDecode(search), args)));
+        } else {
+            url = url + "?" + Ext.urlEncode(args);
+        }
+
+        return url;
+    },
+    
+    /** private: method[createLayout]
+     * Create the various parts that compose the layout.
+     */
+    createLayout: function() {
+        
+        // create the map
+        // TODO: check this.initialConfig.map for any map options
+        this.map = new OpenLayers.Map({
+            allOverlays: true,
+            controls: [new OpenLayers.Control.PanPanel(),
+                       new OpenLayers.Control.ZoomPanel()]
+        });
+
+        //** Remove this code when OpenLayers #2069 is closed **
+        var onDoubleClick = function(ctrl, evt) { 
+ 	        OpenLayers.Event.stop(evt ? evt : window.event); 
+        };
+        var controls = this.map.controls[0].controls;
+        for(var i = 0; i < controls.length; i++){
+            OpenLayers.Event.observe(controls[i].panel_div, "dblclick",  
+ 	                             OpenLayers.Function.bind(onDoubleClick, this.map.controls[0], controls[i])); 
+        }        
+        //******************************************************
+
+        //TODO: make this more configurable
+        this.map.events.on({
+            "preaddlayer" : function(evt){
+                if(evt.layer.mergeNewParams){
+                    var maxExtent = evt.layer.maxExtent;
+                    evt.layer.mergeNewParams({
+                        transparent: true,
+                        format: "image/png",
+                        tiled: true,
+                        tilesorigin: [maxExtent.left, maxExtent.bottom]
+                    });
+                }
+            },
+            scope : this
+        });
+        
+
+        // place map in panel
+        var mapConfig = this.initialConfig.map || {};
+        this.mapPanel = new GeoExt.MapPanel({
+            layout: "anchor",
+            border: true,
+            region: "center",
+            map: this.map,
+            // TODO: update the OpenLayers.Map constructor to accept an initial center
+            center: mapConfig.center && new OpenLayers.LonLat(mapConfig.center[0], mapConfig.center[1]),
+            // TODO: update the OpenLayers.Map constructor to accept an initial zoom
+            zoom: mapConfig.zoom,
+            items: [
+                {
+                    xtype: "gx_zoomslider",
+                    vertical: true,
+                    height: 100,
+                    plugins: new GeoExt.ZoomSliderTip({
+                        template: "<div>Zoom Level: {zoom}</div>"
+                    })
+                },
+                this.createMapOverlay()
+            ]
+        });
+        
+        // create layer store
+        this.layers = this.mapPanel.layers;
+        this.registerBackgroundListeners();                       
+
+        var addLayerButton = new Ext.Button({
+            tooltip : "Add Layers",
+            disabled: true,
+            iconCls: "icon-addlayers",
+            handler : this.showCapabilitiesGrid,
+            scope: this
+        });
+        this.on("ready", function() {addLayerButton.enable();});
+
+        var addBaseLayerButton = new Ext.Button({
+            tooltip : "Add Base Layers",
+            disabled: true,
+            iconCls: "icon-addlayers",
+            handler: this.showBaseCapabilitiesGrid,
+            scope: this
+        });
+        this.on("ready", function() {addBaseLayerButton.enable();});
+
+
+        //allow user to select only one layer at a time
+        //by sharing selection model
+        var selectionModel = new Ext.tree.DefaultSelectionModel({
+            listeners: {
+                beforeselect: function() {
+                    removeLayerAction.enable();
+                }
+            }
+        });
+
+        var baseSelectionModel = new Ext.tree.DefaultSelectionModel({
+            listeners: {
+                beforeselect: function() {
+                    removeBaseLayerAction.enable();
+                }
+            }
+        });
+
+        var removeLayerAction = new Ext.Action({
+            text: "Remove Layer",
+            iconCls: "icon-removelayers",
+            disabled: true,
+            tooltip: "Remove Layer",
+            handler: function() {
+                var node = selectionModel.getSelectedNode();
+                if(node && node.layer) {
+                    var layer = node.layer;
+                    var store = node.layerStore;
+                    var record = store.getAt(store.findBy(function(record) {
+                        return record.get("layer") === layer;
+                    }));
+                    store.remove(record);
+                    removeLayerAction.disable();
+                }
+            }
+        });
+
+        var removeBaseLayerAction = new Ext.Action({
+            text: "Remove Base Layer",
+            iconCls: "icon-removelayers",
+            disabled: true,
+            tooltip: "Remove Base Layer",
+            handler: function() {
+                var node = baseSelectionModel.getSelectedNode();
+                if(node && node.layer) {
+                    var layer = node.layer;
+                    var store = node.layerStore;
+                    var record = store.getAt(store.findBy(function(record) {
+                        return record.get("layer") === layer;
+                    }));
+                    store.remove(record);
+                    removeBaseLayerAction.disable();
+                }
+            }
+        });
+
+        var layerTreeConfig = {
+            border:false,
+            rootVisible: false,
+            autoScroll: true,
+            split: true,
+            listeners: {
+                contextmenu: function(node, e) {
+                    node.select();
+                    var c = node.getOwnerTree().contextMenu;
+                    c.contextNode = node;
+                    c.showAt(e.getXY());
+                },
+                scope: this
+            },
+            contextMenu: new Ext.menu.Menu({
+                items: [
+                    {
+                        text: "Zoom to Layer Extent",
+                        iconCls: "icon-zoom-visible",
+                        handler: function(){
+                            var node = selectionModel.getSelectedNode();
+                            if(node && node.layer) {
+                                this.map.zoomToExtent(node.layer.restrictedExtent);
+                            }
+                        },
+                        scope: this
+                    },
+                    removeLayerAction
+                ]
+            })
+        };        
+
+        var overlayLayerTree = new Ext.tree.TreePanel(
+            Ext.apply(
+                {
+                    title: "Layers",
+                    tbar: [
+                        addLayerButton,
+                        Ext.apply(new Ext.Button(removeLayerAction), {text: ""})
+                    ],
+                    selModel: selectionModel,
+                    root: new GeoExplorer.GroupContainer({
+                        background: false,
+                        layerStore: this.layerStore
+                    }),
+                    ddGroup: "OverlayLayerDD",
+                    height: 'auto',
+                    region: 'center',
+                    enableDD: true
+                }, 
+                layerTreeConfig));
+        
+        var baseLayerTree = new Ext.tree.TreePanel(
+            Ext.apply(
+                {
+                    title: 'Base Layers',
+                    tbar: [
+                        addBaseLayerButton,
+                        Ext.apply(new Ext.Button(removeBaseLayerAction), {text: ""})
+                    ],
+                    root: new GeoExplorer.GroupContainer({
+                        background: true,
+                        layerStore: this.layerStore
+                    }), 
+                    selModel: baseSelectionModel,
+                    ddGroup: "BaseLayerDD",
+                    height: 160,
+                    region: 'south',
+                    contextMenu: new Ext.menu.Menu({
+                    items: [
+                        {
+                            text: "Zoom to Layer Extent",
+                            iconCls: "icon-zoom-visible",
+                            handler: function(){
+                                var node = selectionModel.getSelectedNode();
+                                if(node && node.layer) {
+                                    this.map.zoomToExtent(node.layer.restrictedExtent);
+                                }
+                            },
+                            scope: this
+                        },
+                        removeBaseLayerAction
+                    ]
+            })
+        }, 
+        layerTreeConfig));
+
+        var layersContainer = new Ext.Panel({
+            border: false,
+            region: 'center',
+            layout: 'border',
+            items: [overlayLayerTree, baseLayerTree]
+        });
+
+        var legendContainer = new GeoExt.LegendPanel({
+            title: "Legend",
+            border: false,
+            region: 'south',
+            height: 200,
+            collapsible: true,
+            split: true,
+            autoScroll: true,
+            ascending: false,
+            map: this.map,
+            childDefaults: {border: false, cls: 'legend-title'}
+        });
+
+        var westPanel = new Ext.Panel({
+            border: true,
+            layout: "border",
+            region: "west",
+            width: 250,
+            split: true,
+            collapsible: true,
+            collapseMode: "mini",
+            items: [
+                layersContainer, legendContainer
+            ]
+        });
+        
+        var toolbar = new Ext.Toolbar({
+            xtype: "toolbar",
+            region: "north",
+            disabled: true,
+            items: this.createTools()
+        });
+        this.on("ready", function() {
+            // enable only those items that were not specifically disabled
+            var disabled = toolbar.items.filterBy(function(item) {
+                return item.initialConfig && item.initialConfig.disabled;
+            });
+            toolbar.enable();
+            disabled.each(function(item) {
+                item.disable();
+            });
+        });
+        
+        var viewport = new Ext.Viewport({
+            layout: "fit",
+            hideBorders: true,
+            items: {
+                layout: "border",
+                deferredRender: false,
+                items: [
+                    toolbar,
+                    this.mapPanel,
+                    westPanel
+                ]
+            }
+        });    
+    },
+
+    registerBackgroundListeners: function() {
+        
+        var updateBackground = function(store, candidate) {
+
+            var vis = [], all = [];
+            store.each(function(record) {
+                if(record.get("background")) {
+                    all.push(record);
+                    if(record.get("layer").getVisibility()) {
+                        vis.push(record);
+                    }
+                }
+            });
+            
+            if(all.length) {
+                candidate = candidate || all[0];
+                if(vis.length === 0) {
+                    candidate.get("layer").setVisibility(true);
+                } else if(vis.length > 1) {
+                    Ext.each(vis, function(r) {
+                        if(r !== candidate) {
+                            window.setTimeout(function() {
+                                r.get("layer").setVisibility(false);
+                            }, 0);
+                            return false;
+                        }
+                    });
+                }
+            }
+        };
+
+        // make sure one base layer is always visible after add, remove or update
+        this.layers.on({
+            add: function(store, records, index) {
+                var candidate;
+                Ext.each(records, function(r) {
+                    if(r.get("background")) {
+                        candidate = r;
+                        return false;
+                    }
+                });
+                if(candidate) {
+                    updateBackground(store, candidate);
+                }
+            },
+            remove: function(store, record, index) {
+                if(record.get("background")) {
+                    updateBackground(store);
+                }
+            },
+            update: function(store, record, op) {
+                if(record.get("background")) {
+                    updateBackground(store, record);
+                }
+            }
+        });
+
+    },
+    
+    /** private: method[activate]
+     * Activate the application.  Call after application is configured.
+     */
+    activate: function() {
+        
+        // add any layers from config
+        this.addLayers();
+
+        // initialize tooltips
+        Ext.QuickTips.init();
+        
+        this.fireEvent("ready");
+
+    },
+    
+    /** private: method[addLayers]
+     * Construct the layer store to be used with the map (referenced as 
+     * :attr:`GeoExplorer.layers`).
+     */
+    addLayers: function() {
+        var mapConfig = this.initialConfig.map;
+
+        if(mapConfig && mapConfig.layers) {
+            var records = [];
+            
+            for(var i = 0; i < mapConfig.layers.length; ++i) {
+                var conf = mapConfig.layers[i];
+                var index = this.layerSources.find("identifier", conf.ows);
+                
+                if (index == -1) {
+                    continue;
+                }
+                
+                var storeRecord = this.layerSources.getAt(index);
+                var store = storeRecord.data.store;
+
+                var id = store.find("name", conf.name);
+                
+                var record;
+                var base;
+                if (id >= 0) {
+                    record = store.getAt(id).copy();
+
+                    layer = record.get("layer");
+                    
+                    // set layer max extent from capabilities
+                    // TODO: make this SRS independent
+                    layer.restrictedExtent = OpenLayers.Bounds.fromArray(record.get("llbbox"));
+                    
+                    if (this.alignToGrid) {
+                        layer.maxExtent = new OpenLayers.Bounds(-180, -90, 180, 90);
+                    } else {
+                        layer.maxExtent = layer.restrictedExtent;
+                    }
+
+                    layer = layer.clone();
+                    record.set("layer", null); //need to do this because record.set compares String(value) to determine equality (dumb)
+                    record.set("layer", layer);
+
+                    // set layer visibility from config
+                    layer.visibility = ("visibility" in conf) ? conf.visibility : true;
+                    
+                    // set layer title from config
+                    if (conf.title) {
+                        layer.name = conf.title;
+                    }
+
+                    record.set("background", ("background" in conf ? 
+                                              conf.background : false));
+                    
+                    // set any other layer configuration
+                    // ensures that background layers are on the bottom
+                    if(record.get("background")){
+                        records.unshift(record);
+                    } else {
+                        records.push(record);
+                    }
+                }
+                
+            }
+            
+            this.layers.add(records);
+
+            // set map center
+            if(this.mapPanel.center) {
+                // zoom does not have to be defined
+                this.map.setCenter(this.mapPanel.center, this.mapPanel.zoom);
+            } else if (this.mapPanel.extent) {
+                this.map.zoomToExtent(this.mapPanel.extent);
+            } else {
+                this.map.zoomToMaxExtent();
+            }
+            
+        }
+    },
+
+    /**
+     * private: method[initCapGrid]
+     * Constructs a window with a capabilities grid.
+     */
+    initCapGrid: function(){
+
+        // TODO: Might be nice to subclass some of these things into
+        // into their own classes.
+
+        var firstSource = this.layerSources.getAt(0);
+
+        var capGridConfig = {
+            store: firstSource.data.store,
+            mapPanel : this.mapPanel,
+            layout: 'fit',
+            region: 'center',
+            autoScroll: true,
+            alignToGrid: this.alignToGrid,
+            listeners: {
+                rowdblclick: function(panel, index, evt) {
+                    panel.addLayers();
+                }
+            }
+        };
+
+        var capGridPanel = new GeoExplorer.CapabilitiesGrid(capGridConfig);
+        var baseCapGridPanel = new GeoExplorer.CapabilitiesGrid(capGridConfig);
+
+        var sourceComboConfig = {
+            store: this.layerSources,
+            valueField: "identifier",
+            displayField: "name",
+            triggerAction: "all",
+            editable: false,
+            allowBlank: false,
+            forceSelection: true,
+            mode: "local",
+            value: firstSource.data.identifier
+        };
+
+        var sourceComboBox = new Ext.form.ComboBox(sourceComboConfig);
+        sourceComboBox.on("select", function(combo, record, index) {
+            capGridPanel.reconfigure(record.data.store, capGridPanel.getColumnModel());
+        }, this);
+
+        var baseSourceComboBox = new Ext.form.ComboBox(sourceComboConfig);
+        baseSourceComboBox.on("select", function(combo, record, index) {
+            capGridPanel.reconfigure(record.data.store, baseCapGridPanel.getColumnModel());
+        }, this);
+
+        var capGridToolbar = null;
+        var baseCapGridToolbar = null;
+
+        if (this.proxy || this.layerSources.getCount() > 1) {
+            capGridToolbar = [
+                new Ext.Toolbar.TextItem({
+                    text: "View available data from:"
+                }),
+                sourceComboBox
+            ];
+            baseCapGridToolbar = [
+                new Ext.Toolbar.TextItem({
+                    text: "View available data from:"
+                }),
+                baseSourceComboBox
+            ];
+        }
+
+        if (this.proxy) {
+            capGridToolbar.push(new Ext.Button({
+                text: "or add a new server.",
+                handler: function() {
+                    newSourceWindow.show();
+                }
+            }));
+            baseCapGridToolbar.push(new Ext.Button({
+                text: "or add a new server.",
+                handler: function() {
+                    newSourceWindow.show();
+                }
+            }));
+        }
+
+        var newSourceWindow = new GeoExplorer.NewSourceWindow();
+        
+        newSourceWindow.on("server-added", function(url) {
+            newSourceWindow.setLoading();
+            
+            var success = function(record) {
+                // The combo box will automatically update when a new item
+                // is added to the layerSources store. Now all we have to
+                // do is select it. Note: There's probably a better way to do this, 
+                // but there doesn't seem to be another way to get the select event
+                // to fire.
+                var index = this.layerSources.find("identifier", record.data.identifier);
+                sourceComboBox.fireEvent("select", sourceComboBox, record, index);
+                
+                // Close the new source window.
+                newSourceWindow.hide();
+            };
+            
+            var failure = function() {
+                newSourceWindow.setError("Error contacting server.\nPlease check the url and try again.");
+            };
+            
+            this.addSource(url, null, success, failure, this);
+        }, this);
+        
+        this.capGrid = new Ext.Window({
+            title: "Available Layers",
+            closeAction: 'hide',
+            layout: 'border',
+            height: 300,
+            width: 600,
+            modal: true,
+            items: [
+                capGridPanel
+            ],
+            tbar: capGridToolbar,
+            bbar: [
+                "->",
+                new Ext.Button({
+                    text: "Add Layers",
+                    iconCls: "icon-addlayers",
+                    handler: function(){
+                        capGridPanel.addLayers();
+                    },
+                    scope : this
+                }),
+                new Ext.Button({
+                    text: "Done",
+                    handler: function() {
+                        this.capGrid.hide();
+                    },
+                    scope: this
+                })
+            ],
+            listeners: {
+                hide: function(win){
+                    capGridPanel.getSelectionModel().clearSelections();
+                }
+            }
+        });
+
+        this.baseCapGrid = new Ext.Window({
+            title: "Available Base Layers",
+            closeAction: 'hide',
+            layout: 'border',
+            height: 300,
+            width: 600,
+            modal: true,
+            items: [
+                baseCapGridPanel
+            ],
+            tbar: baseCapGridToolbar,
+            bbar: [
+                "->",
+                new Ext.Button({
+                    text: "Add Base Layers",
+                    iconCls: "icon-addlayers",
+                    handler: function(){
+                        baseCapGridPanel.addLayers(true);
+                    },
+                    scope : this
+                }),
+                new Ext.Button({
+                    text: "Done",
+                    handler: function() {
+                        this.baseCapGrid.hide();
+                    },
+                    scope: this
+                })
+            ]
+        });
+ 
+    },
+
+    /** private: method[showCapabilitiesGrid]
+     * Shows the window with a capabilities grid.
+     */
+    showBaseCapabilitiesGrid: function() {
+        if(!this.capGrid) {
+            this.initCapGrid();
+        }
+        this.baseCapGrid.show();
+    },
+
+    /** private: method[showCapabilitiesGrid]
+     * Shows the window with a capabilities grid.
+     */
+    showCapabilitiesGrid: function() {
+        if(!this.capGrid) {
+            this.initCapGrid();
+        }
+        this.capGrid.show();
+    },
+
+    /** private: method[createMapOverlay]
+     * Builds the :class:`Ext.Panel` containing components to be overlaid on the
+     * map, setting up the special configuration for its layout and 
+     * map-friendliness.
+     */
+    createMapOverlay: function() {
+        var scaleLinePanel = new Ext.Panel({
+            cls: 'olControlScaleLine overlay-element overlay-scaleline',
+            border: false
+        });
+
+        scaleLinePanel.on('render', function(){
+            var scaleLine = new OpenLayers.Control.ScaleLine({
+                div: scaleLinePanel.body.dom
+            });
+
+            this.map.addControl(scaleLine);
+            scaleLine.activate();
+        }, this);
+
+        var zoomStore = new GeoExt.data.ScaleStore({
+            map: this.map
+        });
+
+        var zoomSelector = new Ext.form.ComboBox({
+            emptyText: 'Zoom level',
+            tpl: '<tpl for="."><div class="x-combo-list-item">1 : {[parseInt(values.scale)]}</div></tpl>',
+            editable: false,
+            triggerAction: 'all',
+            mode: 'local',
+            store: zoomStore,
+            width: 110
+        });
+
+        zoomSelector.on('click', function(evt){evt.stopEvent();});
+        zoomSelector.on('mousedown', function(evt){evt.stopEvent();});
+
+        zoomSelector.on('select', function(combo, record, index) {
+                this.map.zoomTo(record.data.level);
+            },
+            this);
+
+        var zoomSelectorWrapper = new Ext.Panel({
+            items: [zoomSelector],
+            cls: 'overlay-element overlay-scalechooser',
+            border: false });
+
+        this.map.events.register('zoomend', this, function() {
+            var scale = zoomStore.queryBy(function(record){
+                return this.map.getZoom() == record.data.level;
+            });
+
+            if (scale.length > 0) {
+                scale = scale.items[0];
+                zoomSelector.setValue("1 : " + parseInt(scale.data.scale, 10));
+            } else {
+                if (!zoomSelector.rendered) return;
+                zoomSelector.clearValue();
+            }
+        });
+
+        var mapOverlay = new Ext.Panel({
+            // title: "Overlay",
+            cls: 'map-overlay',
+            items: [
+                scaleLinePanel,
+                zoomSelectorWrapper
+            ]
+        });
+
+
+        mapOverlay.on("afterlayout", function(){
+            scaleLinePanel.body.dom.style.position = 'relative';
+            scaleLinePanel.body.dom.style.display = 'inline';
+
+            mapOverlay.getEl().on("click", function(x){x.stopEvent();});
+            mapOverlay.getEl().on("mousedown", function(x){x.stopEvent();});
+        }, this);
+
+        return mapOverlay;
+    },
+
+    /** private: method[createTools]
+     * Create the toolbar configuration for the main panel.  This method can be 
+     * overridden in derived explorer classes such as :class:`GeoExplorer.Full`
+     * or :class:`GeoExplorer.Embed` to provide specialized controls.
+     */
+    createTools: function() {
+
+        var toolGroup = "toolGroup";
+
+        // create a navigation control
+        var navAction = new GeoExt.Action({
+            tooltip: "Pan Map",
+            iconCls: "icon-pan",
+            enableToggle: true,
+            pressed: true,
+            allowDepress: false,
+            control: new OpenLayers.Control.Navigation(),
+            map: this.map,
+            toggleGroup: toolGroup
+        });
+
+        // create a navigation history control
+        var historyControl = new OpenLayers.Control.NavigationHistory();
+        this.map.addControl(historyControl);
+
+        // create actions for previous and next
+        var navPreviousAction = new GeoExt.Action({
+            tooltip: "Zoom to Previous Extent",
+            iconCls: "icon-zoom-previous",
+            disabled: true,
+            control: historyControl.previous
+        });
+        
+        var navNextAction = new GeoExt.Action({
+            tooltip: "Zoom to Next Extent",
+            iconCls: "icon-zoom-next",
+            disabled: true,
+            control: historyControl.next
+        });
+
+        var toolGroup = "toolGroup";
+        
+        // create a get feature info control
+        var info = {controls: []};
+        var infoButton = new Ext.Button({
+            tooltip: "Get Feature Info",
+            iconCls: "icon-getfeatureinfo",
+            toggleGroup: toolGroup,
+            enableToggle: true,
+            allowDepress: false,
+            toggleHandler: function(button, pressed) {
+                for (var i = 0, len = info.controls.length; i < len; i++){
+                    if(pressed) {
+                        info.controls[i].activate();
+                    } else {
+                        info.controls[i].deactivate();
+                    }
+                }
+            }
+        });
+
+        var updateInfo = function() {
+            var queryableLayers = this.mapPanel.layers.queryBy(function(x){
+                return x.get("queryable");
+            });
+
+            var map = this.mapPanel.map;
+            var control;
+            for (var i = 0, len = info.controls.length; i < len; i++){
+                control = info.controls[i];
+                control.deactivate();  // TODO: remove when http://trac.openlayers.org/ticket/2130 is closed
+                control.destroy();
+            }
+
+            info.controls = [];
+            queryableLayers.each(function(x){
+                var control = new OpenLayers.Control.WMSGetFeatureInfo({
+                    url: x.get("layer").url,
+                    queryVisible: true,
+                    layers: [x.get("layer")],
+                    eventListeners: {
+                        getfeatureinfo: function(evt) {
+                            this.displayPopup(evt, x.get("title") || x.get("name"));
+                        },
+                        scope: this
+                    }
+                });
+                map.addControl(control);
+                info.controls.push(control);
+                if(infoButton.pressed) {
+                    control.activate();
+                }
+            }, this);
+        };
+
+        this.mapPanel.layers.on("update", updateInfo, this);
+        this.mapPanel.layers.on("add", updateInfo, this);
+        this.mapPanel.layers.on("remove", updateInfo, this);
+
+        // create length measure control
+        var measureLength = this.createMeasureTool(
+            OpenLayers.Handler.Path, 'Length');
+        this.map.addControl(measureLength);
+        
+        // create area measure control
+        var measureArea = this.createMeasureTool(
+            OpenLayers.Handler.Polygon, 'Area');
+        this.map.addControl(measureArea);
+
+        var tools = [
+            navAction,
+            infoButton,
+            new GeoExplorer.MapToolSplitToggle({
+                tooltip: "Measure",
+                iconCls: "icon-measure-length",
+                defaultTool: measureLength,
+                allowDepress: false,
+                tools: [
+                    {text: 'Length', tool: measureLength, iconCls: 'icon-measure-length'}, 
+                    {text: 'Area', tool: measureArea, iconCls: 'icon-measure-area'}
+                ],
+                enableToggle: true,
+                toggleGroup: toolGroup 
+            }),
+            "-",
+            new Ext.Button({
+                handler: function(){
+                    this.map.zoomIn();
+                },
+                tooltip: "Zoom In",
+                iconCls: "icon-zoom-in",
+                scope: this
+            }),
+            new Ext.Button({
+                tooltip: "Zoom Out",
+                handler: function(){
+                    this.map.zoomOut();
+                },
+                iconCls: "icon-zoom-out",
+                scope: this
+            }),
+            navPreviousAction,
+            navNextAction,
+            new Ext.Button({
+                tooltip: "Zoom to Visible Extent",
+                iconCls: "icon-zoom-visible",
+                handler: function() {
+                    var extent, layer;
+                    for(var i=0, len=this.map.layers.length; i<len; ++i) {
+                        layer = this.map.layers[i];
+                        if(layer.getVisibility()) {
+                            if(extent) {
+                                extent.extend(layer.maxExtent);
+                            } else {
+                                extent = layer.maxExtent.clone();
+                            }
+                        }
+                    }
+                    if(extent) {
+                        this.map.zoomToExtent(extent);
+                    }
+                },
+                scope: this
+            })
+        ];
+
+        return tools;
+    },
+
+    /** private: method[createMeasureTool]
+     * :param: handlerType: the :class:`OpenLayers.Handler` for the measurement
+     *     operation
+     * :param: title: the string label to display alongside results
+     *
+     * Convenience method for creating a :class:`OpenLayers.Control.Measure` 
+     * control
+     */
+    createMeasureTool: function(handlerType, title) {
+        
+        var styleMap = new OpenLayers.StyleMap({
+            "default": new OpenLayers.Style(null, {
+                rules: [new OpenLayers.Rule({
+                    symbolizer: {
+                        "Point": {
+                            pointRadius: 4,
+                            graphicName: "square",
+                            fillColor: "white",
+                            fillOpacity: 1,
+                            strokeWidth: 1,
+                            strokeOpacity: 1,
+                            strokeColor: "#333333"
+                        },
+                        "Line": {
+                            strokeWidth: 3,
+                            strokeOpacity: 1,
+                            strokeColor: "#666666",
+                            strokeDashstyle: "dash"
+                        },
+                        "Polygon": {
+                            strokeWidth: 2,
+                            strokeOpacity: 1,
+                            strokeColor: "#666666",
+                            fillColor: "white",
+                            fillOpacity: 0.3
+                        }
+                    }
+                })]
+            })
+        });
+
+        var cleanup = function() {
+            if (measureToolTip) {
+                measureToolTip.destroy();
+            }   
+        };
+
+        var makeString = function(metricData) {
+            var metric = metricData.measure;
+            var metricUnit = metricData.units;
+            
+            measureControl.displaySystem = "english";
+            
+            var englishData = metricData.geometry.CLASS_NAME.indexOf("LineString") > -1 ?
+            measureControl.getBestLength(metricData.geometry) :
+            measureControl.getBestArea(metricData.geometry);
+
+            var english = englishData[0];
+            var englishUnit = englishData[1];
+            
+            measureControl.displaySystem = "metric";
+            var dim = metricData.order == 2 ? 
+            '<sup>2</sup>' :
+            '';
+            
+            return metric.toFixed(2) + " " + metricUnit + dim + "<br>" + 
+                english.toFixed(2) + " " + englishUnit + dim;
+        };
+        
+        var measureToolTip; 
+        var measureControl = new OpenLayers.Control.Measure(handlerType, {
+            persist: true,
+            handlerOptions: {layerOptions: {styleMap: styleMap}},
+            eventListeners: {
+                measurepartial: function(event) {
+                    cleanup();
+                    measureToolTip = new Ext.ToolTip({
+                        html: makeString(event),
+                        title: title,
+                        autoHide: false,
+                        closable: true,
+                        draggable: false,
+                        mouseOffset: [0, 0],
+                        showDelay: 1,
+                        listeners: {hide: cleanup}
+                    });
+                    if(event.measure > 0) {
+                        var px = measureControl.handler.lastUp;
+                        var p0 = this.mapPanel.getPosition();
+                        measureToolTip.targetXY = [p0[0] + px.x, p0[1] + px.y];
+                        measureToolTip.show();
+                    }
+                },
+                measure: function(event) {
+                    cleanup();                    
+                    measureToolTip = new Ext.ToolTip({
+                        target: Ext.getBody(),
+                        html: makeString(event),
+                        title: title,
+                        autoHide: false,
+                        closable: true,
+                        draggable: false,
+                        mouseOffset: [0, 0],
+                        showDelay: 1,
+                        listeners: {
+                            hide: function() {
+                                measureControl.cancel();
+                                cleanup();
+                            }
+                        }
+                    });
+                },
+                deactivate: cleanup,
+                scope: this
+            }
+        });
+
+        return measureControl;
+    },
+
+    /** private: method[displayPopup]
+     * :param: evt: the event object from a 
+     *     :class:`OpenLayers.Control.GetFeatureInfo` control
+     * :param: title: a String to use for the title of the results section 
+     *     reporting the info to the user
+     */
+    displayPopup: function(evt, title) {
+        var popup;
+        var popupKey = evt.xy.x + "." + evt.xy.y;
+
+        if (!(popupKey in this.popupCache)) {
+            var lonlat = this.map.getLonLatFromPixel(evt.xy);
+            popup = new GeoExt.Popup({
+                title: "Feature Info",
+                lonlat: lonlat,
+                map: this.mapPanel,
+                width: 250,
+                height: 300,
+                autoScroll: true,
+                listeners: {
+                    close: (function(key) {
+                        return function(panel){
+                            delete this.popupCache[key];
+                        };
+                    })(popupKey),
+                    scope: this
+                }
+            });
+            popup.show();
+            this.popupCache[popupKey] = popup;
+        } else {
+            popup = this.popupCache[popupKey];
+        }
+
+        var html = evt.text;
+        if (!(html === '' || html.match(/<body>\s*<\/body>/))) {
+            popup.add({
+                title: title,
+                html: html,
+                autoScroll: true,
+                collapsible: true
+            });
+        }
+
+        popup.doLayout();
+    },
+
+
+    /**
+     * private: method[bookmark]
+     * :return: the URL :class:`String` that was displayed to the user
+     *
+     * Creates a window that shows the user a URL that can be used to
+     * reload the map in its current configuration.
+     */ 
+    bookmark: function(){
+        var config = this.extractConfiguration();
+
+        var query = Ext.urlEncode({q: Ext.util.JSON.encode(config)});
+
+        var url = 
+            document.location.protocol + "//" +
+            document.location.hostname +
+            document.location.pathname + "?" + query;
+
+        var win = new Ext.Window({
+            title: "Bookmark URL",
+            layout: 'form',
+            items: [{
+                xtype: 'textfield',
+                fieldLabel: 'Permalink',
+                readOnly: true,
+                value: url
+            }],
+            width: 300
+        });
+
+        win.show();
+
+        return url;
+    },
+    
+    /**
+     * private: method[extractConfiguration]
+     * :return: an :class:`Object` representing the app's current configuration.
+     */ 
+    extractConfiguration: function() {
+        var config = {
+            ows: {}
+        };
+
+        // Map configuration
+
+        var center = this.map.getCenter();
+        
+        config.map = {
+            center: [center.lon, center.lat],
+            zoom: this.map.zoom
+        };
+
+        var sourcesUsed = {};
+
+        //Layers configuration
+        config.map.layers = [];
+        
+        this.layers.each(function(layerRecord){
+            var layer = layerRecord.get('layer');
+            if (layer.displayInLayerSwitcher) {
+                
+                // Get the source of this layer.
+                var index = this.layerSources.find("identifier", layerRecord.get("source_id"));
+                var source = this.layerSources.getAt(index);
+                
+                if (source === null) {
+                    OpenLayers.Console.error("Could not find source for layer '" + layerRecord.get("name") + "'");
+                    
+                    // Return; error gracefully. (This is debatable.)
+                    return;
+                }
+
+                sourcesUsed[source.get("identifier")] = source.get("url");
+                
+                var c = {
+                    name: layerRecord.get("name"),
+                    visibility: layer.getVisibility(),
+                    background: layerRecord.get('background'),
+                    ows: source.get("identifier")
+                };
+
+                config.map.layers.push(c);
+            }
+        }, this);
+        
+        // Source configuration
+        for (identifier in sourcesUsed) {
+            config.ows[identifier] = sourcesUsed[identifier];
+        }
+        
+        return config;
+    },
+
+    /** private: method[displayAppInfo]
+     * Display an informational dialog about the application.
+     */
+    displayAppInfo: function() {
+        var appInfo = new Ext.Panel({
+            title: "GeoExplorer",
+            html: "<iframe style=\"border: none; height: 100%; width: 100%\" src=\"about.html\"><a target=\"_blank\" href=\"about.html\">About GeoExplorer</a> </iframe>"
+        });
+
+        var about = Ext.applyIf(this.about, {
+            title: '', 
+            "abstract": '', 
+            keywords: '',
+            contact: ''
+        });
+
+        var mapInfo = new Ext.Panel({
+            title: "Map Info",
+            html: '<div class="gx-info-panel">' 
+            + '<h2> Title </h2> <p>' + about.title 
+            + '</p> <h2> Abstract </h2> <p>' + about['abstract'] 
+            + '</p> <h2> Keywords </h2> <p>' + about.keywords 
+            + '</p> <h2> Contact </h2> <p>' + about.contact +' </p> </div>',
+            height: 'auto',
+            width: 'auto'
+        });
+
+        var tabs = new Ext.TabPanel({
+            activeTab: 0,
+            width: 300,
+            height: 350,
+            items:[mapInfo, appInfo]
+        });
+
+        var win = new Ext.Window({
+            title: "About this Map",
+            modal: true,
+            items: [tabs]
+        });
+        win.show();
+    }
+});
+


Property changes on: apps/opengeo/geoexplorer/trunk/src/script/app/GeoExplorer.js
___________________________________________________________________
Name: svn:mergeinfo
   + 

Copied: apps/opengeo/geoexplorer/trunk/src/script/app/loader.js (from rev 1164, apps/opengeo/geoexplorer/trunk/script/GeoExplorer-debug.js)
===================================================================
--- apps/opengeo/geoexplorer/trunk/src/script/app/loader.js	                        (rev 0)
+++ apps/opengeo/geoexplorer/trunk/src/script/app/loader.js	2009-06-29 22:12:56 UTC (rev 1165)
@@ -0,0 +1,41 @@
+(function() {
+
+    // Since the applications are located one directory down from
+    // the base, all these includes must be prefixed by a ../
+    var jsfiles = new Array(
+        "../../src/script/app/GeoExplorer.js",
+        "../../src/script/app/GeoExplorer/util.js",
+        "../../src/script/app/GeoExplorer/MapToolToggle.js",
+        "../../src/script/app/GeoExplorer/MapToolSplitToggle.js",
+        "../../src/script/app/GeoExplorer/MapToolMenu.js",
+        "../../src/script/app/GeoExplorer/Wizard.js",
+        "../../src/script/app/GeoExplorer/LayerMenuItem.js",
+        "../../src/script/app/GeoExplorer/CapabilitiesGrid.js",
+        "../../src/script/app/GeoExplorer/GroupContainer.js",
+        "../../src/script/app/GeoExplorer/Full.js",
+        "../../src/script/app/GeoExplorer/Embed.js",
+        "../../src/script/app/GeoExplorer/NewSourceWindow.js"
+    );
+
+    var appendable = !(/MSIE/.test(navigator.userAgent) ||
+                       /Safari/.test(navigator.userAgent));
+    var pieces = new Array(jsfiles.length);
+
+    var element = document.getElementsByTagName("head").length ?
+                    document.getElementsByTagName("head")[0] :
+                    document.body;
+    var script;
+
+    for(var i=0; i<jsfiles.length; i++) {
+        if(!appendable) {
+            pieces[i] = "<script src='" + jsfiles[i] + "'></script>"; 
+        } else {
+            script = document.createElement("script");
+            script.src = jsfiles[i];
+            element.appendChild(script);
+        }
+    }
+    if(!appendable) {
+        document.write(pieces.join(""));
+    }
+})();


Property changes on: apps/opengeo/geoexplorer/trunk/src/script/app/loader.js
___________________________________________________________________
Name: svn:mergeinfo
   + 

Copied: apps/opengeo/geoexplorer/trunk/src/script/ux/RowExpander.js (from rev 1164, apps/opengeo/geoexplorer/trunk/lib/Ext/grid/RowExpander.js)
===================================================================
--- apps/opengeo/geoexplorer/trunk/src/script/ux/RowExpander.js	                        (rev 0)
+++ apps/opengeo/geoexplorer/trunk/src/script/ux/RowExpander.js	2009-06-29 22:12:56 UTC (rev 1165)
@@ -0,0 +1,136 @@
+/*
+ * Ext JS Library 2.2.1
+ * Copyright(c) 2006-2009, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://extjs.com/license
+ */
+
+Ext.grid.RowExpander = function(config){
+    Ext.apply(this, config);
+
+    this.addEvents({
+        beforeexpand : true,
+        expand: true,
+        beforecollapse: true,
+        collapse: true
+    });
+
+    Ext.grid.RowExpander.superclass.constructor.call(this);
+
+    if(this.tpl){
+        if(typeof this.tpl == 'string'){
+            this.tpl = new Ext.Template(this.tpl);
+        }
+        this.tpl.compile();
+    }
+
+    this.state = {};
+    this.bodyContent = {};
+};
+
+Ext.extend(Ext.grid.RowExpander, Ext.util.Observable, {
+    header: "",
+    width: 20,
+    sortable: false,
+    fixed:true,
+    menuDisabled:true,
+    dataIndex: '',
+    id: 'expander',
+    lazyRender : true,
+    enableCaching: true,
+
+    getRowClass : function(record, rowIndex, p, ds){
+        p.cols = p.cols-1;
+        var content = this.bodyContent[record.id];
+        if(!content && !this.lazyRender){
+            content = this.getBodyContent(record, rowIndex);
+        }
+        if(content){
+            p.body = content;
+        }
+        return this.state[record.id] ? 'x-grid3-row-expanded' : 'x-grid3-row-collapsed';
+    },
+
+    init : function(grid){
+        this.grid = grid;
+
+        var view = grid.getView();
+        view.getRowClass = this.getRowClass.createDelegate(this);
+
+        view.enableRowBody = true;
+
+        grid.on('render', function(){
+            view.mainBody.on('mousedown', this.onMouseDown, this);
+        }, this);
+    },
+
+    getBodyContent : function(record, index){
+        if(!this.enableCaching){
+            return this.tpl.apply(record.data);
+        }
+        var content = this.bodyContent[record.id];
+        if(!content){
+            content = this.tpl.apply(record.data);
+            this.bodyContent[record.id] = content;
+        }
+        return content;
+    },
+
+    onMouseDown : function(e, t){
+        if(t.className == 'x-grid3-row-expander'){
+            e.stopEvent();
+            var row = e.getTarget('.x-grid3-row');
+            this.toggleRow(row);
+        }
+    },
+
+    renderer : function(v, p, record){
+        p.cellAttr = 'rowspan="2"';
+        return '<div class="x-grid3-row-expander">&#160;</div>';
+    },
+
+    beforeExpand : function(record, body, rowIndex){
+        if(this.fireEvent('beforeexpand', this, record, body, rowIndex) !== false){
+            if(this.tpl && this.lazyRender){
+                body.innerHTML = this.getBodyContent(record, rowIndex);
+            }
+            return true;
+        }else{
+            return false;
+        }
+    },
+
+    toggleRow : function(row){
+        if(typeof row == 'number'){
+            row = this.grid.view.getRow(row);
+        }
+        this[Ext.fly(row).hasClass('x-grid3-row-collapsed') ? 'expandRow' : 'collapseRow'](row);
+    },
+
+    expandRow : function(row){
+        if(typeof row == 'number'){
+            row = this.grid.view.getRow(row);
+        }
+        var record = this.grid.store.getAt(row.rowIndex);
+        var body = Ext.DomQuery.selectNode('tr:nth(2) div.x-grid3-row-body', row);
+        if(this.beforeExpand(record, body, row.rowIndex)){
+            this.state[record.id] = true;
+            Ext.fly(row).replaceClass('x-grid3-row-collapsed', 'x-grid3-row-expanded');
+            this.fireEvent('expand', this, record, body, row.rowIndex);
+        }
+    },
+
+    collapseRow : function(row){
+        if(typeof row == 'number'){
+            row = this.grid.view.getRow(row);
+        }
+        var record = this.grid.store.getAt(row.rowIndex);
+        var body = Ext.fly(row).child('tr:nth(1) div.x-grid3-row-body', true);
+        if(this.fireEvent('beforecollapse', this, record, body, row.rowIndex) !== false){
+            this.state[record.id] = false;
+            Ext.fly(row).replaceClass('x-grid3-row-expanded', 'x-grid3-row-collapsed');
+            this.fireEvent('collapse', this, record, body, row.rowIndex);
+        }
+    }
+});


Property changes on: apps/opengeo/geoexplorer/trunk/src/script/ux/RowExpander.js
___________________________________________________________________
Name: svn:mergeinfo
   + 

Copied: apps/opengeo/geoexplorer/trunk/src/theme/app (from rev 1164, apps/opengeo/geoexplorer/trunk/theme)


Property changes on: apps/opengeo/geoexplorer/trunk/src/theme/app
___________________________________________________________________
Name: svn:mergeinfo
   + 

Modified: apps/opengeo/geoexplorer/trunk/src/theme/app/geoexplorer.css
===================================================================
--- apps/opengeo/geoexplorer/trunk/theme/geoexplorer.css	2009-06-29 16:48:53 UTC (rev 1164)
+++ apps/opengeo/geoexplorer/trunk/src/theme/app/geoexplorer.css	2009-06-29 22:12:56 UTC (rev 1165)
@@ -117,7 +117,7 @@
 /* Pan- and Zoom- Panel Styles*/
 
 .olControlPanPanel div {
-    background-image:url(../externals/ext/resources/images/gray/panel/tool-sprites.gif);
+    background-image:url(http://extjs.cachefly.net/ext-2.2.1/resources/images/gray/panel/tool-sprites.gif);
     height:15px;
     width:15px;
     /* workaround for button height in IE */
@@ -149,7 +149,7 @@
 }
 
 .olControlZoomPanel div {
-    background-image:url(../externals/ext/resources/images/gray/panel/tool-sprites.gif);
+    background-image:url(http://extjs.cachefly.net/ext-2.2.1/resources/images/gray/panel/tool-sprites.gif);
     height:15px;
     width:15px;
     /* workaround for button height in IE */



More information about the Commits mailing list