Merge DEV_TREE into HEAD. May as well get this ball rolling.
authorchriskl <chriskl>
Mon, 2 May 2005 15:47:23 +0000 (15:47 +0000)
committerchriskl <chriskl>
Mon, 2 May 2005 15:47:23 +0000 (15:47 +0000)
67 files changed:
CREDITS
HISTORY
TRANSLATORS
aggregates.php
all_db.php
bottombar.php [deleted file]
browser.php
classes/ArrayRecordSet.php [new file with mode: 0644]
classes/Misc.php
classes/Reports.php
classes/database/Postgres.php
classes/database/Postgres71.php
classes/database/Postgres72.php
classes/database/Postgres73.php
classes/database/Postgres80.php
constraints.php
conversions.php
database.php
dataexport.php
dbexport.php
display.php
domains.php
functions.php
groups.php
images/themes/default/I.png [new file with mode: 0644]
images/themes/default/L.png [new file with mode: 0644]
images/themes/default/Lminus.png [new file with mode: 0644]
images/themes/default/Lplus.png [new file with mode: 0644]
images/themes/default/T.png [new file with mode: 0644]
images/themes/default/Tminus.png [new file with mode: 0644]
images/themes/default/Tplus.png [new file with mode: 0644]
images/themes/default/blank.png [new file with mode: 0644]
images/themes/default/file.png [new file with mode: 0644]
images/themes/default/folder.png [new file with mode: 0644]
images/themes/default/folderOpen.png [new file with mode: 0644]
images/themes/default/loading.gif [new file with mode: 0644]
images/themes/default/root.png [new file with mode: 0644]
images/themes/default/title.png
index.php
indexes.php
intro.php
lang/english.php
lang/translations.php [new file with mode: 0644]
libraries/decorator.inc.php [new file with mode: 0644]
libraries/errorhandler.inc.php
libraries/lib.inc.php
login.php
opclasses.php
operators.php
redirect.php
reports.php
sequences.php
servers.php [new file with mode: 0644]
sqledit.php
tables.php
tablespaces.php
tblproperties.php
themes/default/global.css
topbar.php [deleted file]
triggers.php
types.php
users.php
viewproperties.php
views.php
xloadtree/xloadtree2.js [new file with mode: 0644]
xloadtree/xmlextras.js [new file with mode: 0644]
xloadtree/xtree2.js [new file with mode: 0644]

diff --git a/CREDITS b/CREDITS
index 6d4f23d22fb518ee17e582d0f2aadab4013b2f34..45caa9e0c41fb470eac715fbb50bf93797f24a2d 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -57,4 +57,4 @@ Contributors
 Third Party Libraries
 
 - Highlight.php (Jacob D. Cohen of rafb.net)
-
+- XLoadTree2 (Erik Arvidsson & Emil A Eklund of webfx.eae.net)
diff --git a/HISTORY b/HISTORY
index 9c4f1d4270667948216bb1b03a9f466d5b30760e..bc6c3c8ce45f34d69e493c43e2aa3e99634a8e98 100644 (file)
--- a/HISTORY
+++ b/HISTORY
@@ -15,6 +15,11 @@ Features
 * primary key and unique key at table creation (Andreas Huber)
 * Add row|statement level options to create trigger for >= 7.4 (Robert Treat)
 * Allow altering name (for >= 7.4) and owner (for >= 8.0) of a database (Bryan Encina)
+* Allow login to several servers simultaneously
+* Rearrange frame layout to suit multi-server support
+* New browser tree with dynamically loading branches
+  (Using XLoadTree from http://webfx.eae.net/)
+* Allow language change on the fly
   
 Bugs
 * Tree Icons are displayed middle instead of top
index ba0aad6fc95a10926b85dce814d40b0e18eece8a..f4bffe6b273590f16b4b9dcd967c82f8eeea3999 100644 (file)
@@ -54,11 +54,11 @@ find the rest of these steps too difficult.
    language's characters as well as the characters of the language in your
    database.
 
-8. To add your language to phpPgAdmin's login screen, edit the
-   libraries/lib.inc.php file and add your language to the $appLangFiles array.
+8. To add your language to phpPgAdmin, edit the lang/translations.php file
+   and add your language to the $appLangFiles array.
    You must include the HTML encoded version of your language's name.  You can
-   get this from the recoded version of your translated strings file.  Also,
-   edit the login.php and add your language to the list of languages for
+   get this from the recoded version of your translated strings file.
+   Also, add your language to the $availableLanguages array for
    browser auto detection.
 
 9. Send your contribution to us.  We need the lib.inc.php entry as well as the
index e7ab25a15ef8186b0798674d64c4ace4cfacda71..81a6d21e59899ef4f1d0b5d6d41e8355faf9f728 100644 (file)
@@ -3,7 +3,7 @@
        /**
         * Manage aggregates in a database
         *
-        * $Id: aggregates.php,v 1.10 2004/09/20 14:41:38 jollytoad Exp $
+        * $Id: aggregates.php,v 1.11 2005/05/02 15:47:23 chriskl Exp $
         */
 
        // Include application functions
                $misc->printTable($aggregates, $columns, $actions, $lang['strnoaggregates']);
        }
 
+       /**
+        * Generate XML for the browser tree.
+        */
+       function doTree() {
+               global $misc, $data;
+               
+               $aggregates = &$data->getAggregates();
+               
+               $proto = concat(field('proname'), ' (', field('proargtypes'), ')');
+               
+               $attrs = array(
+                       'text'   => $proto,
+                       'icon'   => 'functions',
+                       'toolTip'=> field('aggcomment'),
+               );
+               
+               $misc->printTreeXML($aggregates, $attrs);
+               exit;
+       }
+       
+       if ($action == 'tree') doTree();
+       
        $misc->printHeader($lang['straggregates']);
        $misc->printBody();
 
index fe7632402785b87489aa13a582daecd2c5a13fb9..28eb728db122b4d5103246a47cb331858066d1f6 100644 (file)
@@ -3,7 +3,7 @@
        /**
         * Manage databases within a server
         *
-        * $Id: all_db.php,v 1.37 2005/04/30 18:01:58 soranzo Exp $
+        * $Id: all_db.php,v 1.38 2005/05/02 15:47:23 chriskl Exp $
         */
 
        // Include application functions
@@ -82,8 +82,8 @@
                        echo "<p>", sprintf($lang['strconfdropdatabase'], $misc->printVal($_REQUEST['dropdatabase'])), "</p>\n";        
                        echo "<form action=\"$PHP_SELF\" method=\"post\">\n";
                        echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n";
-                       echo "<input type=\"hidden\" name=\"dropdatabase\" value=\"", 
-                               htmlspecialchars($_REQUEST['dropdatabase']), "\" />\n";
+                       echo "<input type=\"hidden\" name=\"server\" value=\"", htmlspecialchars($_REQUEST['server']), "\" />\n";
+                       echo "<input type=\"hidden\" name=\"dropdatabase\" value=\"", htmlspecialchars($_REQUEST['dropdatabase']), "\" />\n";
                        echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n";
                        echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n";
                        echo "</form>\n";
                
                echo "</table>\n";
                echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create\" />\n";
+               echo $misc->form;
                echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n";
                echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n";
                echo "</form>\n";
                echo "<br/><input type=\"radio\" name=\"output\" value=\"download\" />{$lang['strdownload']}</p>\n";
 
                echo "<p><input type=\"hidden\" name=\"action\" value=\"export\" />\n";
-               echo "<p><input type=\"hidden\" name=\"mode\" value=\"cluster\" />\n";          
+               echo "<p><input type=\"hidden\" name=\"subject\" value=\"server\" />\n";                
                echo $misc->form;
                echo "<input type=\"submit\" value=\"{$lang['strexport']}\" /></p>\n";
                echo "</form>\n";
                $actions = array(
                        'properties' => array(
                                'title' => $lang['strproperties'],
-                               'url'   => 'redirect.php?section=database&amp;',
+                               'url'   => "redirect.php?subject=database&amp;{$misc->href}&amp;",
                                'vars'  => array('database' => 'datname'),
                        ),
                        'drop' => array(
                                'title' => $lang['strdrop'],
-                               'url'   => "{$PHP_SELF}?action=confirm_drop&amp;subject=database&amp;",
+                               'url'   => "{$PHP_SELF}?action=confirm_drop&amp;subject=database&amp;{$misc->href}&amp;",
                                'vars'  => array('dropdatabase' => 'datname'),
                        ),
                        'privileges' => array(
                                'title' => $lang['strprivileges'],
-                               'url'   => "privileges.php?subject=database&amp;",
+                               'url'   => "privileges.php?subject=database&amp;{$misc->href}&amp;",
                                'vars'  => array('database' => 'datname'),
                        )
                );
                
                $misc->printTable($databases, $columns, $actions, $lang['strnodatabases']);
 
-               echo "<p><a class=\"navlink\" href=\"$PHP_SELF?action=create\">{$lang['strcreatedatabase']}</a></p>\n";
+               echo "<p><a class=\"navlink\" href=\"$PHP_SELF?action=create&amp;{$misc->href}\">{$lang['strcreatedatabase']}</a></p>\n";
 
        }
+       
+       function doTree() {
+               global $misc, $data, $lang;
+               
+               $databases = &$data->getDatabases();
+               
+               $reqvars = $misc->getRequestVars('database');
+               
+               $attrs = array(
+                       'text'   => field('datname'),
+                       'icon'   => 'database',
+                       'toolTip'=> field('datcomment'),
+                       'action' => url('redirect.php',
+                                                       $reqvars,
+                                                       array('database' => field('datname'))
+                                               ),
+                       'branch' => url('database.php',
+                                                       $reqvars,
+                                                       array(
+                                                               'action' => 'tree',
+                                                               'database' => field('datname')
+                                                       )
+                                               ),
+               );
+               
+               $misc->printTreeXML($databases, $attrs);
+               exit;
+       }
 
+       if ($action == 'tree') doTree();
+       
        $misc->printHeader($lang['strdatabases']);
        $misc->printBody();
 
diff --git a/bottombar.php b/bottombar.php
deleted file mode 100644 (file)
index 10191c7..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-
-       /**
-        * Bottom bar
-        *
-        * $Id: bottombar.php,v 1.3 2003/12/17 09:11:32 chriskl Exp $
-        */     
-
-       // Include application functions (no db conn)
-       $_no_db_connection = true;
-        include_once('./libraries/lib.inc.php');
-
-       $misc->printHeader();
-       $misc->printBody('bottombar');
-       $misc->printFooter();
-?>
index 6b7d1d8d1c5fc5e30fe6bfd3c2c8860353bfa785..df42006f44d9eede5d421f7fc8586884a1278f6b 100644 (file)
         * if you click on a database it shows a list of database objects in that
         * database.
         *
-        * $Id: browser.php,v 1.45 2005/03/11 04:32:10 chriskl Exp $
+        * $Id: browser.php,v 1.46 2005/05/02 15:47:23 chriskl Exp $
         */
 
        // Include application functions
+       $_no_db_connection = true;
        include_once('./libraries/lib.inc.php');
        
-       // Include tree classe
-       include_once('./classes/HTML_TreeMenu/TreeMenu.php');
-
        // Output header
-       $misc->printHeader('', "<script src=\"classes/HTML_TreeMenu/TreeMenu.js\" type=\"text/javascript\"></script>\n<script src=\"links.js\" type=\"text/javascript\"></script>");
+       $misc->printHeader('', "<script src=\"xloadtree/xmlextras.js\" type=\"text/javascript\"></script>\n<script src=\"xloadtree/xtree2.js\" type=\"text/javascript\"></script>\n<script src=\"xloadtree/xloadtree2.js\" type=\"text/javascript\"></script>");
        $misc->printBody('browser');
        echo "<div dir=\"ltr\">\n";
-       
-       // Construct expanding tree
-       $menu  = new HTML_TreeMenu(null, array('usePersistence' => false));
-       $root = new HTML_TreeNode(array(
-                                               'text' => $misc->printVal(($conf['servers'][$_SESSION['webdbServerID']]['desc'])), 
-                                               'link' => addslashes('redirect.php?section=server&amp;' . SID), 
-                                               'icon' => 'folder.gif', 
-                                               'expandedIcon' => 'folder-expanded.gif',
-                                               'expanded' => true,
-                                               'linkTarget' => 'detail'));
-
-       // Add root node to menu
-       $menu->addItem($root);
-
-       /**
-        * Helper function for adding nodes
-        * @param $schemanode Node onto which to add
-        */
-       function addNodes(&$schemanode, $querystr) {
-               global $data, $misc, $lang, $conf;
-               
-               // Tables
-               $table_node = &new HTML_TreeNode(array(
-                                               'text' => $lang['strtables'], 
-                                               'link' => addslashes(htmlspecialchars("tables.php?{$querystr}")), 
-                                               'icon' => "../../../images/themes/{$conf['theme']}/tables.png", 
-                                               'expandedIcon' => "../../../images/themes/{$conf['theme']}/tables.png",
-                                               'expanded' => false,
-                                               'linkTarget' => 'detail'));
-               // Add table folder to schema
-               $schemanode->addItem($table_node);
-
-               $tables = &$data->getTables();
-               while (!$tables->EOF) {
-                       $return_url = urlencode("tblproperties.php?table=" . urlencode($tables->f['relname']) . "&{$querystr}");
-                       $item_node = &new HTML_TreeNode(array(
-                                                       'text' => $misc->printVal($tables->f['relname']), 
-                                                       'link' => addslashes(htmlspecialchars("redirect.php?section=table&{$querystr}&table=" . urlencode($tables->f['relname']))), 
-                                                       'icon' => "../../../images/themes/{$conf['theme']}/tables.png", 
-                                                       'expandedIcon' => "../../../images/themes/{$conf['theme']}/tables.png",
-                                                       'expanded' => false,
-                                                       'linkTarget' => 'detail',
-                                                       'iconLink' => addslashes(htmlspecialchars('display.php?table=' . urlencode($tables->f['relname']) . '&subject=table&' . $querystr . "&return_url={$return_url}&return_desc=" . urlencode($lang['strback'])))
-                                                       ));
-                       // Add table folder to schema
-                       $table_node->addItem($item_node);
-
-                       $tables->moveNext();
-               }
-
-               // Views
-               $view_node = &new HTML_TreeNode(array(
-                                               'text' => $lang['strviews'], 
-                                               'link' => addslashes(htmlspecialchars("views.php?{$querystr}")), 
-                                               'icon' => "../../../images/themes/{$conf['theme']}/views.png", 
-                                               'expandedIcon' => "../../../images/themes/{$conf['theme']}/views.png",
-                                               'expanded' => false,
-                                               'linkTarget' => 'detail'));
-               // Add view folder to schema
-               $schemanode->addItem($view_node);
-
-               $views = &$data->getViews();
-               while (!$views->EOF) {
-                       $return_url = urlencode("viewproperties.php?view=" . urlencode($views->f['relname']) . "&{$querystr}");
-                       $item_node = &new HTML_TreeNode(array(
-                                                       'text' => $misc->printVal($views->f['relname']), 
-                                                       'link' => addslashes(htmlspecialchars("redirect.php?section=view&{$querystr}&view=" .
-                                                               urlencode($views->f['relname']))), 
-                                                       'icon' => "../../../images/themes/{$conf['theme']}/views.png", 
-                                                       'expandedIcon' => "../../../images/themes/{$conf['theme']}/views.png",
-                                                       'expanded' => false,
-                                                       'linkTarget' => 'detail',
-                                                       // XXX: FIX BROWSE
-                                                       'iconLink' => addslashes(htmlspecialchars('display.php?view='.urlencode($views->f['relname']).'&subject=view&'.$querystr.
-                                                               "&return_url={$return_url}&return_desc=" . urlencode($lang['strback'])))
-                                                       ));
-                       // Add view folder to schema
-                       $view_node->addItem($item_node);
-
-                       $views->moveNext();
-               }
-
-               // Sequences
-               $seq_node = &new HTML_TreeNode(array(
-                                               'text' => $lang['strsequences'], 
-                                               'link' => addslashes(htmlspecialchars("sequences.php?{$querystr}")), 
-                                               'icon' => "../../../images/themes/{$conf['theme']}/sequences.png", 
-                                               'expandedIcon' => "../../../images/themes/{$conf['theme']}/sequences.png",
-                                               'expanded' => false,
-                                               'linkTarget' => 'detail'));
-               // Add folder to schema
-               $schemanode->addItem($seq_node);
-
-               // Functions
-               $func_node = &new HTML_TreeNode(array(
-                                               'text' => $lang['strfunctions'], 
-                                               'link' => addslashes(htmlspecialchars("functions.php?{$querystr}")), 
-                                               'icon' => "../../../images/themes/{$conf['theme']}/functions.png", 
-                                               'expandedIcon' => "../../../images/themes/{$conf['theme']}/functions.png",
-                                               'expanded' => false,
-                                               'linkTarget' => 'detail'));
-               // Add folder to schema
-               $schemanode->addItem($func_node);
-
-               // Domains
-               if ($data->hasDomains()) {
-                       $dom_node = &new HTML_TreeNode(array(
-                                                       'text' => $lang['strdomains'], 
-                                                       'link' => addslashes(htmlspecialchars("domains.php?{$querystr}")), 
-                                                       'icon' => "../../../images/themes/{$conf['theme']}/domains.png", 
-                                                       'expandedIcon' => "../../../images/themes/{$conf['theme']}/domains.png",
-                                                       'expanded' => false,
-                                                       'linkTarget' => 'detail'));
-
-                       // Add folder to schema
-                       $schemanode->addItem($dom_node);
-               }
-
-               // Advanced
-               if ($conf['show_advanced']) {
-                       $adv_node = &new HTML_TreeNode(array(
-                                                       'text' => $lang['stradvanced'], 
-#                                                      'link' => ($data->hasSchemas()) ? addslashes(htmlspecialchars("schema.php?{$querystr}&" . SID)) : null, 
-                                                       'icon' => 'folder.gif', 
-                                                       'expandedIcon' => 'folder-expanded.gif',
-                                                       'linkTarget' => 'detail'));
-                       // Add folder to schema
-                       $schemanode->addItem($adv_node);                        
-
-                       // Aggregates
-                       $agg_node = &new HTML_TreeNode(array(
-                                                       'text' => $lang['straggregates'], 
-                                                       'link' => addslashes(htmlspecialchars("aggregates.php?{$querystr}")), 
-                                                       'icon' => "../../../images/themes/{$conf['theme']}/types.png", 
-                                                       'expandedIcon' => "../../../images/themes/{$conf['theme']}/types.png",
-                                                       'expanded' => false,
-                                                       'linkTarget' => 'detail'));
-                       // Add folder to schema
-                       $adv_node->addItem($agg_node);
-
-                       // Types
-                       $type_node = &new HTML_TreeNode(array(
-                                                       'text' => $lang['strtypes'], 
-                                                       'link' => addslashes(htmlspecialchars("types.php?{$querystr}")), 
-                                                       'icon' => "../../../images/themes/{$conf['theme']}/types.png", 
-                                                       'expandedIcon' => "../../../images/themes/{$conf['theme']}/types.png",
-                                                       'expanded' => false,
-                                                       'linkTarget' => 'detail'));
-                       // Add folder to schema
-                       $adv_node->addItem($type_node);
-
-                       // Operators
-                       $opr_node = &new HTML_TreeNode(array(
-                                                       'text' => $lang['stroperators'], 
-                                                       'link' => addslashes(htmlspecialchars("operators.php?{$querystr}")), 
-                                                       'icon' => "../../../images/themes/{$conf['theme']}/operators.png", 
-                                                       'expandedIcon' => "../../../images/themes/{$conf['theme']}/operators.png",
-                                                       'expanded' => false,
-                                                       'linkTarget' => 'detail'));
-                       // Add folder to schema
-                       $adv_node->addItem($opr_node);
-
-                       // Operator Classes
-                       $opc_node = &new HTML_TreeNode(array(
-                                                       'text' => $lang['stropclasses'], 
-                                                       'link' => addslashes(htmlspecialchars("opclasses.php?{$querystr}")), 
-                                                       'icon' => "../../../images/themes/{$conf['theme']}/operators.png", 
-                                                       'expandedIcon' => "../../../images/themes/{$conf['theme']}/operators.png",
-                                                       'expanded' => false,
-                                                       'linkTarget' => 'detail'));
-                       // Add folder to schema
-                       $adv_node->addItem($opc_node);
-
-                       // Conversions
-                       if ($data->hasConversions()) {
-                               $con_node = &new HTML_TreeNode(array(
-                                                               'text' => $lang['strconversions'], 
-                                                               'link' => addslashes(htmlspecialchars("conversions.php?{$querystr}")), 
-                                                               'icon' => "../../../images/themes/{$conf['theme']}/types.png", 
-                                                               'expandedIcon' => "../../../images/themes/{$conf['theme']}/types.png",
-                                                               'expanded' => false,
-                                                               'linkTarget' => 'detail'));
-
-                               // Add folder to schema
-                               $adv_node->addItem($con_node);
-                       }
-               }
-       }       
-
-       $databases = &$data->getDatabases(isset($_REQUEST['database']) ? $_REQUEST['database'] : NULL);
-       while (!$databases->EOF) {
-               // If database is selected, show folder, otherwise show document
-               if (isset($_REQUEST['database']) && $_REQUEST['database'] == $databases->f['datname']) {
-                       // Very ugly hack to work around the fact that the PEAR HTML_Tree can't have links with embedded
-                       // apostrophes create the get string we need to append
-                       $querystr = 'database=' . urlencode($databases->f['datname']) . '&' . SID;
-                       $db_node = &new HTML_TreeNode(array(
-                                                               'text' => $misc->printVal($databases->f['datname']), 
-                                                               'link' => addslashes(htmlspecialchars("redirect.php?section=database&{$querystr}")),
-                                                               'icon' => "../../../images/themes/{$conf['theme']}/database.png", 
-                                                               'expandedIcon' => "../../../images/themes/{$conf['theme']}/database.png",
-                                                               'expanded' => true,
-                                                               'linkTarget' => 'detail'));
-               
-                       // If database supports schemas, add the extra level of hierarchy
-                       if ($data->hasSchemas()) {
-                               $schemas = &$data->getSchemas();
-                               while (!$schemas->EOF) {
-                                       $data->setSchema($schemas->f['nspname']);
-                                       // Construct database & schema query string
-                                       $querystr = 'database=' . urlencode($databases->f['datname']). '&schema=' .
-                                                       urlencode($schemas->f['nspname']) . '&' . SID;
-                                       $schemanode = &new HTML_TreeNode(array(
-                                                                       'text' => $misc->printVal($schemas->f['nspname']), 
-                                                                       'link' => addslashes(htmlspecialchars("redirect.php?section=schema&{$querystr}")), 
-                                                                       'icon' => 'folder.gif', 
-                                                                       'expandedIcon' => 'folder-expanded.gif',
-                                                                       // Auto-expand your personal schema, if it exists.  Also expand schema if there is
-                                                                       // only one schema in the database.
-                                                                       'expanded' => ($schemas->f['nspname'] == $_SESSION['webdbUsername']
-                                                                                                                       || $schemas->recordCount() == 1),
-                                                                       'linkTarget' => 'detail'));
-
-                                       addNodes($schemanode, $querystr);
-
-                                       // Add schema to database
-                                       $db_node->addItem($schemanode);
-
-                                       $schemas->moveNext();
-                               }
-                       }
-                       // Database doesn't support schemas
-                       else {
-                               // Construct database query string
-                               $querystr = 'database=' . urlencode($databases->f['datname']) . '&' . SID;
-
-                               addNodes($db_node, $querystr);
-                       }
-                       
-                       // Reset database query string
-                       $querystr = 'database=' . urlencode($databases->f['datname']) . '&' . SID;
-
-                       // Languages
-                       if ($conf['show_advanced']) {
-                               $lang_node = &new HTML_TreeNode(array(
-                                                               'text' => $lang['strlanguages'], 
-                                                               'link' => addslashes(htmlspecialchars("languages.php?{$querystr}")), 
-                                                               'icon' => "../../../images/themes/{$conf['theme']}/types.png", 
-                                                               'expandedIcon' => "../../../images/themes/{$conf['theme']}/types.png",
-                                                               'expanded' => false,
-                                                               'linkTarget' => 'detail'));
-                               // Add folder to database
-                               $db_node->addItem($lang_node);
-                       
-                               // Casts
-                               if ($data->hasCasts()) {                
-                                       $cast_node = &new HTML_TreeNode(array(
-                                                                       'text' => $lang['strcasts'], 
-                                                                       'link' => addslashes(htmlspecialchars("casts.php?{$querystr}")), 
-                                                                       'icon' => "../../../images/themes/{$conf['theme']}/types.png", 
-                                                                       'expandedIcon' => "../../../images/themes/{$conf['theme']}/types.png",
-                                                                       'expanded' => false,
-                                                                       'linkTarget' => 'detail'));
-
-                                       // Add folder to database
-                                       $db_node->addItem($cast_node);
-                               }
-                       }
-               
-                       // Add node to menu
-                       $root->addItem($db_node);
+?>
 
-               } else {
-                       // Very ugly hack to work around the fact that the PEAR HTML_Tree can't have links with embedded
-                       // apostrophes create the get string we need to append
-                       $jsLink = '?database=' . addslashes(htmlspecialchars(urlencode($databases->f['datname']) . '&' . SID));
-                       $jsLink = "javascript:updateLinks(' + \"'{$jsLink}'\" + ')";
-                       $db_node = &new HTML_TreeNode(array(
-                                                                       'text' => $misc->printVal($databases->f['datname']), 
-                                                                       'link' => $jsLink,
-                                                                       'icon' => "../../../images/themes/{$conf['theme']}/database.png", 
-                                                                       'expandedIcon' => "../../../images/themes/{$conf['theme']}/database.png",
-                                                                       'expanded' => false,
-                                                                       'linkTarget' => '_self'));
-               
-                       // Add node to menu
-                       $root->addItem($db_node);
-               }
-               
-               $databases->moveNext();
-       }               
-       // Create the presentation class
-       $treeMenu = &new HTML_TreeMenu_DHTML($menu, array('images' => 'classes/HTML_TreeMenu/images', 'defaultClass' => 'treeMenuDefault'));
-       
-       // Actually display the menu
-       $treeMenu->printMenu();
+       <div class="logo"><a href="intro.php" target="detail"><img src="<?php echo $misc->icon('title') ?>" width="200" height="50" alt="<?php echo htmlspecialchars($appName) ?>" title="<?php echo htmlspecialchars($appName) ?>" /></a></div>
+
+<style type="text/css">
+.webfx-tree-children {
+       background-image:       url("<?php echo $misc->icon('I') ?>");
+}
+</style>
+<script type="text/javascript">
+
+webFXTreeConfig.rootIcon               = "<?php echo $misc->icon('root') ?>";
+webFXTreeConfig.openRootIcon   = "<?php echo $misc->icon('root') ?>";
+webFXTreeConfig.folderIcon             = "<?php echo $misc->icon('folder') ?>";
+webFXTreeConfig.openFolderIcon = "<?php echo $misc->icon('folderOpen') ?>";
+webFXTreeConfig.fileIcon               = "<?php echo $misc->icon('file') ?>";
+webFXTreeConfig.iIcon                  = "<?php echo $misc->icon('I') ?>";
+webFXTreeConfig.lIcon                  = "<?php echo $misc->icon('L') ?>";
+webFXTreeConfig.lMinusIcon             = "<?php echo $misc->icon('Lminus') ?>";
+webFXTreeConfig.lPlusIcon              = "<?php echo $misc->icon('Lplus') ?>";
+webFXTreeConfig.tIcon                  = "<?php echo $misc->icon('T') ?>";
+webFXTreeConfig.tMinusIcon             = "<?php echo $misc->icon('Tminus') ?>";
+webFXTreeConfig.tPlusIcon              = "<?php echo $misc->icon('Tplus') ?>";
+webFXTreeConfig.blankIcon              = "<?php echo $misc->icon('blank') ?>";
+webFXTreeConfig.loadingIcon            = "<?php echo $misc->icon('loading') ?>";
+webFXTreeConfig.loadingText            = "<?php echo $lang['strloading'] ?>";
+webFXTreeConfig.errorIcon              = "<?php echo $misc->icon('error') ?>";
+webFXTreeConfig.errorLoadingText = "<?php echo $lang['strerrorloading'] ?>";
+webFXTreeConfig.reloadText             = "<?php echo $lang['strclicktoreload'] ?>";
+
+// Set default target frame:
+WebFXTreeAbstractNode.prototype.target = 'detail';
+
+// Disable double click:
+WebFXTreeAbstractNode.prototype._onDblClick = function(){}
+
+// Show tree XML on double click - for debugging purposes only
+// TODO: REMOVE THIS BEFORE RELEASE
+WebFXTreeAbstractNode.prototype._onDblClick = function(e){
+       var el = e.target || e.srcElement;
+
+       if (this.src != null)
+               window.open(this.src, this.target || "_self");
+       return false;
+};
+
+var tree = new WebFXLoadTree("<?php echo $lang['strservers']; ?>", "servers.php?action=tree", "servers.php");
+
+tree.write();
+tree.setExpanded(true);
+
+</script>
 
+<?php
    // Output footer
    echo "</div>\n";
    $misc->printFooter();
diff --git a/classes/ArrayRecordSet.php b/classes/ArrayRecordSet.php
new file mode 100644 (file)
index 0000000..f05e0db
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+
+/**
+ * Really simple RecordSet to allow printTable of arrays.
+ *
+ * $Id: ArrayRecordSet.php,v 1.2 2005/05/02 15:47:25 chriskl Exp $
+ */
+class ArrayRecordSet {
+
+       var $_array;
+       var $_count;
+       var $EOF = false;
+       var $f;
+       
+       function ArrayRecordSet($data) {
+               $this->_array = $data;
+               $this->_count = count($this->_array);
+               $this->f = reset($this->_array);
+               if ($this->f === false) $this->EOF = true;
+       }
+       
+       function recordCount() {
+               return $this->_count;
+       }
+       
+       function moveNext() {
+               $this->f = next($this->_array);
+               if ($this->f === false) $this->EOF = true;
+       }
+}
+
+?>
index 5c604992af2e4a757300484eaa17d155f76dec94..1cd892f76023a4ec7b0a7d6a6f0c565462ded079 100644 (file)
@@ -2,7 +2,7 @@
        /**
         * Class to hold various commonly used functions
         *
-        * $Id: Misc.php,v 1.99 2005/04/11 15:15:44 chriskl Exp $
+        * $Id: Misc.php,v 1.100 2005/05/02 15:47:25 chriskl Exp $
         */
         
        class Misc {
                 * @return True, dumps are set up, false otherwise
                 */
                function isDumpEnabled($all = false) {
-                       global $conf;
-                       
-                       if ($all)
-                               return ($conf['servers'][$_SESSION['webdbServerID']]['pg_dumpall_path'] !== null 
-                                                               && $conf['servers'][$_SESSION['webdbServerID']]['pg_dumpall_path'] != '');
-                       else 
-                               return ($conf['servers'][$_SESSION['webdbServerID']]['pg_dump_path'] !== null 
-                                                               && $conf['servers'][$_SESSION['webdbServerID']]['pg_dump_path'] != '');
+                       $info = $this->getServerInfo();
+                       return !empty($info[$all ? 'pg_dumpall_path' : 'pg_dump_path']);
                }
 
                /**
-                * Checks whether a login is allowed
-                * @return True if login is allowed to be used
+                * Sets the href tracking variable
                 */
-               function checkExtraSecurity() {
-                       global $conf;
-
-                       // Disallowed logins if extra_login_security is enabled.  These must be lowercase.
-                       $bad_usernames = array('pgsql', 'postgres', 'root', 'administrator');
-                       
-                       // If extra security is off, return true
-                       if (!$conf['extra_login_security']) return true;
-                       elseif ($_SESSION['webdbPassword'] == '') return false;
-                       else {
-                               $username = strtolower($_SESSION['webdbUsername']);
-                               return !in_array($username, $bad_usernames);
-                       }
+               function setHREF() {
+                       $this->href = $this->getHREF();
                }
-
+               
                /**
-                * Sets the href tracking variable
+                * Get a href query string, excluding objects below the given object type (inclusive)
                 */
-               function setHREF() {
-                       $this->href = '';
-                       if (isset($_REQUEST['database'])) {
-                               $this->href .= 'database=' . urlencode($_REQUEST['database']);
-                               if (isset($_REQUEST['schema']))
-                                       $this->href .= '&amp;schema=' . urlencode($_REQUEST['schema']);
+               function getHREF($exclude_from = null) {
+                       $href = '';
+                       if (isset($_REQUEST['server']) && $exclude_from != 'server') {
+                               $href .= 'server=' . urlencode($_REQUEST['server']);
+                               if (isset($_REQUEST['database']) && $exclude_from != 'database') {
+                                       $href .= '&amp;database=' . urlencode($_REQUEST['database']);
+                                       if (isset($_REQUEST['schema']) && $exclude_from != 'schema') {
+                                               $href .= '&amp;schema=' . urlencode($_REQUEST['schema']);
+                                       }
+                               }
                        }
+                       return $href;
                }
 
                /**
                 */
                function setForm() {
                        $this->form = '';
-                       if (isset($_REQUEST['database'])) {
-                               $this->form .= "<input type=\"hidden\" name=\"database\" value=\"" . htmlspecialchars($_REQUEST['database']) . "\" />\n";
-                               if (isset($_REQUEST['schema']))
-                                       $this->form .= "<input type=\"hidden\" name=\"schema\" value=\"" . htmlspecialchars($_REQUEST['schema']) . "\" />\n";
+                       if (isset($_REQUEST['server'])) {
+                               $this->form .= "<input type=\"hidden\" name=\"server\" value=\"" . htmlspecialchars($_REQUEST['server']) . "\" />\n";
+                               if (isset($_REQUEST['database'])) {
+                                       $this->form .= "<input type=\"hidden\" name=\"database\" value=\"" . htmlspecialchars($_REQUEST['database']) . "\" />\n";
+                                       if (isset($_REQUEST['schema'])) {
+                                               $this->form .= "<input type=\"hidden\" name=\"schema\" value=\"" . htmlspecialchars($_REQUEST['schema']) . "\" />\n";
+                                       }
+                               }
                        }
                }
 
                /**
                 * Creates a database accessor
                 */
-               function &getDatabaseAccessor($database) {
-                       global $conf;
+               function &getDatabaseAccessor($database, $server_id = null) {
+                       global $lang, $conf, $misc;
+                       
+                       $server_info = $this->getServerInfo($server_id);
 
+                       // Perform extra security checks if this config option is set
+                       if ($conf['extra_login_security']) {
+                               // Disallowed logins if extra_login_security is enabled.
+                               // These must be lowercase.
+                               $bad_usernames = array('pgsql', 'postgres', 'root', 'administrator');
+                               
+                               $username = strtolower($server_info['username']);
+                               
+                               if ($server_info['password'] == '' || in_array($username, $bad_usernames)) {
+                                       unset($_SESSION['webdbLogin'][$_REQUEST['server']]);
+                                       $msg = $lang['strlogindisallowed'];
+                                       include('./login.php');
+                                       exit;
+                               }
+                       }
+                       
                        // Create the connection object and make the connection
                        $_connection = new Connection(
-                               $conf['servers'][$_SESSION['webdbServerID']]['host'],
-                               $conf['servers'][$_SESSION['webdbServerID']]['port'],
-                               $_SESSION['webdbUsername'],
-                               $_SESSION['webdbPassword'],
+                               $server_info['host'],
+                               $server_info['port'],
+                               $server_info['username'],
+                               $server_info['password'],
                                $database
                        );
 
-                       // Get the name of the database driver we need to use.  The description
-                       // of the server is returned and placed into the conf array.
-                       $_type = $_connection->getDriver($desc);
-                       // XXX: NEED TO CHECK RETURN STATUS HERE
-
+                       // Get the name of the database driver we need to use.
+                       // The description of the server is returned in $platform.
+                       $_type = $_connection->getDriver($platform);
+                       if ($_type === null) {
+                               printf($lang['strpostgresqlversionnotsupported'], $postgresqlMinVer);
+                               exit;
+                       }
+                       $this->setServerInfo('platform', $platform, $server_id);
+                       
                        // Create a database wrapper class for easy manipulation of the
                        // connection.
                        include_once('./classes/database/' . $_type . '.php');
-                       $data = &new $_type($_connection->conn);
+                       $data =& new $_type($_connection->conn);
+                       $data->platform = $_connection->platform;
 
                        return $data;
                }
                                $active = ($tab_id == $activetab) ? ' active' : '';
                                
                                if (!isset($tab['hide']) || $tab['hide'] !== true) {
-                                       $tablink = "<a href=\"" . $this->printVal($tab['url'], 'nbsp') . "\">{$tab['title']}</a>";
+                                       $tablink = "<a" . $this->printActionUrl($tab, $_REQUEST, 'href') . ">{$tab['title']}</a>";
                                        
                                        echo "<td width=\"{$width}\" class=\"tab{$active}\">";
                                        
                function getNavTabs($section) {
                        global $data, $lang, $conf;
                        
-                       $databasevar = isset($_REQUEST['database']) ? 'database=' . urlencode($_REQUEST['database']) : '';
-                       $schemavar = isset($_REQUEST['schema']) ? '&schema=' . urlencode($_REQUEST['schema']) : '';
+#                      $servervar = isset($_REQUEST['server']) ? 'server=' . urlencode($_REQUEST['server']) : '';
+#                      $databasevar = isset($_REQUEST['database']) ? '&database=' . urlencode($_REQUEST['database']) : '';
+#                      $schemavar = isset($_REQUEST['schema']) ? '&schema=' . urlencode($_REQUEST['schema']) : '';
                        $hide_advanced = ($conf['show_advanced'] === false);
                        
                        switch ($section) {
+                               case 'root':
+                                       return array (
+                                               'intro' => array (
+                                                       'title' => $lang['strintroduction'],
+                                                       'url'   => "intro.php",
+                                               ),
+                                               'servers' => array (
+                                                       'title' => $lang['strservers'],
+                                                       'url'   => "servers.php",
+                                               ),
+                                       );
+
                                case 'server':
-                                       $hide_users = !$data->isSuperUser($_SESSION['webdbUsername']);
+#                                      $vars = $servervar . $databasevar . '&subject=server';
+                                       $server_info = $this->getServerInfo();
+                                       $hide_users = !$data->isSuperUser($server_info['username']);
+                                       #$hide_users = false;
                                        return array (
                                                'databases' => array (
                                                        'title' => $lang['strdatabases'],
-                                                       'url'   => "all_db.php",
+                                                       'url'   => 'all_db.php',
+                                                       'urlvars' => array('subject' => 'server'),
                                                        'help'  => 'pg.database',
                                                ),
                                                'users' => array (
                                                        'title' => $lang['strusers'],
-                                                       'url'   => "users.php",
+                                                       'url'   => 'users.php',
+                                                       'urlvars' => array('subject' => 'server'),
                                                        'hide'  => $hide_users,
                                                        'help'  => 'pg.user',
                                                ),
                                                'groups' => array (
                                                        'title' => $lang['strgroups'],
-                                                       'url'   => "groups.php",
+                                                       'url'   => 'groups.php',
+                                                       'urlvars' => array('subject' => 'server'),
                                                        'hide'  => $hide_users,
                                                        'help'  => 'pg.group',
                                                ),
+                                               'account' => array (
+                                                       'title' => $lang['straccount'],
+                                                       'url'   => 'users.php',
+                                                       'urlvars' => array('subject' => 'server', 'action' => 'action'),
+                                                       'hide'  => !$hide_users,
+                                                       'help'  => 'pg.user',
+                                               ),
                                                'tablespaces' => array (
                                                        'title' => $lang['strtablespaces'],
-                                                       'url'   => "tablespaces.php",
+                                                       'url'   => 'tablespaces.php',
+                                                       'urlvars' => array('subject' => 'server'),
                                                        'hide'  => (!$data->hasTablespaces()),
                                                        'help'  => 'pg.tablespace',
                                                ),
                                                'export' => array (
                                                        'title' => $lang['strexport'],
-                                                       'url'   => "all_db.php?action=export",
+                                                       'url'   => 'all_db.php',
+                                                       'urlvars' => array('subject' => 'server', 'action' => 'export'),
                                                        'hide'  => (!$this->isDumpEnabled()),
                                                ),
+                                               'reports' => array (
+                                                       'title' => $lang['strreports'],
+                                                       'url'   => 'reports.php',
+                                                       'urlvars' => array('subject' => 'server'),
+                                               ),
                                        );
 
                                case 'database':
-                                       $vars = $databasevar . '&subject=database';
+#                                      $vars = $servervar . $databasevar . '&subject=database';
                                        return array (
                                                'schemas' => array (
                                                        'title' => $lang['strschemas'],
-                                                       'url'   => "database.php?{$vars}",
+                                                       'url'   => 'database.php',
+                                                       'urlvars' => array('subject' => 'database'),
                                                        'hide'  => (!$data->hasSchemas()),
                                                        'help'  => 'pg.schema',
                                                ),
                                                'sql' => array (
                                                        'title' => $lang['strsql'],
-                                                       'url'   => "database.php?{$vars}&action=sql",
+                                                       'url'   => 'database.php',
+                                                       'urlvars' => array('subject' => 'database', 'action' => 'sql'),
                                                        'help'  => 'pg.sql',
                                                ),
                                                'find' => array (
                                                        'title' => $lang['strfind'],
-                                                       'url'   => "database.php?{$vars}&action=find",
+                                                       'url'   => 'database.php',
+                                                       'urlvars' => array('subject' => 'database', 'action' => 'find'),
                                                ),
                                                'variables' => array (
                                                        'title' => $lang['strvariables'],
-                                                       'url'   => "database.php?{$vars}&action=variables",
+                                                       'url'   => 'database.php',
+                                                       'urlvars' => array('subject' => 'database', 'action' => 'variables'),
                                                        'hide'  => (!$data->hasVariables()),
                                                        'help'  => 'pg.variable',
                                                ),
                                                'processes' => array (
                                                        'title' => $lang['strprocesses'],
-                                                       'url'   => "database.php?{$vars}&action=processes",
+                                                       'url'   => 'database.php',
+                                                       'urlvars' => array('subject' => 'database', 'action' => 'processes'),
                                                        'hide'  => (!$data->hasProcesses()),
                                                        'help'  => 'pg.process',
                                                ),
                                                'admin' => array (
                                                        'title' => $lang['stradmin'],
-                                                       'url'   => "database.php?{$vars}&action=admin",
+                                                       'url'   => 'database.php',
+                                                       'urlvars' => array('subject' => 'database', 'action' => 'admin'),
                                                ),
                                                'privileges' => array (
                                                        'title' => $lang['strprivileges'],
-                                                       'url'   => "privileges.php?{$vars}",
+                                                       'url'   => 'privileges.php',
+                                                       'urlvars' => array('subject' => 'database'),
                                                        'hide'  => (!isset($data->privlist['database'])),
                                                        'help'  => 'pg.privilege',
                                                ),
                                                'languages' => array (
                                                        'title' => $lang['strlanguages'],
-                                                       'url'   => "languages.php?{$vars}",
+                                                       'url'   => 'languages.php',
+                                                       'urlvars' => array('subject' => 'database'),
                                                        'hide'  => $hide_advanced,
                                                        'help'  => 'pg.language',
                                                ),
                                                'casts' => array (
                                                        'title' => $lang['strcasts'],
-                                                       'url'   => "casts.php?{$vars}",
+                                                       'url'   => 'casts.php',
+                                                       'urlvars' => array('subject' => 'database'),
                                                        'hide'  => ($hide_advanced || !$data->hasCasts()),
                                                        'help'  => 'pg.cast',
                                                ),
                                                'export' => array (
                                                        'title' => $lang['strexport'],
-                                                       'url'   => "database.php?{$vars}&action=export",
+                                                       'url'   => 'database.php',
+                                                       'urlvars' => array('subject' => 'database', 'action' => 'export'),
                                                        'hide'  => (!$this->isDumpEnabled()),
                                                ),
                                        );
 
                                case 'schema':
-                                       $vars = $databasevar . $schemavar . '&subject=schema';
+#                                      $vars = $servervar . $databasevar . $schemavar . '&subject=schema';
                                        return array (
                                                'tables' => array (
                                                        'title' => $lang['strtables'],
-                                                       'url'   => "tables.php?{$vars}",
+                                                       'url'   => 'tables.php',
+                                                       'urlvars' => array('subject' => 'schema'),
                                                        'help'  => 'pg.table',
+                                                       'icon'  => 'tables',
                                                ),
                                                'views' => array (
                                                        'title' => $lang['strviews'],
-                                                       'url'   => "views.php?{$vars}",
+                                                       'url'   => 'views.php',
+                                                       'urlvars' => array('subject' => 'schema'),
                                                        'help'  => 'pg.view',
+                                                       'icon'  => 'views',
                                                ),
                                                'sequences' => array (
                                                        'title' => $lang['strsequences'],
-                                                       'url'   => "sequences.php?{$vars}",
+                                                       'url'   => 'sequences.php',
+                                                       'urlvars' => array('subject' => 'schema'),
                                                        'help'  => 'pg.sequence',
+                                                       'icon'  => 'sequences',
                                                ),
                                                'functions' => array (
                                                        'title' => $lang['strfunctions'],
-                                                       'url'   => "functions.php?{$vars}",
+                                                       'url'   => 'functions.php',
+                                                       'urlvars' => array('subject' => 'schema'),
                                                        'help'  => 'pg.function',
+                                                       'icon'  => 'functions',
                                                ),
                                                'domains' => array (
                                                        'title' => $lang['strdomains'],
-                                                       'url'   => "domains.php?{$vars}",
+                                                       'url'   => 'domains.php',
+                                                       'urlvars' => array('subject' => 'schema'),
                                                        'hide'  => (!$data->hasDomains()),
                                                        'help'  => 'pg.domain',
+                                                       'icon'  => 'domains',
                                                ),
                                                'aggregates' => array (
                                                        'title' => $lang['straggregates'],
-                                                       'url'   => "aggregates.php?{$vars}",
+                                                       'url'   => 'aggregates.php',
+                                                       'urlvars' => array('subject' => 'schema'),
                                                        'hide'  => $hide_advanced,
                                                        'help'  => 'pg.aggregate',
+                                                       'icon'  => 'functions',
                                                ),
                                                'types' => array (
                                                        'title' => $lang['strtypes'],
-                                                       'url'   => "types.php?{$vars}",
+                                                       'url'   => 'types.php',
+                                                       'urlvars' => array('subject' => 'schema'),
                                                        'hide'  => $hide_advanced,
                                                        'help'  => 'pg.type',
+                                                       'icon'  => 'types',
                                                ),
                                                'operators' => array (
                                                        'title' => $lang['stroperators'],
-                                                       'url'   => "operators.php?{$vars}",
+                                                       'url'   => 'operators.php',
+                                                       'urlvars' => array('subject' => 'schema'),
                                                        'hide'  => $hide_advanced,
                                                        'help'  => 'pg.operator',
+                                                       'icon'  => 'operators',
                                                ),
                                                'opclasses' => array (
                                                        'title' => $lang['stropclasses'],
-                                                       'url'   => "opclasses.php?{$vars}",
+                                                       'url'   => 'opclasses.php',
+                                                       'urlvars' => array('subject' => 'schema'),
                                                        'hide'  => $hide_advanced,
                                                        'help'  => 'pg.opclass',
+                                                       'icon'  => 'operators',
                                                ),
                                                'conversions' => array (
                                                        'title' => $lang['strconversions'],
-                                                       'url'   => "conversions.php?{$vars}",
+                                                       'url'   => 'conversions.php',
+                                                       'urlvars' => array('subject' => 'schema'),
                                                        'hide'  => ($hide_advanced || !$data->hasConversions()),
                                                        'help'  => 'pg.conversion',
+                                                       'icon'  => 'types',
                                                ),
                                                'privileges' => array (
                                                        'title' => $lang['strprivileges'],
-                                                       'url'   => "privileges.php?{$vars}",
+                                                       'url'   => 'privileges.php',
+                                                       'urlvars' => array('subject' => 'schema'),
                                                        'hide'  => (!$data->hasSchemas()),
                                                        'help'  => 'pg.privilege',
                                                ),
                                        );
 
                                case 'table':
-                                       $table = urlencode($_REQUEST['table']);
-                                       $vars = $databasevar . $schemavar . "&table={$table}&subject=table";
+#                                      $table = urlencode($_REQUEST['table']);
+#                                      $vars = $servervar . $databasevar . $schemavar . "&table={$table}&subject=table";
                                        return array (
                                                'columns' => array (
                                                        'title' => $lang['strcolumns'],
-                                                       'url'   => "tblproperties.php?{$vars}",
+                                                       'url'   => 'tblproperties.php',
+                                                       'urlvars' => array('subject' => 'table', 'table' => field('table')),
                                                ),
                                                'indexes' => array (
                                                        'title' => $lang['strindexes'],
-                                                       'url'   => "indexes.php?{$vars}",
+                                                       'url'   => 'indexes.php',
+                                                       'urlvars' => array('subject' => 'table', 'table' => field('table')),
                                                        'help'  => 'pg.index',
                                                ),
                                                'constraints' => array (
                                                        'title' => $lang['strconstraints'],
-                                                       'url'   => "constraints.php?{$vars}",
+                                                       'url'   => 'constraints.php',
+                                                       'urlvars' => array('subject' => 'table', 'table' => field('table')),
                                                        'help'  => 'pg.constraint',
                                                ),
                                                'triggers' => array (
                                                        'title' => $lang['strtriggers'],
-                                                       'url'   => "triggers.php?{$vars}",
+                                                       'url'   => 'triggers.php',
+                                                       'urlvars' => array('subject' => 'table', 'table' => field('table')),
                                                        'help'  => 'pg.trigger',
                                                ),
                                                'rules' => array (
                                                        'title' => $lang['strrules'],
-                                                       'url'   => "rules.php?{$vars}",
+                                                       'url'   => 'rules.php',
+                                                       'urlvars' => array('subject' => 'table', 'table' => field('table')),
                                                        'help'  => 'pg.rule',
                                                ),
                                                'info' => array (
                                                        'title' => $lang['strinfo'],
-                                                       'url'   => "info.php?{$vars}",
+                                                       'url'   => 'info.php',
+                                                       'urlvars' => array('subject' => 'table', 'table' => field('table')),
                                                ),
                                                'privileges' => array (
                                                        'title' => $lang['strprivileges'],
-                                                       'url'   => "privileges.php?{$vars}",
+                                                       'url'   => 'privileges.php',
+                                                       'urlvars' => array('subject' => 'table', 'table' => field('table')),
                                                        'help'  => 'pg.privilege',
                                                ),
                                                'import' => array (
                                                        'title' => $lang['strimport'],
-                                                       'url'   => "tblproperties.php?{$vars}&action=import",
+                                                       'url'   => 'tblproperties.php',
+                                                       'urlvars' => array('subject' => 'table', 'table' => field('table'), 'action' => 'import'),
                                                ),
                                                'export' => array (
                                                        'title' => $lang['strexport'],
-                                                       'url'   => "tblproperties.php?{$vars}&action=export",
+                                                       'url'   => 'tblproperties.php',
+                                                       'urlvars' => array('subject' => 'table', 'table' => field('table'), 'action' => 'export'),
                                                ),
                                        );
                                
                                case 'view':
-                                       $view = urlencode($_REQUEST['view']);
-                                       $vars = $databasevar . $schemavar . "&view={$view}&subject=view";
+#                                      $view = urlencode($_REQUEST['view']);
+#                                      $vars = $servervar . $databasevar . $schemavar . "&view={$view}&subject=view";
                                        return array (
                                                'columns' => array (
                                                        'title' => $lang['strcolumns'],
-                                                       'url'   => "viewproperties.php?{$vars}",
+                                                       'url'   => 'viewproperties.php',
+                                                       'urlvars' => array('subject' => 'view', 'view' => field('view')),
                                                ),
                                                'definition' => array (
                                                        'title' => $lang['strdefinition'],
-                                                       'url'   => "viewproperties.php?{$vars}&action=definition",
+                                                       'url'   => 'viewproperties.php',
+                                                       'urlvars' => array('subject' => 'view', 'view' => field('view'), 'action' => 'definition'),
                                                ),
                                                'rules' => array (
                                                        'title' => $lang['strrules'],
-                                                       'url'   => "rules.php?{$vars}",
+                                                       'url'   => 'rules.php',
+                                                       'urlvars' => array('subject' => 'view', 'view' => field('view')),
                                                        'help'  => 'pg.rule',
                                                ),
                                                'privileges' => array (
                                                        'title' => $lang['strprivileges'],
-                                                       'url'   => "privileges.php?{$vars}",
+                                                       'url'   => 'privileges.php',
+                                                       'urlvars' => array('subject' => 'view', 'view' => field('view')),
                                                        'help'  => 'pg.privilege',
                                                ),
                                                'export' => array (
                                                        'title' => $lang['strexport'],
-                                                       'url'   => "viewproperties.php?{$vars}&action=export",
+                                                       'url'   => 'viewproperties.php',
+                                                       'urlvars' => array('subject' => 'view', 'view' => field('view'), 'action' => 'export'),
                                                ),
                                        );
                                
                                case 'function':
-                                       $funcnam = urlencode($_REQUEST['function']);
-                                       $funcoid = urlencode($_REQUEST['function_oid']);
-                                       $vars = $databasevar . $schemavar . "&function={$funcnam}&function_oid={$funcoid}&subject=function";
+#                                      $funcnam = urlencode($_REQUEST['function']);
+#                                      $funcoid = urlencode($_REQUEST['function_oid']);
+#                                      $vars = $servervar . $databasevar . $schemavar . "&function={$funcnam}&function_oid={$funcoid}&subject=function";
                                        return array (
                                                'definition' => array (
                                                        'title' => $lang['strdefinition'],
-                                                       'url'   => "functions.php?{$vars}&action=properties",
+                                                       'url'   => 'functions.php',
+                                                       'urlvars' => array(
+                                                                       'subject' => 'function',
+                                                                       'function' => field('function'),
+                                                                       'function_oid' => field('function_oid'),
+                                                                       'action' => 'properties',
+                                                               ),
                                                ),
                                                'privileges' => array (
                                                        'title' => $lang['strprivileges'],
-                                                       'url'   => "privileges.php?{$vars}",
+                                                       'url'   => 'privileges.php',
+                                                       'urlvars' => array(
+                                                                       'subject' => 'function',
+                                                                       'function' => field('function'),
+                                                                       'function_oid' => field('function_oid'),
+                                                               ),
                                                ),
                                        );
                                
                                case 'popup':
-                                       $vars = $databasevar;
+#                                      $vars = $servervar . $databasevar;
                                        return array (
                                                'sql' => array (
                                                        'title' => $lang['strsql'],
-                                                       'url'   => "sqledit.php?{$vars}&action=sql",
+                                                       'url'   => 'sqledit.php',
+                                                       'urlvars' => array('subject' => 'schema', 'action' => 'sql'),
                                                        'help'  => 'pg.sql',
                                                ),
                                                'find' => array (
                                                        'title' => $lang['strfind'],
-                                                       'url'   => "sqledit.php?{$vars}&action=find",
+                                                       'url'   => 'sqledit.php',
+                                                       'urlvars' => array('subject' => 'schema', 'action' => 'find'),
                                                ),
                                        );
                                
                        return isset($tab['url']) ? $tab['url'] : null;
                }
 
+               function printTopbar() {
+                       global $lang, $conf, $appName, $appVersion, $appLangFiles;
+                       
+                       $server_info = $this->getServerInfo();
+                       
+                       echo "<div class=\"topbar\"><table width=\"100%\"><tr><td>";
+                       
+                       if ($server_info && isset($server_info['platform']) && isset($server_info['username'])) {
+                               echo sprintf($lang['strtopbar'],
+                                       '<span class="platform">'.htmlspecialchars($server_info['platform']).'</span>',
+                                       '<span class="host">'.htmlspecialchars($server_info['host']).'</span>',
+                                       '<span class="port">'.htmlspecialchars($server_info['port']).'</span>',
+                                       '<span class="username">'.htmlspecialchars($server_info['username']).'</span>',
+                                       '<span class="date">'.date($lang['strtimefmt']).'</span>');
+                       } else {
+                               echo "<span class=\"appname\">$appName</span> <span class=\"version\">$appVersion</span>";
+                       }
+                       
+                       echo "</td>";
+
+                       if (isset($_REQUEST['server'])) {
+                               $url = "sqledit.php?{$this->href}&amp;action=";
+                               
+                               $window_id = htmlspecialchars('sqledit:'.$_REQUEST['server']);
+                               
+                               echo "<td align=\"right\">";
+                               
+                               echo "<a class=\"toplink\" href=\"{$url}sql\" target=\"sqledit\" onclick=\"window.open('{$url}sql','{$window_id}','toolbar=no,width=600,height=400,resizable=yes,scrollbars=no').focus(); return false;\">{$lang['strsql']}</a> | ";
+                               
+                               echo "<a class=\"toplink\" href=\"{$url}find\" target=\"sqledit\" onclick=\"window.open('{$url}find','{$window_id}','toolbar=no,width=600,height=400,resizable=yes,scrollbars=no').focus(); return false;\">{$lang['strfind']}</a>";
+                               
+                               echo "</td>";
+                       }
+/*
+                       echo "<td align=\"right\" width=\"1%\">";
+                       
+                       echo "<form method=\"get\"><select name=\"language\" onchange=\"this.form.submit()\">\n";
+                       $language = isset($_SESSION['webdbLanguage']) ? $_SESSION['webdbLanguage'] : 'english';
+                       foreach ($appLangFiles as $k => $v) {
+                               echo "<option value=\"{$k}\"",
+                                       ($k == $language) ? ' selected="selected"' : '',
+                                       ">{$v}</option>\n";
+                       }
+                       echo "</select>\n";
+                       echo "<noscript><input type=\"submit\" value=\"Set Language\"></noscript>\n";
+                       foreach ($_GET as $key => $val) {
+                               if ($key == 'language') continue;
+                               echo "<input type=\"hidden\" name=\"$key\" value=\"", htmlspecialchars($val), "\" />\n";
+                       }
+                       echo "</form>\n";
+                       
+                       echo "</td>";
+*/
+                       echo "</tr></table></div>\n";
+               }
+               
                /**
                 * Display a bread crumb trail.
                 */
                function printTrail($trail = array()) {
                        global $lang;
                        
+                       $this->printTopbar();
+                       
                        if (is_string($trail)) {
                                $trail = $this->getTrail($trail);
                        }
                 * @param $object The type of object at the end of the trail.
                 */
                function getTrail($subject = null) {
-                       global $lang, $conf;
+                       global $lang, $conf, $data, $appName;
                        
                        $trail = array();
                        $vars = '';
                        $done = false;
                        
-                       $trail['server'] = array(
-                               'title' => $lang['strserver'],
-                               'text'  => $conf['servers'][$_SESSION['webdbServerID']]['desc'],
-                               'url'   => 'redirect.php?section=server',
-                               'help'  => 'pg.server'
+                       $trail['root'] = array(
+                               'text'  => $appName,
+                               'url'   => 'redirect.php?subject=root',
                        );
+                       
+                       if ($subject == 'root') $done = true;
+                       
+                       if (!$done) {
+                               $vars = 'server='.urlencode($_REQUEST['server']).'&';
+                               $server_info = $this->getServerInfo();
+                               $trail['server'] = array(
+                                       'title' => $lang['strserver'],
+                                       'text'  => $server_info['desc'],
+                                       'url'   => "redirect.php?subject=server&{$vars}",
+                                       'help'  => 'pg.server'
+                               );
+                       }
                        if ($subject == 'server') $done = true;
                        
                        if (isset($_REQUEST['database']) && !$done) {
-                               $vars = 'database='.urlencode($_REQUEST['database']).'&';
+                               $vars .= 'database='.urlencode($_REQUEST['database']).'&';
                                $trail['database'] = array(
                                        'title' => $lang['strdatabase'],
                                        'text'  => $_REQUEST['database'],
-                                       'url'   => "redirect.php?section=database&{$vars}",
+                                       'url'   => "redirect.php?subject=database&{$vars}",
                                        'help'  => 'pg.database'
                                );
                        }
                                $trail['schema'] = array(
                                        'title' => $lang['strschema'],
                                        'text'  => $_REQUEST['schema'],
-                                       'url'   => "redirect.php?section=schema&{$vars}",
+                                       'url'   => "redirect.php?subject=schema&{$vars}",
                                        'help'  => 'pg.schema'
                                );
                        }
                        if ($subject == 'schema') $done = true;
                        
                        if (isset($_REQUEST['table']) && !$done) {
-                               $vars .= "section=table&table=".urlencode($_REQUEST['table']);
+                               $vars .= "subject=table&table=".urlencode($_REQUEST['table']);
                                $trail['table'] = array(
                                        'title' => $lang['strtable'],
                                        'text'  => $_REQUEST['table'],
                                        'help'  => 'pg.table'
                                );
                        } elseif (isset($_REQUEST['view']) && !$done) {
-                               $vars .= "section=view&view=".urlencode($_REQUEST['view']);
+                               $vars .= "subject=view&view=".urlencode($_REQUEST['view']);
                                $trail['view'] = array(
                                        'title' => $lang['strview'],
                                        'text'  => $_REQUEST['view'],
                                switch ($subject) {
                                        case 'function':
                                                $vars .= "{$subject}_oid=".urlencode($_REQUEST[$subject.'_oid']).'&';
-                                               $vars .= "section={$subject}&{$subject}=".urlencode($_REQUEST[$subject]);
+                                               $vars .= "subject={$subject}&{$subject}=".urlencode($_REQUEST[$subject]);
                                                $trail[$subject] = array(
                                                        'title' => $lang['str'.$subject],
                                                        'text'  => $_REQUEST[$subject],
                        echo $str;
                        if ($help) {
                                echo "<a class=\"help\" href=\"";
-                               echo htmlspecialchars("help.php?help=".urlencode($help));
+                               echo htmlspecialchars("help.php?help=".urlencode($help)."&server=".urlencode($_REQUEST['server']));
                                echo "\" title=\"{$lang['strhelp']}\" target=\"phppgadminhelp\">{$lang['strhelpicon']}</a>";
                        }
                }
                        echo "-->\n";
                        echo "</script>\n";
                }
+               
+               /**
+                * Outputs JavaScript to set the name of the browser window.
+                * @param $name the window name
+                * @param $addServer if true (default) then the server id is
+                *        attached to the name.
+                */
+               function setWindowName($name, $addServer = true) {
+                       echo "<script type=\"text/javascript\">\n<!--\n";
+                       echo "   window.name = '{$name}", ($addServer ? ':'.htmlspecialchars($_REQUEST['server']) : ''), "';\n";
+                       echo "-->\n</script>\n";
+               }
 
                /**
                 * Converts a PHP.INI size variable to bytes.  Taken from publically available
                 * @param $strIniSize The PHP.INI variable
                 * @return size in bytes, false on failure
                 */
-               function inisizeToBytes($strIniSize) {
+               function inisizeToBytes($strIniSize) {
                        // This function will take the string value of an ini 'size' parameter,
                        // and return a double (64-bit float) representing the number of bytes
                        // that the parameter represents. Or false if $strIniSize is unparseable.
                                default:
                                        return $nSize;
                        }
-               }                
+               }
+
+               /**
+                * Display a URL given an action associative array.
+                * @param $action An associative array of the follow properties:
+                *                      'url'  => The first part of the URL (before the ?)
+                *                      'urlvars' => Associative array of (URL variable => field name)
+                *                                              these are appended to the URL
+                *                      'urlfn' => Function to apply to URL before display
+                * @param $fields Field data from which 'urlfield' and 'vars' are obtained.
+                * @param $attr If supplied then the URL will be quoted and prefixed with
+                *                              '$attr='.
+                */
+               function printActionUrl(&$action, &$fields, $attr = null) {
+                       $url = value($action['url'], $fields);
+                       
+                       if ($url === false) return '';
+                       
+                       if (!empty($action['urlvars'])) {
+                               $urlvars = value($action['urlvars'], $fields);
+                       } else {
+                               $urlvars = array();
+                       }
+                       
+                       if (isset($urlvars['subject'])) {
+                               $subject = value($urlvars['subject'], $fields);
+                               if (isset($_REQUEST['server']) && $subject != 'root') {
+                                       $urlvars['server'] = $_REQUEST['server'];
+                                       if (isset($_REQUEST['database']) && $subject != 'server') {
+                                               $urlvars['database'] = $_REQUEST['database'];
+                                               if (isset($_REQUEST['schema']) && $subject != 'database') {
+                                                       $urlvars['schema'] = $_REQUEST['schema'];
+                                               }
+                                       }
+                               }
+                       }
+                       
+                       $sep = '?';
+                       foreach ($urlvars as $var => $varfield) {
+                               $url .= $sep . value_url($var, $fields) . '=' . value_url($varfield, $fields);
+                               $sep = '&';
+                       }
+                       
+                       $url = htmlentities($url);
+                       
+                       if ($attr !== null && $url != '')
+                               return ' '.$attr.'="'.$url.'"';
+                       else
+                               return $url;
+               }
 
+               function getRequestVars($subject = '') {
+                       $v = array();
+                       if (!empty($subject))
+                               $v['subject'] = $subject;
+                       if (isset($_REQUEST['server']) && $subject != 'root') {
+                               $v['server'] = $_REQUEST['server'];
+                               if (isset($_REQUEST['database']) && $subject != 'server') {
+                                       $v['database'] = $_REQUEST['database'];
+                                       if (isset($_REQUEST['schema']) && $subject != 'database') {
+                                               $v['schema'] = $_REQUEST['schema'];
+                                       }
+                               }
+                       }
+                       return $v;
+               }
+               
                function printUrlVars(&$vars, &$fields) {
                        foreach ($vars as $var => $varfield) {
                                echo "{$var}=", urlencode($fields[$varfield]), "&amp;";
                                                switch ($column_id) {
                                                        case 'actions':
                                                                foreach ($alt_actions as $action) {
-                                                                       if (isset($action['disable'])) {
+                                                                       if (isset($action['disable']) && $action['disable'] === true) {
                                                                                echo "<td class=\"data{$id}\"></td>";
                                                                        } else {
                                                                                echo "<td class=\"opbutton{$id}\">";
                                                                break;
                                                        default;
                                                                echo "<td class=\"data{$id}\">";
-                                                               if (isset($column['url'])) {
-                                                                       echo "<a href=\"{$column['url']}";
-                                                                       $misc->printUrlVars($column['vars'], $tabledata->f);
-                                                                       echo "\">";
-                                                               }
+                                                               if (isset($tabledata->f[$column['field']])) {
+                                                                       if (isset($column['url'])) {
+                                                                               echo "<a href=\"{$column['url']}";
+                                                                               $misc->printUrlVars($column['vars'], $tabledata->f);
+                                                                               echo "\">";
+                                                                       }
                                                                
-                                                               $type = isset($column['type']) ? $column['type'] : null;
-                                                               $params = isset($column['params']) ? $column['params'] : array();
-                                                               echo $misc->printVal($tabledata->f[$column['field']], $type, $params);
+                                                                       $type = isset($column['type']) ? $column['type'] : null;
+                                                                       $params = isset($column['params']) ? $column['params'] : array();
+                                                                       echo $misc->printVal($tabledata->f[$column['field']], $type, $params);
+                                                               }
                                                                
                                                                if (isset($column['url'])) echo "</a>";
 
                        }
                }
                
+               /** Produce XML data for the browser tree
+                * @param $treedata A set of records to populate the tree.
+                * @param $attrs Attributes for tree items
+                *        'text' - the text for the tree node
+                *        'icon' - an icon for node
+                *        'openIcon' - an alternative icon when the node is expanded
+                *        'toolTip' - tool tip text for the node
+                *        'action' - URL to visit when single clicking the node
+                *        'branch' - URL for child nodes (tree XML)
+                *        'expand' - the action to return XML for the subtree
+                *        'nodata' - message to display when node has no children
+                */
+               function printTreeXML(&$treedata, &$attrs) {
+                       global $conf, $lang;
+                       header("Content-Type: text/xml");
+                       header("Cache-Control: no-cache");
+                       
+                       echo "<?xml version=\"1.0\"?>\n";
+                       
+                       echo "<tree>\n";
+                       
+                       if ($treedata->recordCount() > 0) {
+                               while (!$treedata->EOF) {
+                                       $rec =& $treedata->f;
+                                       
+                                       echo "<tree";
+                                       echo value_xml_attr('text', $attrs['text'], $rec);
+                                       echo value_xml_attr('action', $attrs['action'], $rec);
+                                       echo value_xml_attr('src', $attrs['branch'], $rec);
+                                       
+                                       $icon = $this->icon(value($attrs['icon'], $rec));
+                                       echo value_xml_attr('icon', $icon, $rec);
+                                       
+                                       if (!empty($attrs['openIcon'])) {
+                                               $icon = $this->icon(value($attrs['openIcon'], $rec));
+                                       }
+                                       echo value_xml_attr('openIcon', $icon, $rec);
+                                       
+                                       echo value_xml_attr('toolTip', $attrs['toolTip'], $rec);
+                                       
+                                       echo "/>\n";
+                                       
+                                       $treedata->moveNext();
+                               }
+                       } else {
+                               $msg = isset($attrs['nodata']) ? $attrs['nodata'] : $lang['strnoobjects'];
+                               echo "<tree text=\"{$msg}\" onaction=\"this.parentNode.reload()\" icon=\"", $this->icon('error'), "\"/>\n";
+                       }
+                       
+                       echo "</tree>\n";
+               }
+               
+               function icon($icon) {
+                       global $conf;
+                       $path = "images/themes/{$conf['theme']}/{$icon}";
+                       if (file_exists($path.'.png')) return $path.'.png';
+                       if (file_exists($path.'.gif')) return $path.'.gif';
+                       $path = "images/themes/default/{$icon}";
+                       if (file_exists($path.'.png')) return $path.'.png';
+                       if (file_exists($path.'.gif')) return $path.'.gif';
+                       return '';
+               }
+               
                /**
                 * Function to escape command line parameters
                 * @param $str The string to escape
                        else    
                                return escapeshellcmd($str);
                }
+               
+               /**
+                * Get list of servers
+                * @param $recordset return as RecordSet suitable for printTable if true,
+                *                   otherwise just return an array.
+                */
+               function &getServers($recordset = false) {
+                       global $conf;
+                       
+                       $srvs = isset($_SESSION['webdbLogin']) && is_array($_SESSION['webdbLogin']) ? $_SESSION['webdbLogin'] : array();
+                       
+                       foreach($conf['servers'] as $idx => $info) {
+                               $server_id = $info['host'].':'.$info['port'];
+                               
+                               if (!isset($srvs[$server_id])) {
+                                       $srvs[$server_id] = $info;
+                               }
+                               $srvs[$server_id]['id'] = $server_id;
+                       }
+                       
+                       function _cmp_desc($a, $b) {
+                               return strcmp($a['desc'], $b['desc']);
+                       }
+                       uasort($srvs, '_cmp_desc');
+                       
+                       if ($recordset) {
+                               include_once('classes/ArrayRecordSet.php');
+                               return new ArrayRecordSet($srvs);
+                       }
+                       return $srvs;
+               }
+               
+               /**
+                * Get information on a server.
+                * If the parameter isn't supplied then the currently
+                * connected server is returned.
+                * @param $server_id A server identifier (host:port)
+                * @return An associative array of server properties
+                */
+               function getServerInfo($server_id = null) {
+                       global $conf;
+                       
+                       if ($server_id === null && isset($_REQUEST['server']))
+                               $server_id = $_REQUEST['server'];
+                       
+                       // Check for the server in the logged-in list
+                       if (isset($_SESSION['webdbLogin'][$server_id]))
+                               return $_SESSION['webdbLogin'][$server_id];
+                       
+                       // Otherwise, look for it in the conf file
+                       foreach($conf['servers'] as $idx => $info) {
+                               if ($server_id == $info['host'].':'.$info['port'])
+                                       return $info;
+                       }
+                       
+                       return null;
+               }
+               
+               /**
+                * Set server information.
+                * @param $key parameter name to set, or null to replace all
+                *             params with the assoc-array in $value.
+                * @param $value the new value, or null to unset the parameter
+                * @param $server_id the server identifier, or null for current
+                *                   server.
+                */
+               function setServerInfo($key, $value, $server_id = null)
+               {
+                       if ($server_id === null && isset($_REQUEST['server']))
+                               $server_id = $_REQUEST['server'];
+                       
+                       if ($key === null) {
+                               if ($value === null)
+                                       unset($_SESSION['webdbLogin'][$server_id]);
+                               else
+                                       $_SESSION['webdbLogin'][$server_id] = $value;
+                       } else {
+                               if ($value === null)
+                                       unset($_SESSION['webdbLogin'][$server_id][$key]);
+                               else
+                                       $_SESSION['webdbLogin'][$server_id][$key] = $value;
+                       }
+               }
        }
 ?>
index 8cabfcea8690d4a1a08df5111ba73a731cc73fc2..65fe2e1960cf9d8ab8174c2711c322a00a1277c2 100644 (file)
@@ -4,7 +4,7 @@
         * the functions provided by the database driver exclusively, and hence
         * will work with any database without modification.
         *
-        * $Id: Reports.php,v 1.11 2004/07/01 07:15:11 chriskl Exp $
+        * $Id: Reports.php,v 1.12 2005/05/02 15:47:26 chriskl Exp $
         */
 
        class Reports {
                 * @return A recordset
                 */
                function &getReports() {
-                       global $conf;
+                       global $conf, $misc;
                        // Filter for owned reports if necessary
                        if ($conf['owned_reports_only']) {
-                               $filter['created_by'] = $_SESSION['webdbUsername'];
+                               $server_info = $misc->getServerInfo();
+                               $filter['created_by'] = $server_info['username'];
                                $ops = array('created_by' => '=');
                        }
                        else $filter = $ops = array();
                 * @return 0 success
                 */
                function createReport($report_name, $db_name, $descr, $report_sql) {
+                       global $misc;
+                       $server_info = $misc->getServerInfo();
                        $temp = array(
                                'report_name' => $report_name,
                                'db_name' => $db_name,
-                               'created_by' => $_SESSION['webdbUsername'],
+                               'created_by' => $server_info['username'],
                                'report_sql' => $report_sql
                        );
                        if ($descr != '') $temp['descr'] = $descr;
                 * @return 0 success
                 */
                function alterReport($report_id, $report_name, $db_name, $descr, $report_sql) {
+                       global $misc;
+                       $server_info = $misc->getServerInfo();
                        $temp = array(
                                'report_name' => $report_name,
                                'db_name' => $db_name,
-                               'created_by' => $_SESSION['webdbUsername'],
+                               'created_by' => $server_info['username'],
                                'report_sql' => $report_sql
                        );
                        if ($descr != '') $temp['descr'] = $descr;
index 30cf2da1a1ae194a08b088684e17eada02518360..cf8c28d3c2ae23a0b24697ae0cc10ad9fb65f8cf 100755 (executable)
@@ -4,7 +4,7 @@
  * A class that implements the DB interface for Postgres
  * Note: This class uses ADODB and returns RecordSets.
  *
- * $Id: Postgres.php,v 1.260 2005/04/30 18:01:59 soranzo Exp $
+ * $Id: Postgres.php,v 1.261 2005/05/02 15:47:26 chriskl Exp $
  */
 
 // @@@ THOUGHT: What about inherits? ie. use of ONLY???
@@ -407,10 +407,12 @@ class Postgres extends ADODB_base {
         * @return A list of databases, sorted alphabetically
         */
        function &getDatabases($currentdatabase = NULL) {
-               global $conf;
+               global $conf, $misc;
 
-               if (isset($conf['owned_only']) && $conf['owned_only'] && !$this->isSuperUser($_SESSION['webdbUsername'])) {
-                       $username = $_SESSION['webdbUsername'];
+               $server_info = $misc->getServerInfo();
+               
+               if (isset($conf['owned_only']) && $conf['owned_only'] && !$this->isSuperUser($server_info['username'])) {
+                       $username = $server_info['username'];
                        $this->clean($username);
                        $clause = " AND pu.usename='{$username}'";
                }
@@ -3353,7 +3355,9 @@ class Postgres extends ADODB_base {
                                pt.typname AS proresult,
                                pl.lanname AS prolanguage,
                                oidvectortypes(pc.proargtypes) AS proarguments,
-                               (SELECT description FROM pg_description pd WHERE pc.oid=pd.objoid) AS procomment
+                               (SELECT description FROM pg_description pd WHERE pc.oid=pd.objoid) AS procomment,
+                               proname || ' (' || proarguments || ')' AS proproto,
+                               CASE WHEN proretset THEN 'setof ' ELSE '' END || pt.typname AS proreturns
                        FROM
                                pg_proc pc, pg_user pu, pg_type pt, pg_language pl
                        WHERE
@@ -3368,7 +3372,9 @@ class Postgres extends ADODB_base {
                                proretset,
                                'OPAQUE' AS proresult,
                                oidvectortypes(pc.proargtypes) AS proarguments,
-                               (SELECT description FROM pg_description pd WHERE pc.oid=pd.objoid) AS procomment
+                               (SELECT description FROM pg_description pd WHERE pc.oid=pd.objoid) AS procomment,
+                               proname || ' (' || proarguments || ')' AS proproto,
+                               CASE WHEN proretset THEN 'setof ' ELSE '' END || 'OPAQUE' AS proreturns
                        FROM
                                pg_proc pc, pg_user pu, pg_type pt
                        WHERE   
index bf828ac5e3810f98ed36368503db7e0056668e5c..bf35f02fbd1eb9b4ecbf2008c38e133f6a07258a 100644 (file)
@@ -4,7 +4,7 @@
  * A class that implements the DB interface for Postgres
  * Note: This class uses ADODB and returns RecordSets.
  *
- * $Id: Postgres71.php,v 1.70 2005/02/06 20:03:20 soranzo Exp $
+ * $Id: Postgres71.php,v 1.71 2005/05/02 15:47:26 chriskl Exp $
  */
 
 // @@@ THOUGHT: What about inherits? ie. use of ONLY???
@@ -86,10 +86,12 @@ class Postgres71 extends Postgres {
         * @return A list of databases, sorted alphabetically
         */
        function &getDatabases($currentdatabase = NULL) {
-               global $conf;
-
-               if (isset($conf['owned_only']) && $conf['owned_only'] && !$this->isSuperUser($_SESSION['webdbUsername'])) {
-                       $username = $_SESSION['webdbUsername'];
+               global $conf, $misc;
+               
+               $server_info = $misc->getServerInfo();
+               
+               if (isset($conf['owned_only']) && $conf['owned_only'] && !$this->isSuperUser($server_info['username'])) {
+                       $username = $server_info['username'];
                        $this->clean($username);
                        $clause = " AND pu.usename='{$username}'";
                }
index 8f6da6691b58df1ea25c9a45498ed92c9852aaa4..54d850a8fa9992a8a20846f94d175f605708ea4c 100644 (file)
@@ -4,7 +4,7 @@
  * A class that implements the DB interface for Postgres
  * Note: This class uses ADODB and returns RecordSets.
  *
- * $Id: Postgres72.php,v 1.78 2004/11/10 01:46:36 chriskl Exp $
+ * $Id: Postgres72.php,v 1.79 2005/05/02 15:47:26 chriskl Exp $
  */
 
 
@@ -324,7 +324,9 @@ class Postgres72 extends Postgres71 {
                                false AS proretset,
                                format_type(p.prorettype, NULL) AS proresult,
                                oidvectortypes(p.proargtypes) AS proarguments,
-                               (SELECT description FROM pg_description pd WHERE p.oid=pd.objoid) AS procomment
+                               (SELECT description FROM pg_description pd WHERE p.oid=pd.objoid) AS procomment,
+                               p.proname || ' (' || oidvectortypes(p.proargtypes) || ')' AS proproto,
+                               format_type(p.prorettype, NULL) AS proreturns
                        FROM
                                pg_proc p
                        WHERE
index 14f3b9bda0ff4df48a2ece78695a8dfa3a54d782..0ea905c196fd38a073488cbc947b04a6ceb51707 100644 (file)
@@ -4,7 +4,7 @@
  * A class that implements the DB interface for Postgres
  * Note: This class uses ADODB and returns RecordSets.
  *
- * $Id: Postgres73.php,v 1.142 2004/12/06 02:48:34 chriskl Exp $
+ * $Id: Postgres73.php,v 1.143 2005/05/02 15:47:26 chriskl Exp $
  */
 
 // @@@ THOUGHT: What about inherits? ie. use of ONLY???
@@ -720,7 +720,9 @@ class Postgres73 extends Postgres72 {
                                pg_catalog.format_type(p.prorettype, NULL) AS proresult,
                                pg_catalog.oidvectortypes(p.proargtypes) AS proarguments,
                                pl.lanname AS prolanguage,
-                               pg_catalog.obj_description(p.oid, 'pg_proc') AS procomment
+                               pg_catalog.obj_description(p.oid, 'pg_proc') AS procomment,
+                               p.proname || ' (' || pg_catalog.oidvectortypes(p.proargtypes) || ')' AS proproto,
+                               CASE WHEN p.proretset THEN 'setof ' ELSE '' END || pg_catalog.format_type(p.prorettype, NULL) AS proreturns
                        FROM pg_catalog.pg_proc p
                                INNER JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
                                INNER JOIN pg_catalog.pg_language pl ON pl.oid = p.prolang
index 9d9855fc46e32de47a834d263f8fdef13d91d454..abba26118f6b2345f2bd01ad3da891cbeadb63a2 100644 (file)
@@ -3,7 +3,7 @@
 /**
  * PostgreSQL 8.0 support
  *
- * $Id: Postgres80.php,v 1.12 2005/04/30 18:02:01 soranzo Exp $
+ * $Id: Postgres80.php,v 1.13 2005/05/02 15:47:26 chriskl Exp $
  */
 
 include_once('./classes/database/Postgres74.php');
@@ -48,10 +48,12 @@ class Postgres80 extends Postgres74 {
         * @return A list of databases, sorted alphabetically
         */
        function &getDatabases($currentdatabase = NULL) {
-               global $conf;
-
-               if (isset($conf['owned_only']) && $conf['owned_only'] && !$this->isSuperUser($_SESSION['webdbUsername'])) {
-                       $username = $_SESSION['webdbUsername'];
+               global $conf, $misc;
+               
+               $server_info = $misc->getServerInfo();
+               
+               if (isset($conf['owned_only']) && $conf['owned_only'] && !$this->isSuperUser($server_info['username'])) {
+                       $username = $server_info['username'];
                        $this->clean($username);
                        $clause = " AND pu.usename='{$username}'";
                }
index 85776870df14a1747ad154087750a9da4d5b5857..0dcdd954010e8269e05342b0ee2ddd27ee95c497 100644 (file)
@@ -3,7 +3,7 @@
        /**
         * List constraints on a table
         *
-        * $Id: constraints.php,v 1.40 2004/09/07 13:58:21 jollytoad Exp $
+        * $Id: constraints.php,v 1.41 2005/05/02 15:47:23 chriskl Exp $
         */
 
        // Include application functions
                
                $misc->printTable($constraints, $columns, $actions, $lang['strnoconstraints'], 'cnPre');
                
-               echo "<p><a class=\"navlink\" href=\"{$PHP_SELF}?action=add_check&{$misc->href}&table=", urlencode($_REQUEST['table']),
+               echo "<p><a class=\"navlink\" href=\"{$PHP_SELF}?action=add_check&amp;{$misc->href}&amp;table=", urlencode($_REQUEST['table']),
                        "\">{$lang['straddcheck']}</a> |\n";
-               echo "<a class=\"navlink\" href=\"{$PHP_SELF}?action=add_unique_key&{$misc->href}&table=", urlencode($_REQUEST['table']),
+               echo "<a class=\"navlink\" href=\"{$PHP_SELF}?action=add_unique_key&amp;{$misc->href}&amp;table=", urlencode($_REQUEST['table']),
                        "\">{$lang['stradduniq']}</a> |\n";
-               echo "<a class=\"navlink\" href=\"{$PHP_SELF}?action=add_primary_key&{$misc->href}&table=", urlencode($_REQUEST['table']),
+               echo "<a class=\"navlink\" href=\"{$PHP_SELF}?action=add_primary_key&amp;{$misc->href}&amp;table=", urlencode($_REQUEST['table']),
                        "\">{$lang['straddpk']}</a> |\n";
-               echo "<a class=\"navlink\" href=\"{$PHP_SELF}?action=add_foreign_key&{$misc->href}&table=", urlencode($_REQUEST['table']),
+               echo "<a class=\"navlink\" href=\"{$PHP_SELF}?action=add_foreign_key&amp;{$misc->href}&amp;table=", urlencode($_REQUEST['table']),
                        "\">{$lang['straddfk']}</a></p>\n";
        }
 
index 7437e0dc4b2a12d7867d18733521e176cc5ef6c6..316bcb1a7816cea1b465699149c793a5e077691e 100644 (file)
@@ -3,7 +3,7 @@
        /**
         * Manage conversions in a database
         *
-        * $Id: conversions.php,v 1.9 2004/09/01 16:35:58 jollytoad Exp $
+        * $Id: conversions.php,v 1.10 2005/05/02 15:47:23 chriskl Exp $
         */
 
        // Include application functions
                
                $misc->printTable($conversions, $columns, $actions, $lang['strnoconversions']);
        }
-
+       
+       /**
+        * Generate XML for the browser tree.
+        */
+       function doTree() {
+               global $misc, $data;
+               
+               $conversions = &$data->getconversions();
+               
+               $attrs = array(
+                       'text'   => field('conname'),
+                       'icon'   => 'conversions',
+                       'toolTip'=> field('concomment')
+               );
+               
+               $misc->printTreeXML($conversions, $attrs);
+               exit;
+       }
+       
+       if ($action == 'tree') doTree();
+       
        $misc->printHeader($lang['strconversions']);
        $misc->printBody();
 
index a3726770f315b1eca6ad6d853f17944b29444308..a3aee0cada3c6f1a7e6e4e3b93b1ebe9dcfbaf9e 100755 (executable)
@@ -3,7 +3,7 @@
        /**
         * Manage schemas within a database
         *
-        * $Id: database.php,v 1.65 2004/11/29 01:48:38 chriskl Exp $
+        * $Id: database.php,v 1.66 2005/05/02 15:47:23 chriskl Exp $
         */
 
        // Include application functions
                }
                echo "</p>\n";
                echo "<p><input type=\"hidden\" name=\"action\" value=\"export\" />\n";
-               echo "<p><input type=\"hidden\" name=\"mode\" value=\"database\" />\n";         
+               echo "<input type=\"hidden\" name=\"subject\" value=\"database\" />\n";
                echo $misc->form;
                echo "<input type=\"submit\" value=\"{$lang['strexport']}\" /></p>\n";
                echo "</form>\n";
 
                if ($data->hasSignals()) {
                        $columns['actions'] = array('title' => $lang['stractions']);
-
+                       
+                       $href = $misc->getHREF('schema');
+                       
                        $actions = array(
                                'cancel' => array(
                                        'title' => $lang['strcancel'],
-                                       'url'   => "{$PHP_SELF}?action=signal&amp;signal=CANCEL&amp;database=" . urlencode($_REQUEST['database']) . "&amp;",
+                                       'url'   => "{$PHP_SELF}?action=signal&amp;signal=CANCEL&amp;{$href}&amp;",
                                        'vars'  => array('procpid' => 'procpid')
                                )
                        );
                                $status = $data->recluster();
                                if ($status == 0) doAdmin('', $lang['strclusteredgood']);
                                else doAdmin('', $lang['strclusteredbad']);
-                               break;                          
+                               break;
                        case 'reindex';
                                $status = $data->reindex('DATABASE', $_REQUEST['database'], isset($_REQUEST['reindex_force']));
                                if ($status == 0) doAdmin('', $lang['strreindexgood']);
                        echo "<p>", sprintf($lang['strconfdropschema'], $misc->printVal($_REQUEST['schema'])), "</p>\n";
 
                        echo "<form action=\"{$PHP_SELF}\" method=\"post\">\n";
+                       echo $misc->form;
                        echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n";
                        echo "<input type=\"hidden\" name=\"database\" value=\"", htmlspecialchars($_REQUEST['database']), "\" />\n";
                        echo "<input type=\"hidden\" name=\"schema\" value=\"", htmlspecialchars($_REQUEST['schema']), "\" />\n";
                global $data, $misc;
                global $PHP_SELF, $lang;
 
+               $server_info = $misc->getServerInfo();
+               
                if (!isset($_POST['formName'])) $_POST['formName'] = '';
-               if (!isset($_POST['formAuth'])) $_POST['formAuth'] = $_SESSION['webdbUsername'];
+               if (!isset($_POST['formAuth'])) $_POST['formAuth'] = $server_info['username'];
                if (!isset($_POST['formSpc'])) $_POST['formSpc'] = '';
                if (!isset($_POST['formComment'])) $_POST['formComment'] = '';
 
                $misc->printMsg($msg);
                
                echo "<form action=\"$PHP_SELF\" method=\"post\">\n";
+               echo $misc->form;
                echo "<table width=\"100%\">\n";
                echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n";
                echo "\t\t<td class=\"data1\"><input name=\"formName\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"",
                                ),
                        );
                        
+                       $href = $misc->getHREF('schema');
+                       
                        $actions = array(
                                'properties' => array(
                                        'title' => $lang['strproperties'],
-                                       'url'   => "redirect.php?section=schema&amp;database=".urlencode($_REQUEST['database'])."&amp;",
+                                       'url'   => "redirect.php?subject=schema&amp;{$href}&amp;",
                                        'vars'  => array('schema' => 'nspname'),
                                ),
                                'drop' => array(
                                        'title' => $lang['strdrop'],
-                                       'url'   => "{$PHP_SELF}?action=confirm_drop&amp;database=".urlencode($_REQUEST['database'])."&amp;",
+                                       'url'   => "{$PHP_SELF}?action=confirm_drop&amp;{$href}&amp;",
                                        'vars'  => array('schema' => 'nspname'),
                                ),
                                'privileges' => array(
                                        'title' => $lang['strprivileges'],
-                                       'url'   => "privileges.php?subject=schema&amp;database=".urlencode($_REQUEST['database'])."&amp;",
+                                       'url'   => "privileges.php?subject=schema&amp;{$href}&amp;",
                                        'vars'  => array('schema' => 'nspname'),
                                ),
                                'alter' => array(
                                        'title' => $lang['stralter'],
-                                       'url'   => "{$PHP_SELF}?action=alter_schema&amp;database=".urlencode($_REQUEST['database'])."&amp;",
+                                       'url'   => "{$PHP_SELF}?action=alter_schema&amp;{$href}&amp;",
                                        'vars'  => array('schema' => 'nspname'),
                                ),
                        );
                        
                        $misc->printTable($schemas, $columns, $actions, $lang['strnoschemas']);
 
-                       echo "<p><a class=\"navlink\" href=\"$PHP_SELF?database=", urlencode($_REQUEST['database']),
-                               "&amp;action=create\">{$lang['strcreateschema']}</a></p>\n";
+                       echo "<p><a class=\"navlink\" href=\"$PHP_SELF?action=create&amp;{$href}\">{$lang['strcreateschema']}</a></p>\n";
                } else {
                        // If the database does not support schemas...
                        echo "<p>{$lang['strnoschemas']}</p>\n";
                }
        }
        
+       function doTree() {
+               global $misc, $data, $lang, $PHP_SELF;
+               
+               $schemas = &$data->getSchemas();
+               
+               $reqvars = $misc->getRequestVars('schema');
+               
+               $attrs = array(
+                       'text'   => field('nspname'),
+                       'icon'   => 'folder',
+                       'toolTip'=> field('nspcomment'),
+                       'action' => url('redirect.php',
+                                                       $reqvars,
+                                                       array(
+                                                               'subject' => 'schema',
+                                                               'schema'  => field('nspname')
+                                                       )
+                                               ),
+                       'branch' => url('database.php',
+                                                       $reqvars,
+                                                       array(
+                                                               'action'  => 'subtree',
+                                                               'schema'  => field('nspname')
+                                                       )
+                                               )
+               );
+               
+               $misc->printTreeXML($schemas, $attrs);
+               exit;
+       }
+       
+       function doSubTree() {
+               global $misc, $data, $lang;
+               
+               include_once('classes/ArrayRecordSet.php');
+               $tabs = $misc->getNavTabs('schema');
+               
+               // Remove Privileges link
+               unset($tabs['privileges']);
+               
+               // Remove hidden links
+               foreach ($tabs as $i => $tab) {
+                       if (isset($tab['hide']) && $tab['hide'] === true)
+                               unset($tabs[$i]);
+               }
+               $items =& new ArrayRecordSet($tabs);
+               
+               $reqvars = $misc->getRequestVars('schema');
+               
+               $attrs = array(
+                       'text'   => noEscape(field('title')),
+                       'icon'   => field('icon', 'folder'),
+                       'action' => url(field('url'),
+                                                       $reqvars,
+                                                       field('urlvars', array())
+                                               ),
+                       'branch' => url(field('url'),
+                                                       $reqvars,
+                                                       field('urlvars'),
+                                                       array('action' => 'tree')
+                                               )
+               );
+               
+               $misc->printTreeXML($items, $attrs);
+               exit;
+       }
+       
        /**
         * Display a form to permit editing schema properies.
         * TODO: permit changing name, owner
                        doAlterSchema($lang['strschemaalteredbad']);
        }
 
+       if ($action == 'tree') doTree();
+       if ($action == 'subtree') doSubTree();
+       
        $misc->printHeader($lang['strschemas']);
        $misc->printBody();
 
index 983cba884bdb723ceec51a29fde27f3932b9fdb0..fc9212f3dcce51ca49d25e6ad475ee10f3a478ab 100644 (file)
@@ -4,7 +4,7 @@
         * Does an export to the screen or as a download.  This checks to
         * see if they have pg_dump set up, and will use it if possible.
         *
-        * $Id: dataexport.php,v 1.19 2005/03/04 02:27:29 chriskl Exp $
+        * $Id: dataexport.php,v 1.20 2005/05/02 15:47:23 chriskl Exp $
         */
 
        $extensions = array(
        // What must we do in this case? Maybe redirect to the homepage?
 
        // If format is set, then perform the export
-       if (isset($_REQUEST['what'])) {          
-
+       if (isset($_REQUEST['what'])) {
+               
                // Include application functions
                $_no_output = true;
                include_once('./libraries/lib.inc.php');
-
+               
                switch ($_REQUEST['what']) {
                        case 'dataonly':
                                // Check to see if they have pg_dump set up and if they do, use that
                                // instead of custom dump code
                                if ($misc->isDumpEnabled()
                                                && ($_REQUEST['d_format'] == 'copy' || $_REQUEST['d_format'] == 'sql')) {
-                                       $url = 'dbexport.php?mode=database&database=' . urlencode($_REQUEST['database']);
-                                       $url .= '&what=' . urlencode($_REQUEST['what']);
-                                       $url .= '&table=' . urlencode($_REQUEST['table']);
-                                       if ($data->hasSchemas()) $url .= '&schema=' . urlencode($_REQUEST['schema']);
-                                       $url .= '&d_format=' . urlencode($_REQUEST['d_format']);
-                                       $url .= '&output=' . urlencode($_REQUEST['output']);
-                                       if (isset($_REQUEST['d_oids'])) $url .= '&d_oids=' . urlencode($_REQUEST['d_oids']);
-                                       $url .= "&" . SID;
-                                       
-                                       header("Location: {$url}");
+                                       include('./dbexport.php');
                                        exit;
                                }
                                else {
                                // Check to see if they have pg_dump set up and if they do, use that
                                // instead of custom dump code
                                if ($misc->isDumpEnabled()) {
-                                       $url = 'dbexport.php?mode=database&database=' . urlencode($_REQUEST['database']);
-                                       $url .= '&what=' . urlencode($_REQUEST['what']);
-                                       $url .= '&table=' . urlencode($_REQUEST['table']);
-                                       if ($data->hasSchemas()) $url .= '&schema=' . urlencode($_REQUEST['schema']);
-                                       $url .= '&output=' . urlencode($_REQUEST['output']);
-                                       if (isset($_REQUEST['s_clean'])) $url .= '&s_clean=' . urlencode($_REQUEST['s_clean']);
-                                       $url .= "&" . SID;
-                                       
-                                       header("Location: {$url}");
+                                       include('./dbexport.php');
                                        exit;
                                }
                                else $clean = isset($_REQUEST['s_clean']);
                                // Check to see if they have pg_dump set up and if they do, use that
                                // instead of custom dump code
                                if ($misc->isDumpEnabled()) {
-                                       $url = 'dbexport.php?mode=database&database=' . urlencode($_REQUEST['database']);
-                                       $url .= '&what=' . urlencode($_REQUEST['what']);
-                                       $url .= '&table=' . urlencode($_REQUEST['table']);
-                                       if ($data->hasSchemas()) $url .= '&schema=' . urlencode($_REQUEST['schema']);
-                                       $url .= '&sd_format=' . urlencode($_REQUEST['sd_format']);
-                                       $url .= '&output=' . urlencode($_REQUEST['output']);
-                                       if (isset($_REQUEST['sd_clean'])) $url .= '&sd_clean=' . urlencode($_REQUEST['sd_clean']);
-                                       if (isset($_REQUEST['sd_oids'])) $url .= '&sd_oids=' . urlencode($_REQUEST['sd_oids']);
-                                       $url .= "&" . SID;
-
-                                       header("Location: {$url}");
+                                       include('./dbexport.php');
                                        exit;
                                }
                                else {
                        if (strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE') && isset($_SERVER['HTTPS'])) {
                                header('Content-Type: text/plain');
                        }
-                       else {\r
+                       else {
                                header('Content-Type: application/download');
                
                                if (isset($extensions[$format]))
        
                if (isset($_REQUEST['query'])) $_REQUEST['query'] = trim(unserialize($_REQUEST['query']));
 
+               // Set the schema search path
+               if ($data->hasSchemas() && isset($_REQUEST['search_path'])) {
+                       $data->setSearchPath(array_map('trim',explode(',',$_REQUEST['search_path'])));
+               }
+               
                // Set up the dump transaction
                $status = $data->beginDump();
 
                $status = $data->endDump();
        }
        else {
-               if (!isset($msg)) $msg = null;
-               
                // Include application functions
                include_once('./libraries/lib.inc.php');
 
-               $misc->printHeader($lang['strexport']);         
-               echo "<h2>", $misc->printVal($_REQUEST['database']), ": {$lang['strexport']}</h2>\n";
-               $misc->printMsg($msg);
+               $misc->printHeader($lang['strexport']);
+               $misc->printBody();
+               $misc->printTrail(isset($_REQUEST['subject']) ? $_REQUEST['subject'] : 'database');
+               $misc->printTitle($lang['strexport']);
+               if (isset($msg)) $misc->printMsg($msg);
 
                echo "<form action=\"{$_SERVER['PHP_SELF']}\" method=\"post\">\n";
                echo "<table>\n";
                        echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n";
                }
                echo "<input type=\"hidden\" name=\"query\" value=\"", htmlspecialchars(serialize($_REQUEST['query'])), "\" />\n";
+               if (isset($_REQUEST['search_path'])) {
+                       echo "<input type=\"hidden\" name=\"search_path\" value=\"", htmlspecialchars($_REQUEST['search_path']), "\" />\n";
+               }
                echo $misc->form;
                echo "<input type=\"submit\" value=\"{$lang['strexport']}\" /></p>\n";
                echo "</form>\n";
index b4c9662f132ec6667243e837caf0406090d65c29..18cc0017a27dbcbe1ebda14bb7085260f00223e9 100644 (file)
@@ -3,7 +3,7 @@
         * Does an export of a database or a table (via pg_dump)
         * to the screen or as a download.
         *
-        * $Id: dbexport.php,v 1.20 2005/04/12 01:52:16 chriskl Exp $
+        * $Id: dbexport.php,v 1.21 2005/05/02 15:47:23 chriskl Exp $
         */
 
        // Prevent timeouts on large exports (non-safe mode only)
                }
 
                // Set environmental variables that pg_dump uses
-               putenv('PGPASSWORD=' . $_SESSION['webdbPassword']);
-               putenv('PGUSER=' . $_SESSION['webdbUsername']);
-               $hostname = $conf['servers'][$_SESSION['webdbServerID']]['host'];
+               $server_info = $misc->getServerInfo();          
+               putenv('PGPASSWORD=' . $server_info['password']);
+               putenv('PGUSER=' . $server_info['username']);
+               $hostname = $server_info['host'];
                if ($hostname !== null && $hostname != '') {
                        putenv('PGHOST=' . $hostname);
                }
-               $port = $conf['servers'][$_SESSION['webdbServerID']]['port'];
+               $port = $server_info['port'];
                if ($port !== null && $port != '') {
                        putenv('PGPORT=' . $port);
                }
-               if ($_REQUEST['mode'] == 'database') {
-                       putenv('PGDATABASE=' . $_REQUEST['database']);
-               }
 
-               // Check if we're doing a cluster-wide dump or just a per-database dump
-               if ($_REQUEST['mode'] == 'database') {
-                       // Get path of the pg_dump executable.
-                       $exe = $misc->escapeShellCmd($conf['servers'][$_SESSION['webdbServerID']]['pg_dump_path']);
-               }
-               else {
-                       // Get path of the pg_dumpall executable.
-                       $exe = $misc->escapeShellCmd($conf['servers'][$_SESSION['webdbServerID']]['pg_dumpall_path']);
-               }
+               // Are we doing a cluster-wide dump or just a per-database dump
+               $dumpall = ($_REQUEST['subject'] == 'server');
+               
+               // Get the path og the pg_dump/pg_dumpall executable
+               $exe = $misc->escapeShellCmd($server_info[$dumpall ? 'pg_dumpall_path' : 'pg_dump_path']);
                
                // Build command for executing pg_dump.  '-i' means ignore version differences.
                $cmd = $exe . " -i";
                
-               // Check for a table specified
-               if (isset($_REQUEST['table']) && $_REQUEST['mode'] == 'database') {
-                       
+               
+               // Check for a specified table/view
+               switch ($_REQUEST['subject']) {
+               case 'table':
+               case 'view':
                        // Obtain the pg_dump version number
                        $version = array();
                        preg_match("/(\d+(?:\.\d+)?)(?:\.\d+)?.*$/", exec($exe . " --version"), $version);
@@ -78,7 +74,7 @@
                        // set dump schema as well.  Also, mixed case dumping has been fixed
                        // then..
                        if (((float) $version[1]) >= 7.4) {
-                               $cmd .= " -t " . $misc->escapeShellArg($_REQUEST['table']);
+                               $cmd .= " -t " . $misc->escapeShellArg($_REQUEST[$_REQUEST['subject']]);
                                // Even though they're using a schema-enabled pg_dump, the backend database
                                // may not support schemas.
                                if ($data->hasSchemas()) {
                        else {
                                // This is an annoying hack needed to work around a bug in dumping
                                // mixed case tables in pg_dump prior to 7.4
-                               $cmd .= " -t " . $misc->escapeShellArg('"' . $_REQUEST['table'] . '"');
+                               $cmd .= " -t " . $misc->escapeShellArg('"' . $_REQUEST[$_REQUEST['subject']] . '"');
                        }
                }
 
                // Check for GZIP compression specified
-               if ($_REQUEST['output'] == 'gzipped' && $_REQUEST['mode'] == 'database') {
+               if ($_REQUEST['output'] == 'gzipped' && !$dumpall) {
                        $cmd .= " -Z 9";
                }
                                
                                if (isset($_REQUEST['sd_clean'])) $cmd .= ' -c';
                                break;
                }
+
+               if (!$dumpall) {
+                       putenv('PGDATABASE=' . $_REQUEST['database']);
+               }
                
                // Execute command and return the output to the screen
                passthru($cmd);
index 4ade61419e225d69bbfffb3a82f40d558f5abdec..fa335c1d3c2dbcf7ddeb94de7936beba29d3f8dd 100644 (file)
@@ -9,7 +9,7 @@
         * @param $return_desc The return link name
         * @param $page The current page
         *
-        * $Id: display.php,v 1.48 2005/03/04 02:27:38 chriskl Exp $
+        * $Id: display.php,v 1.49 2005/05/02 15:47:23 chriskl Exp $
         */
 
        // Prevent timeouts on large exports (non-safe mode only)
                        // Report views don't set a schema, so we need to disable create view in that case
                        if (isset($_REQUEST['schema'])) echo " | <a class=\"navlink\" href=\"views.php?action=create&amp;formDefinition=",
                                urlencode($_REQUEST['query']), "&amp;{$misc->href}\">{$lang['strcreateview']}</a>\n";
-                       echo " | <a class=\"navlink\" href=\"dataexport.php?query=",
-                                       urlencode($_REQUEST['query']), "&amp;{$misc->href}\">{$lang['strdownload']}</a>\n";     
+                       echo " | <a class=\"navlink\" href=\"dataexport.php?query=", urlencode($_REQUEST['query']);
+                       if (isset($_REQUEST['search_path']))
+                               echo "&amp;search_path=", urlencode($_REQUEST['search_path']);
+                       echo "&amp;{$misc->href}\">{$lang['strdownload']}</a>\n";
                }
 
                // Insert
index f9d5ef3a3f76f0439fdeac5428485bd6ccb585f8..aa1d33a5ae818a66a39d6548130841f4c24676d3 100644 (file)
@@ -3,7 +3,7 @@
        /**
         * Manage domains in a database
         *
-        * $Id: domains.php,v 1.19 2004/09/07 13:58:21 jollytoad Exp $
+        * $Id: domains.php,v 1.20 2005/05/02 15:47:23 chriskl Exp $
         */
 
        // Include application functions
                echo "<p><a class=\"navlink\" href=\"{$PHP_SELF}?action=create&amp;{$misc->href}\">{$lang['strcreatedomain']}</a></p>\n";
 
        }
+       
+       /**
+        * Generate XML for the browser tree.
+        */
+       function doTree() {
+               global $misc, $data, $PHP_SELF;
+               
+               $domains = &$data->getDomains();
+               
+               $reqvars = $misc->getRequestVars('domain');
+               
+               $attrs = array(
+                       'text'   => field('domname'),
+                       'icon'   => 'domains',
+                       'toolTip'=> field('domcomment'),
+                       'action' => url('domains.php',
+                                                       $reqvars,
+                                                       array(
+                                                               'action' => 'properties',
+                                                               'domain' => field('domname')
+                                                       )
+                                               )
+               );
+               
+               $misc->printTreeXML($domains, $attrs);
+               exit;
+       }
+       
+       if ($action == 'tree') doTree();
 
        $misc->printHeader($lang['strdomains']);
        $misc->printBody();
index ded185b8d4be025074745620f0d62716bdf17d8b..d24e0fad44b6817d50aa5f85136a125d40bb248a 100644 (file)
@@ -3,7 +3,7 @@
        /**
         * Manage functions in a database
         *
-        * $Id: functions.php,v 1.47 2004/09/18 11:59:40 soranzo Exp $
+        * $Id: functions.php,v 1.48 2005/05/02 15:47:23 chriskl Exp $
         */
 
        // Include application functions
                global $data, $conf, $misc, $func;
                global $PHP_SELF, $lang;
                
-               function fnPre(&$rowdata) {
-                       global $data;
-                       $rowdata->f['+proproto'] = $rowdata->f['proname'] . " (" . $rowdata->f['proarguments'] . ")";
-                       $rowdata->f['+proreturns'] = ($data->phpBool($rowdata->f['proretset']) ? 'setof ' : '') . $rowdata->f['proresult'];
-               }
-               
                $misc->printTrail('schema');
                $misc->printTabs('schema','functions');
                $misc->printMsg($msg);
                $columns = array(
                        'function' => array(
                                'title' => $lang['strfunction'],
-                               'field' => '+proproto',
+                               'field' => 'proproto',
                                'type'  => 'verbatim',
                        ),
                        'returns' => array(
                                'title' => $lang['strreturns'],
-                               'field' => '+proreturns',
+                               'field' => 'proreturns',
                                'type'  => 'verbatim',
                        ),
                        'proglanguage' => array(
                $actions = array(
                        'properties' => array(
                                'title' => $lang['strproperties'],
-                               'url'   => "redirect.php?section=function&action=properties&amp;{$misc->href}&amp;",
-                               'vars'  => array('function' => '+proproto', 'function_oid' => 'prooid'),
+                               'url'   => "redirect.php?subject=function&action=properties&amp;{$misc->href}&amp;",
+                               'vars'  => array('function' => 'proproto', 'function_oid' => 'prooid'),
                        ),
                        'alter' => array(
                                'title' => $lang['stralter'],
                                'url'   => "{$PHP_SELF}?action=edit&amp;{$misc->href}&amp;",
-                               'vars'  => array('function' => '+proproto', 'function_oid' => 'prooid'),
+                               'vars'  => array('function' => 'proproto', 'function_oid' => 'prooid'),
                        ),
                        'drop' => array(
                                'title' => $lang['strdrop'],
                                'url'   => "{$PHP_SELF}?action=confirm_drop&amp;{$misc->href}&amp;",
-                               'vars'  => array('function' => '+proproto', 'function_oid' => 'prooid'),
+                               'vars'  => array('function' => 'proproto', 'function_oid' => 'prooid'),
                        ),
                        'privileges' => array(
                                'title' => $lang['strprivileges'],
                                'url'   => "privileges.php?{$misc->href}&amp;subject=function&amp;",
-                               'vars'  => array('function' => '+proproto', 'function_oid' => 'prooid'),
+                               'vars'  => array('function' => 'proproto', 'function_oid' => 'prooid'),
                        ),
                );
                
-               $misc->printTable($funcs, $columns, $actions, $lang['strnofunctions'], 'fnPre');
+               $misc->printTable($funcs, $columns, $actions, $lang['strnofunctions']);
 
                echo "<p><a class=\"navlink\" href=\"{$PHP_SELF}?action=create&amp;{$misc->href}\">{$lang['strcreateplfunction']}</a> | ";
                echo "<a class=\"navlink\" href=\"{$PHP_SELF}?action=create&amp;language=internal&amp;{$misc->href}\">{$lang['strcreateinternalfunction']}</a> | ";
                echo "<a class=\"navlink\" href=\"{$PHP_SELF}?action=create&amp;language=C&amp;{$misc->href}\">{$lang['strcreatecfunction']}</a></p>\n";
        }
        
+       /**
+        * Generate XML for the browser tree.
+        */
+       function doTree() {
+               global $misc, $data;
+               
+               $funcs = &$data->getFunctions();
+               
+               $proto = concat(field('proname'),' (',field('proarguments'),')');
+               
+               $reqvars = $misc->getRequestVars('function');
+               
+               $attrs = array(
+                       'text'    => $proto,
+                       'icon'    => 'functions',
+                       'toolTip' => field('procomment'),
+                       'action'  => url('redirect.php',
+                                                       $reqvars,
+                                                       array(
+                                                               'action' => 'properties',
+                                                               'function' => $proto,
+                                                               'function_oid' => field('prooid')
+                                                       )
+                                               )
+               );
+               
+               $misc->printTreeXML($funcs, $attrs);
+               exit;
+       }
+       
+       if ($action == 'tree') doTree();
+       
        $misc->printHeader($lang['strfunctions']);
        $misc->printBody();
 
index 8ba7318e6dc08847abd4e846a5a705482c198354..870c59145c6bb4a4ceb8e49a07a273bccc7531fc 100644 (file)
@@ -3,7 +3,7 @@
        /**
         * Manage groups in a database cluster
         *
-        * $Id: groups.php,v 1.19 2004/09/07 13:58:21 jollytoad Exp $
+        * $Id: groups.php,v 1.20 2005/05/02 15:47:23 chriskl Exp $
         */
 
        // Include application functions
@@ -41,6 +41,7 @@
                        echo "<p>", sprintf($lang['strconfdropmember'], $misc->printVal($_REQUEST['user']), $misc->printVal($_REQUEST['group'])), "</p>\n";
                        
                        echo "<form action=\"{$PHP_SELF}\" method=\"post\">\n";
+                       echo $misc->form;
                        echo "<input type=\"hidden\" name=\"action\" value=\"drop_member\" />\n";
                        echo "<input type=\"hidden\" name=\"group\" value=\"", htmlspecialchars($_REQUEST['group']), "\" />\n";
                        echo "<input type=\"hidden\" name=\"user\" value=\"", htmlspecialchars($_REQUEST['user']), "\" />\n";
                echo "<input type=\"hidden\" name=\"action\" value=\"add_member\" />\n";
                echo "</form>\n";
                
-               echo "<p><a class=\"navlink\" href=\"$PHP_SELF\">{$lang['strshowallgroups']}</a></p>\n";
+               echo "<p><a class=\"navlink\" href=\"{$PHP_SELF}?{$misc->href}\">{$lang['strshowallgroups']}</a></p>\n";
        }
        
        /**
                        echo "<p>", sprintf($lang['strconfdropgroup'], $misc->printVal($_REQUEST['group'])), "</p>\n";
                        
                        echo "<form action=\"{$PHP_SELF}\" method=\"post\">\n";
+                       echo $misc->form;
                        echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n";
                        echo "<input type=\"hidden\" name=\"group\" value=\"", htmlspecialchars($_REQUEST['group']), "\" />\n";
                        echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n";
                $misc->printMsg($msg);
 
                echo "<form action=\"$PHP_SELF\" method=\"post\">\n";
+               echo $misc->form;
                echo "<table>\n";
                echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n";
                echo "\t\t<td class=\"data\"><input size=\"32\" maxlength=\"{$data->_maxNameLen}\" name=\"name\" value=\"", htmlspecialchars($_POST['name']), "\" /></td>\n\t</tr>\n";
                        echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strmembers']}</th>\n";
 
                        echo "\t\t<td class=\"data\">\n";
-                       echo "\t\t\t<select name=\"members[]\" multiple=\"multiple\" size=\"", min(6, $users->recordCount()), "\">\n";
+                       echo "\t\t\t<select name=\"members[]\" multiple=\"multiple\" size=\"", min(40, $users->recordCount()), "\">\n";
                        while (!$users->EOF) {
                                $username = $users->f['usename'];
                                echo "\t\t\t\t<option value=\"{$username}\"",
                
                $misc->printTable($groups, $columns, $actions, $lang['strnogroups']);
                
-               echo "<p><a class=\"navlink\" href=\"$PHP_SELF?action=create\">{$lang['strcreategroup']}</a></p>\n";
+               echo "<p><a class=\"navlink\" href=\"{$PHP_SELF}?action=create&amp;{$misc->href}\">{$lang['strcreategroup']}</a></p>\n";
 
        }
 
diff --git a/images/themes/default/I.png b/images/themes/default/I.png
new file mode 100644 (file)
index 0000000..f56e305
Binary files /dev/null and b/images/themes/default/I.png differ
diff --git a/images/themes/default/L.png b/images/themes/default/L.png
new file mode 100644 (file)
index 0000000..825498b
Binary files /dev/null and b/images/themes/default/L.png differ
diff --git a/images/themes/default/Lminus.png b/images/themes/default/Lminus.png
new file mode 100644 (file)
index 0000000..2ed7a19
Binary files /dev/null and b/images/themes/default/Lminus.png differ
diff --git a/images/themes/default/Lplus.png b/images/themes/default/Lplus.png
new file mode 100644 (file)
index 0000000..b50e9bb
Binary files /dev/null and b/images/themes/default/Lplus.png differ
diff --git a/images/themes/default/T.png b/images/themes/default/T.png
new file mode 100644 (file)
index 0000000..b127a8c
Binary files /dev/null and b/images/themes/default/T.png differ
diff --git a/images/themes/default/Tminus.png b/images/themes/default/Tminus.png
new file mode 100644 (file)
index 0000000..ca962d8
Binary files /dev/null and b/images/themes/default/Tminus.png differ
diff --git a/images/themes/default/Tplus.png b/images/themes/default/Tplus.png
new file mode 100644 (file)
index 0000000..0f9859d
Binary files /dev/null and b/images/themes/default/Tplus.png differ
diff --git a/images/themes/default/blank.png b/images/themes/default/blank.png
new file mode 100644 (file)
index 0000000..fa9a36d
Binary files /dev/null and b/images/themes/default/blank.png differ
diff --git a/images/themes/default/file.png b/images/themes/default/file.png
new file mode 100644 (file)
index 0000000..5e274c4
Binary files /dev/null and b/images/themes/default/file.png differ
diff --git a/images/themes/default/folder.png b/images/themes/default/folder.png
new file mode 100644 (file)
index 0000000..a65d031
Binary files /dev/null and b/images/themes/default/folder.png differ
diff --git a/images/themes/default/folderOpen.png b/images/themes/default/folderOpen.png
new file mode 100644 (file)
index 0000000..a13a2ed
Binary files /dev/null and b/images/themes/default/folderOpen.png differ
diff --git a/images/themes/default/loading.gif b/images/themes/default/loading.gif
new file mode 100644 (file)
index 0000000..f3f1963
Binary files /dev/null and b/images/themes/default/loading.gif differ
diff --git a/images/themes/default/root.png b/images/themes/default/root.png
new file mode 100644 (file)
index 0000000..a65d031
Binary files /dev/null and b/images/themes/default/root.png differ
index 2015f3075beb4dd8e7d1b7ebe74f183e27ee794f..99a58e3644e5d1d08c2e0d8a0ac6a7a1a2ec433a 100644 (file)
Binary files a/images/themes/default/title.png and b/images/themes/default/title.png differ
index 9e11a725b521f1b8f760fd99416f1697cedb921a..f506fcd3821cc995f684ace8743d8c6a1a5656b7 100755 (executable)
--- a/index.php
+++ b/index.php
@@ -3,33 +3,36 @@
        /**
         * Main access point to the app.
         *
-        * $Id: index.php,v 1.11 2004/07/12 04:18:40 chriskl Exp $
+        * $Id: index.php,v 1.12 2005/05/02 15:47:23 chriskl Exp $
         */
 
        // Include application functions
+       $_no_db_connection = true;
        include_once('./libraries/lib.inc.php');
        $misc->printHeader();
+       
+       $rtl = (strcasecmp($lang['applangdir'], 'rtl') == 0);
+       
+       $cols = $rtl ? '*,'.$conf['left_width'] : $conf['left_width'].',*';
+       $mainframe = '<frame src="intro.php" name="detail" id="detail" frameborder="0" />'
 ?>
-<frameset rows="52,*,12">
-       <frame src="topbar.php" name="topbar" scrolling="no" noresize="noresize" frameborder="0" />
-<?php if (strcasecmp($lang['applangdir'], 'rtl') == 0) : ?>    
-       <frameset cols="*,<?php echo $conf['left_width'] ?>">
-         <frame src="intro.php" name="detail" frameborder="0" />
-         <frame src="browser.php" name="browser" frameborder="0" />
-       </frameset>
-<?php else: ?>
-       <frameset cols="<?php echo $conf['left_width'] ?>,*">
-         <frame src="browser.php" name="browser" frameborder="0" />
-         <frame src="intro.php" name="detail" frameborder="0" />
-       </frameset>
-<?php endif; ?>
-       <frame src="bottombar.php" name="bottombar" scrolling="no" noresize="noresize" frameborder="0" />
+<frameset cols="<?php echo $cols ?>">
+
+<?php if ($rtl) echo $mainframe; ?>
+
+       <frame src="browser.php" name="browser" id="browser" frameborder="0" />
+
+<?php if (!$rtl) echo $mainframe; ?>
+
        <noframes>
        <body>
-               <?php echo $lang['strnoframes'] ?>
+               <?php echo $lang['strnoframes'] ?><br />
+               <a href="intro.php"><?php echo $lang['strnoframeslink'] ?></a>
        </body>
        </noframes>
+
 </frameset>
+
 <?php
        $misc->printFooter(false);
 ?>
index a3c1d7c73fc3a42abdf9851776fa7c4d02828025..06c33d38b3c90717a10d7372efd8011ed77b4e1e 100644 (file)
@@ -3,7 +3,7 @@
        /**
         * List indexes on a table
         *
-        * $Id: indexes.php,v 1.34 2004/09/07 13:58:21 jollytoad Exp $
+        * $Id: indexes.php,v 1.35 2005/05/02 15:47:23 chriskl Exp $
         */
 
        // Include application functions
                
                $misc->printTable($indexes, $columns, $actions, $lang['strnoindexes'], 'indPre');
                
-               echo "<p><a class=\"navlink\" href=\"$PHP_SELF?action=create_index&{$misc->href}&table=", urlencode($_REQUEST['table']), "\">{$lang['strcreateindex']}</a></p>\n";              
+               echo "<p><a class=\"navlink\" href=\"$PHP_SELF?action=create_index&amp;{$misc->href}&amp;table=", urlencode($_REQUEST['table']), "\">{$lang['strcreateindex']}</a></p>\n";              
        }
 
        $misc->printHeader($lang['strindexes'], "<script src=\"indexes.js\" type=\"text/javascript\"></script>");
index c0af8f466c9abeaaed4163dd3aa26beaac0ca5fb..5fcf36514277ec649b14948b5dc789e7f89cad74 100755 (executable)
--- a/intro.php
+++ b/intro.php
@@ -3,7 +3,7 @@
        /**
         * Intro screen
         *
-        * $Id: intro.php,v 1.14 2005/01/17 10:09:43 jollytoad Exp $
+        * $Id: intro.php,v 1.15 2005/05/02 15:47:24 chriskl Exp $
         */
 
        // Include application functions (no db conn)
        
        $misc->printHeader();
        $misc->printBody();
+       
+       $misc->printTrail('root');
+       $misc->printTabs('root','intro');
 ?>
 
 <h1><?php echo "$appName $appVersion (PHP ". phpversion() .')' ?></h1>
 
-<p><?php echo $lang['strintro'] ?></p>
-
-<ul>
-<li><b><a href="all_db.php"><?php echo $lang['strdatabases'] ?></a></b></li>
-<li><b><a href="http://phppgadmin.sourceforge.net/" target="_top"><?php echo $lang['strppahome'] ?></a></b></li>
-<li><b><a href="<?php echo $lang['strpgsqlhome_url'] ?>" target="_top"><?php echo $lang['strpgsqlhome'] ?></a></b></li>
+<form method="get" action="<?php echo $_SERVER['PHP_SELF'] ?>">
+ <label>
+  <select name="language" onchange="this.form.submit()">
 <?php
-       //if ( isset($conf['docdir'])) {
-       //      echo "<li><b><a href=\"". $conf['docdir'] ."\" target=\"_top\">";
-       //      echo $lang['strlocaldocs'] ."</a></b></li>";
-       //}
+       $language = isset($_SESSION['webdbLanguage']) ? $_SESSION['webdbLanguage'] : 'english';
+       foreach ($appLangFiles as $k => $v) {
+               echo "<option value=\"{$k}\"",
+                       ($k == $language) ? ' selected="selected"' : '',
+                       ">{$v}</option>\n";
+       }
 ?>
-<li><b><a href="http://sourceforge.net/tracker/?group_id=37132&amp;atid=418980" target="_top"><?php echo $lang['strreportbug'] ?></a></b></li>
-<li><b><a href="<?php echo $lang['strviewfaq_url'] ?>" target="_top"><?php echo $lang['strviewfaq'] ?></a></b></li>
+  </select>
+  <noscript><input type="submit" value="<?php echo $lang['stralter'] ?>" /></noscript>
+ </label>
+</form>
+
+<p><?php echo $lang['strintro'] ?></p>
+
+<ul class="intro">
+<li><a href="http://phppgadmin.sourceforge.net/" target="_top"><?php echo $lang['strppahome'] ?></a></li>
+<li><a href="<?php echo $lang['strpgsqlhome_url'] ?>" target="_top"><?php echo $lang['strpgsqlhome'] ?></a></li>
+<li><a href="http://sourceforge.net/tracker/?group_id=37132&amp;atid=418980" target="_top"><?php echo $lang['strreportbug'] ?></a></li>
+<li><a href="<?php echo $lang['strviewfaq_url'] ?>" target="_top"><?php echo $lang['strviewfaq'] ?></a></li>
 </ul>
 
 <?php
+       if (isset($_GET['language'])) $_reload_browser = true;
        $misc->printFooter();
 ?>
index b9ccfb0e1ca66773ff9f3712d8fe6ab4d8a3e23c..157b79207db0fd52f1f7fbdf939694a52327b2e7 100755 (executable)
@@ -4,7 +4,7 @@
         * English language file for phpPgAdmin.  Use this as a basis
         * for new translations.
         *
-        * $Id: english.php,v 1.174 2005/04/30 18:02:02 soranzo Exp $
+        * $Id: english.php,v 1.175 2005/05/02 15:47:27 chriskl Exp $
         */
 
        // Language and character set
        $lang['strloginfailed'] = 'Login failed';
        $lang['strlogindisallowed'] = 'Login disallowed for security reasons.';
        $lang['strserver'] = 'Server';
+       $lang['strservers'] = 'Servers';
+       $lang['strintroduction'] = 'Introduction';
+       $lang['strhost'] = 'Host';
+       $lang['strport'] = 'Port';
        $lang['strlogout'] = 'Logout';
        $lang['strowner'] = 'Owner';
        $lang['straction'] = 'Action';
        $lang['strfileimported'] = 'File imported.';
 
        // Error handling
-       $lang['strnoframes'] = 'You need a frames-enabled browser to use this application.';
+       $lang['strnoframes'] = 'This application works best with a frames-enabled browser, but can be used without frames by following the link below.';
+       $lang['strnoframeslink'] = 'Use without frames';
        $lang['strbadconfig'] = 'Your config.inc.php is out of date. You will need to regenerate it from the new config.inc.php-dist.';
        $lang['strnotloaded'] = 'Your PHP installation does not support PostgreSQL. You need to recompile PHP using the --with-pgsql configure option.';
        $lang['strpostgresqlversionnotsupported'] = 'Version of PostgreSQL not supported. Please upgrade to version %s or later.';
        $lang['strtimefmt'] = 'jS M, Y g:iA';
        $lang['strhelp'] = 'Help';
        $lang['strhelpicon'] = '?';
+       $lang['strlogintitle'] = 'Login to %s';
+       $lang['strlogoutmsg'] = 'Logged out of %s';
+       $lang['strloading'] = 'Loading...';
+       $lang['strerrorloading'] = 'Error Loading';
+       $lang['strclicktoreload'] = 'Click to reload';
 
 ?>
diff --git a/lang/translations.php b/lang/translations.php
new file mode 100644 (file)
index 0000000..4ff4d02
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+       /**
+        * Supported Translations for phpPgAdmin
+        *
+        * $Id: translations.php,v 1.2 2005/05/02 15:47:27 chriskl Exp $
+        */
+       
+       
+       // List of language files, and encoded language name.
+       
+       $appLangFiles = array(
+               'afrikaans' => 'Afrikaans',
+               'arabic' => '&#1593;&#1585;&#1576;&#1610;',
+               'chinese-tr' => '&#32321;&#39636;&#20013;&#25991;',
+               'chinese-sim' => '&#31616;&#20307;&#20013;&#25991;',
+               'czech' => '&#268;esky',
+               'danish' => 'Danish',
+               'dutch' => 'Nederlands',
+               'english' => 'English',
+               'french' => 'Fran&ccedil;ais',
+               'german' => 'Deutsch',
+               'hebrew' => 'Hebrew',
+               'italian' => 'Italiano',
+               'japanese' => '&#26085;&#26412;&#35486;',
+               'hungarian' => 'Magyar',
+               'mongol' => 'Mongolian',
+               'polish' => 'Polski',
+               'portuguese-br' => 'Portugu&ecirc;s-Brasileiro',
+               'romanian' => 'Rom&acirc;n&#259;',
+               'russian' => '&#1056;&#1091;&#1089;&#1089;&#1082;&#1080;&#1081;',
+               'slovak' => 'Slovensky',
+               'swedish' => 'Svenska',
+               'spanish' => 'Espa&ntilde;ol',
+               'turkish' => 'T&uuml;rk&ccedil;e',
+               'ukrainian' => '&#1059;&#1082;&#1088;&#1072;&#9558;&#1085;&#1089;&#1100;&#1082;&#1072;'
+       );
+       
+       
+       // ISO639 language code to language file mapping.
+       // See http://www.w3.org/WAI/ER/IG/ert/iso639.htm for language codes
+       
+       // If it's available 'language-country', but not general
+       // 'language' translation (eg. 'portuguese-br', but not 'portuguese')
+       // specify both 'la' => 'language-country' and 'la-co' => 'language-country'.
+       
+       $availableLanguages = array(
+               'af' => 'afrikaans',
+               'ar' => 'arabic',
+               'zh' => 'chinese-tr',
+               'zh-cn' => 'chinese-sim',
+               'cs' => 'czech',
+               'da' => 'danish',
+               'nl' => 'dutch',
+               'en' => 'english',
+               'fr' => 'french',
+               'de' => 'german',
+               'he' => 'hebrew',
+               'it' => 'italian',
+               'ja' => 'japanese',
+               'hu' => 'hungarian',
+               'mn' => 'mongol',
+               'pl' => 'polish',
+               'pt' => 'portuguese-br',
+               'pt-br' => 'portuguese-br',
+               'ro' => 'romanian',
+               'ru' => 'russian',
+               'sk' => 'slovak',
+               'sv' => 'swedish',
+               'es' => 'spanish',
+               'tr' => 'turkish',
+               'uk' => 'ukrainian'
+       );
+?>
diff --git a/libraries/decorator.inc.php b/libraries/decorator.inc.php
new file mode 100644 (file)
index 0000000..3427f37
--- /dev/null
@@ -0,0 +1,206 @@
+<?php
+// $Id: decorator.inc.php,v 1.2 2005/05/02 15:47:28 chriskl Exp $
+
+// This group of functions and classes provides support for
+// resolving values in a lazy manner (ie, as and when required)
+// using the Decorator pattern.
+
+###TODO: Better documentation!!!
+
+// Construction functions:
+
+function field($fieldName, $default = null) {
+       return new FieldDecorator($fieldName, $default);
+}
+
+function merge(/* ... */) {
+       return new ArrayMergeDecorator(func_get_args());
+}
+
+function concat(/* ... */) {
+       return new ConcatDecorator(func_get_args());
+}
+
+function callback($callback, $params = null) {
+       return new CallbackDecorator($callback, $params);
+}
+
+function ifempty($value, $empty, $full = null) {
+       return new IfEmptyDecorator($value, $empty, $full);
+}
+
+function url($base, $vars = null /* ... */) {
+       // If more than one array of vars is given,
+       // use an ArrayMergeDecorator to have them merged
+       // at value evaluation time.
+       if (func_num_args() > 2) {
+               $v = func_get_args();
+               array_shift($v);
+               return new UrlDecorator($base, new ArrayMergeDecorator($v));
+       }
+       return new UrlDecorator($base, $vars);
+}
+
+function noEscape($value) {
+       if (is_a($value, 'Decorator')) {
+               $value->esc = false;
+               return $value;
+       }
+       return new Decorator($value, false);
+}
+
+// Resolving functions:
+
+function value(&$var, &$fields, $esc = null) {
+       if (is_a($var, 'Decorator')) {
+               $val =& $var->value($fields);
+               if (!$var->esc) $esc = null;
+       } else {
+               $val =& $var;
+       }
+       if (is_string($val)) {
+               switch($esc) {
+                       case 'xml':
+                               return strtr($val, array(
+                                       '&' => '&amp;',
+                                       "'" => '&apos;', '"' => '&quot;',
+                                       '<' => '&lt;', '>' => '&gt;'
+                               ));
+                       case 'html':
+                               return htmlspecialchars($val);
+                       case 'url':
+                               return urlencode($val);
+               }
+       }
+       return $val;
+}
+
+function value_xml(&$var, &$fields) {
+       return value($var, $fields, 'xml');
+}
+
+function value_xml_attr($attr, &$var, &$fields) {
+       $val = value($var, $fields, 'xml');
+       if (!empty($val))
+               return " {$attr}=\"{$val}\"";
+       else
+               return '';
+}
+
+function value_url(&$var, &$fields) {
+       return value($var, $fields, 'url');
+}
+
+// Underlying classes:
+
+class Decorator
+{
+       var $esc = true;
+       
+       function Decorator($value, $esc = true) {
+               $this->v = $value;
+               $this->esc = $esc;
+       }
+       
+       function value() {
+               return $this->v;
+       }
+}
+
+class FieldDecorator extends Decorator
+{
+       function FieldDecorator($fieldName, $default = null) {
+               $this->f = $fieldName;
+               if ($default !== null) $this->d = $default;
+       }
+       
+       function value($fields) {
+               return isset($fields[$this->f]) ? $fields[$this->f] : (isset($this->d) ? $this->d : null);
+       }
+}
+
+class ArrayMergeDecorator extends Decorator
+{
+       function ArrayMergeDecorator($arrays) {
+               $this->m = $arrays;
+       }
+       
+       function value($fields) {
+               $accum = array();
+               foreach($this->m as $var) {
+                       $accum = array_merge($accum, value($var, $fields));
+               }
+               return $accum;
+       }
+}
+
+class ConcatDecorator extends Decorator
+{
+       function ConcatDecorator($values) {
+               $this->c = $values;
+       }
+       
+       function value($fields) {
+               $accum = '';
+               foreach($this->c as $var) {
+                       $accum .= value($var, $fields);
+               }
+               return $accum;
+       }
+}
+
+class CallbackDecorator extends Decorator
+{
+       function CallbackDecorator($callback, $param = null) {
+               $this->fn = $callback;
+               $this->p = $param;
+       }
+       
+       function value($fields) {
+               return call_user_func($this->fn, $fields, $this->p);
+       }
+}
+
+class IfEmptyDecorator extends Decorator
+{
+       function IfEmptyDecorator($value, $empty, $full = null) {
+               $this->v = $value;
+               $this->e = $empty;
+               if ($full !== null) $this->f = $full;
+       }
+       
+       function value($fields) {
+               $val = value($this->v, $fields);
+               if (empty($val))
+                       return value($this->e, $fields);
+               else
+                       return isset($this->f) ? value($this->f, $fields) : $val;
+       }
+}
+
+class UrlDecorator extends Decorator
+{
+       function UrlDecorator($base, $queryVars = null) {
+               $this->b = $base;
+               if ($queryVars !== null)
+                       $this->q = $queryVars;
+       }
+       
+       function value($fields) {
+               $url = value($this->b, $fields);
+               
+               if ($url === false) return '';
+               
+               if (!empty($this->q)) {
+                       $queryVars = value($this->q, $fields);
+                       
+                       $sep = '?';
+                       foreach ($queryVars as $var => $value) {
+                               $url .= $sep . value_url($var, $fields) . '=' . value_url($value, $fields);
+                               $sep = '&';
+                       }
+               }
+               return $url;
+       }
+}
+?>
index 2e7b1d0e4514151179faf5b4f88291db8eb718bb..5afdaeb2a90f981b2c158d7fd2fa22d33342df91 100644 (file)
@@ -3,7 +3,7 @@
 /**
  * Overrides default ADODB error handler to provide nicer error handling.
  *
- * $Id: errorhandler.inc.php,v 1.16 2004/07/19 03:01:54 chriskl Exp $
+ * $Id: errorhandler.inc.php,v 1.17 2005/05/02 15:47:28 chriskl Exp $
  */
 
 define('ADODB_ERROR_HANDLER','Error_Handler');
@@ -38,6 +38,8 @@ function Error_Handler($dbms, $fn, $errno, $errmsg, $p1=false, $p2=false)
        case 'PCONNECT':
        case 'CONNECT':
                $_failed = true;
+               unset($_SESSION['webdbLogin'][$_REQUEST['server']]);
+               $msg = $lang['strloginfailed'];
                include('./login.php');
                exit;
                break;
index f18c1283bad430bf5bbcc9e2c49313d042e70316..79ab471370b4aa2cbaa3265ce6c08bc278b4c7b0 100644 (file)
@@ -3,8 +3,10 @@
        /**
         * Function library read in upon startup
         *
-        * $Id: lib.inc.php,v 1.93 2005/03/16 01:49:11 chriskl Exp $
+        * $Id: lib.inc.php,v 1.94 2005/05/02 15:47:28 chriskl Exp $
         */
+       include_once('decorator.inc.php');
+       include_once('./lang/translations.php');
        
        // Set error reporting level to max
        error_reporting(E_ALL);
        // backwards incompatible changes are made to config.inc.php-dist.
        $conf['base_version'] = 14;
 
-       // List of available language files.  Remember to update login.php
-       // when you update this list.
-       $appLangFiles = array(
-               'afrikaans' => 'Afrikaans',
-               'arabic' => '&#1593;&#1585;&#1576;&#1610;',
-               'chinese-tr' => '&#32321;&#39636;&#20013;&#25991;',
-               'chinese-sim' => '&#31616;&#20307;&#20013;&#25991;',
-               'czech' => '&#268;esky',
-               'danish' => 'Danish',
-               'dutch' => 'Nederlands',
-               'english' => 'English',
-               'french' => 'Fran&ccedil;ais',
-               'german' => 'Deutsch',
-               'hebrew' => 'Hebrew',
-               'italian' => 'Italiano',
-               'japanese' => '&#26085;&#26412;&#35486;',
-               'hungarian' => 'Magyar',
-               'mongol' => 'Mongolian',
-               'polish' => 'Polski',
-               'portuguese-br' => 'Portugu&ecirc;s-Brasileiro',
-               'portuguese-pt' => 'Portugu&ecirc;s-Portugu&ecirc;s',
-               'romanian' => 'Rom&acirc;n&#259;',
-               'russian' => '&#1056;&#1091;&#1089;&#1089;&#1082;&#1080;&#1081;',
-               'slovak' => 'Slovensky',
-               'swedish' => 'Svenska',
-               'spanish' => 'Espa&ntilde;ol',
-               'turkish' => 'T&uuml;rk&ccedil;e',
-               'ukrainian' => '&#1059;&#1082;&#1088;&#1072;&#9558;&#1085;&#1089;&#1100;&#1082;&#1072;'
-       );
-
        // Always include english.php, since it's the master language file
        if (!isset($conf['default_lang'])) $conf['default_lang'] = 'english';
        $lang = array();
        ini_set('arg_separator.output', '&amp;');
        
        // If login action is set, then set session variables
-       if (isset($_POST['formServer']) && isset($_POST['formUsername']) && 
-               isset($_POST['formPassword']) && isset($_POST['formLanguage'])) {
-               $_SESSION['webdbServerID'] = $_POST['formServer'];
-               $_SESSION['webdbUsername'] = $_POST['formUsername'];
-               $_SESSION['webdbPassword'] = $_POST['formPassword'];
-               $_SESSION['webdbLanguage'] = $_POST['formLanguage'];
+       if (isset($_POST['loginServer']) && isset($_POST['loginUsername']) && 
+               isset($_POST['loginPassword'])) {
+               
+               $_server_info = $misc->getServerInfo($_POST['loginServer']);
+               
+               $_server_info['username'] = $_POST['loginUsername'];
+               $_server_info['password'] = $_POST['loginPassword'];
+               
+               $misc->setServerInfo(null, $_server_info, $_POST['loginServer']);
+               
+               $_reload_browser = true;
        }
 
-       // If the logged in settings aren't present, put up the login screen.
-       if (!isset($_SESSION['webdbUsername'])
-                       ||      !isset($_SESSION['webdbPassword'])
-                       ||      !isset($_SESSION['webdbServerID'])
-                       ||      !isset($_SESSION['webdbLanguage'])
-                       ||      !isset($conf['servers'][$_SESSION['webdbServerID']])) {
-               include('./login.php');
-               exit;
+       // Determine language file to import:
+       
+       // 1. Check for the language from a request var
+       if (isset($_REQUEST['language'])) {
+               $_language = strtolower($_REQUEST['language']);
+               if (!isset($appLangFiles[$_language]))
+                       unset($_language);
        }
-
-       // Import language file
-       include('./lang/recoded/' . strtolower($_SESSION['webdbLanguage']) . '.php');
-
-       // If extra login check fails, back to the login screen
-       $_allowed = $misc->checkExtraSecurity();
-       if (!$_allowed) {
-               include('./login.php');
-               exit;
+       
+       // 2. Check for language session var
+       if (!isset($_language) && isset($_SESSION['webdbLanguage']) && isset($appLangFiles[$_SESSION['webdbLanguage']])) {
+               $_language = $_SESSION['webdbLanguage'];
+       }
+       
+       // 3. Check for acceptable languages in HTTP_ACCEPT_LANGUAGE var
+       if (!isset($_language) && isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
+               // extract acceptable language tags
+               // (http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4)
+               preg_match_all('/\s*([a-z]{1,8}(?:-[a-z]{1,8})*)(?:;q=([01](?:.[0-9]{0,3})?))?\s*(?:,|$)/', strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE']), $_m, PREG_SET_ORDER);
+               foreach($_m as $_l) {  // $_l[1] = language tag, [2] = quality
+                       if (!isset($_l[2])) $_l[2] = 1;  // Default quality to 1
+                       if ($_l[2] > 0 && $_l[2] <= 1 && isset($availableLanguages[$_l[1]])) {
+                               // Build up array of (quality => language_file)
+                               $_acceptLang[$_l[2]] = $availableLanguages[$_l[1]];
+                       }
+               }
+               unset($_m);
+               unset($_l);
+               if (isset($_acceptLang)) {
+                       // Sort acceptable languages by quality
+                       krsort($_acceptLang, SORT_NUMERIC);
+                       $_language = reset($_acceptLang);
+                       unset($_acceptLang);
+               }
+       }
+       
+       // 4. Otherwise resort to the default set in the config file
+       if (!isset($_language) && isset($appLangFiles[$conf['default_lang']])) {
+               $_language = $conf['default_lang'];
+       }
+       
+       // Import the language file
+       if (isset($_language)) {
+               include("./lang/recoded/{$_language}.php");
+               $_SESSION['webdbLanguage'] = $_language;
        }
 
        // Check database support is properly compiled in
 
        // Create data accessor object, if necessary
        if (!isset($_no_db_connection)) {
+               if (!isset($_REQUEST['server'])) {
+                       die('No server supplied!');
+                       # TODO: nice error
+               }
+               
+               $_server_info = $misc->getServerInfo();
+               
+               // Redirect to the login form if not logged in
+               if (!isset($_server_info['username'])) {
+                       include('./login.php');
+                       exit;
+               }
+               
                // Connect to the current database, or if one is not specified
                // then connect to the default database.
                if (isset($_REQUEST['database']))
                        $_curr_db = $_REQUEST['database'];
                else
-                       $_curr_db = $conf['servers'][$_SESSION['webdbServerID']]['defaultdb'];
+                       $_curr_db = $_server_info['defaultdb'];
 
-               // Create the connection object and make the connection
                include_once('./classes/database/Connection.php');
-               $_connection = new Connection(
-                       $conf['servers'][$_SESSION['webdbServerID']]['host'],
-                       $conf['servers'][$_SESSION['webdbServerID']]['port'],
-                       $_SESSION['webdbUsername'],
-                       $_SESSION['webdbPassword'],
-                       $_curr_db
-               );
-
-               // Get the name of the database driver we need to use.  The description
-               // of the server is returned and placed into the conf array.
-               $_type = $_connection->getDriver($conf['description']);
-               if ($_type === null) {
-                       printf($lang['strpostgresqlversionnotsupported'], $postgresqlMinVer);
-                       exit;
-               }
-
-               // Create a database wrapper class for easy manipulation of the
-               // connection.
-               require_once('./classes/database/' . $_type . '.php');
-               $data = new $_type($_connection->conn);
-               $data->platform = $_connection->platform;
+               
+               // Connect to database and set the global $data variable
+               $data =& $misc->getDatabaseAccessor($_curr_db);
 
                // If schema is defined and database supports schemas, then set the 
                // schema explicitly.
index 19229a213914f114e32c1c229585c01a14aa9c63..ab115f3f92598c3443ae3507e30c40fe5350cf59 100755 (executable)
--- a/login.php
+++ b/login.php
        /**
         * Login screen
         *
-        * $Id: login.php,v 1.24 2005/03/16 01:48:59 chriskl Exp $
+        * $Id: login.php,v 1.25 2005/05/02 15:47:24 chriskl Exp $
         */
 
        // This needs to be an include once to prevent lib.inc.php infinite recursive includes.
        // Check to see if the configuration file exists, if not, explain
        require_once('./libraries/lib.inc.php');
+       
+       $misc->printHeader($lang['strlogin']);
+       $misc->printBody();
+       $misc->printTrail('root');
+       
+       $server_info = $misc->getServerInfo($_REQUEST['server']);
+       
+       $misc->printTitle(sprintf($lang['strlogintitle'], $server_info['desc']));
+       
+       $loginServer = htmlspecialchars($_REQUEST['server']);
+       $loginUsername = '';
+       
+       if (isset($msg)) $misc->printMsg($msg);
+?>
 
-       // Prepare form variables
-       if (!isset($_POST['formServer'])) $_POST['formServer'] = '';
-       if (!isset($_POST['formLanguage'])) {
-               // Parse the user acceptable language in HTTP_ACCEPT_LANGUAGE
-               // ( http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4 )
-               // If there's one available, then overwrite the default language.
-               if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
-                       $userLanguage = '';
-                       $userLanguages = array();
-                       $acceptableLanguages = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
-                       foreach ($acceptableLanguages as $accLang) {
-                               $languageInfos = explode(';', trim($accLang));
-                               $languageRange = strtolower($languageInfos[0]);
-                               if (isset($languageInfos[1]) && substr($languageInfos[1], 0, 2) == 'q=')
-                                       $languageQuality = (float)substr($languageInfos[1], 2, 5);
-                               else
-                                       $languageQuality = 1;
-                               // If the language is already in the array, check that we
-                               // don't overwrite its quality value with a lower one
-                               if ((!array_key_exists($languageRange, $userLanguages))
-                                       || ($userLanguages[$languageRange] < $languageQuality))
-                                       $userLanguages[$languageRange] = $languageQuality;
-                       }
-                       arsort($userLanguages, SORT_NUMERIC);
-
-                       // if it's available 'language-country', but not general 'language' translation
-                       // (eg. 'portuguese-br', but not 'portuguese')
-                       // specify both 'la' => 'language-country' and 'la-co' => 'language-country'.
-                       // See http://www.w3.org/WAI/ER/IG/ert/iso639.htm for language codes
-                       $availableLanguages = array(
-                               'af' => 'afrikaans',
-                               'ar' => 'arabic',
-                               'zh' => 'chinese-tr',
-                               'zh-cn' => 'chinese-sim',
-                               'cs' => 'czech',
-                               'da' => 'danish',
-                               'nl' => 'dutch',
-                               'en' => 'english',
-                               'fr' => 'french',
-                               'de' => 'german',
-                               'he' => 'hebrew',
-                               'it' => 'italian',
-                               'ja' => 'japanese',
-                               'hu' => 'hungarian',
-                               'mn' => 'mongol',
-                               'pl' => 'polish',
-                               'pt' => 'portuguese-pt',
-                               'pt-br' => 'portuguese-br',
-                               'pt-pt' => 'portuguese-pt',
-                               'ro' => 'romanian',
-                               'ru' => 'russian',
-                               'sk' => 'slovak',
-                               'sv' => 'swedish',
-                               'es' => 'spanish',
-                               'tr' => 'turkish',
-                               'uk' => 'ukrainian'
-                       );
-
-                       reset($userLanguages);
-                       do {
-                               $languageRange = key($userLanguages);
-                               if (array_key_exists($languageRange, $availableLanguages)) {
-                                       $userLanguage = $availableLanguages[$languageRange];
-                               }
-                       } while ($userLanguage == '' && next($userLanguages));
-                       if ($userLanguage != '') $conf['default_lang'] = $userLanguage;
-               }
-               $_POST['formLanguage'] = $conf['default_lang'];
-               // Include default language over english.
-               include_once('./lang/recoded/' . strtolower($conf['default_lang']) . '.php');
-       }
-
-       // Check for config file version mismatch
-       if (!isset($conf['version']) || $conf['base_version'] > $conf['version']) {
-               echo $lang['strbadconfig'];
-               exit;
-       }
-
-       // Force encoding to UTF-8
-       $lang['appcharset'] = 'UTF-8';
-
-       // Output header
-       if (isset($_failed) && $_failed) {
-               $misc->printHeader($lang['strlogin'], "<script type=\"text/javascript\"><!--
-       // show login form in top frame
-       if (top != self) {
-               window.top.location.href='./index.php?{$_SERVER['QUERY_STRING']}';
-       }
-       //-->
-</script>");
-       } else {
-               $misc->printHeader($lang['strlogin']);
+<form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post" name="login_form">
+<?php
+       if (!empty($_POST)) $vars =& $_POST;
+       else $vars =& $_GET;
+       // Pass request vars through form (is this a security risk???)
+       foreach ($vars as $key => $val) {
+               if (substr($key,0,5) == 'login') continue;
+               echo "<input type=\"hidden\" name=\"", htmlspecialchars($key), "\" value=\"", htmlspecialchars($val), "\" />\n";
        }
-       $misc->printBody();
 ?>
+ <input type="hidden" name="loginServer" value="<?php echo $loginServer; ?>" />
+ <table class="navbar" border="0" cellpadding="5" cellspacing="3">
+  <tr>
+   <td><?php echo $lang['strusername']; ?></td>
+   <td><input type="text" name="loginUsername" value="<?php echo $loginUsername; ?>" size="24" /></td>
+  </tr>
+  <tr>
+   <td><?php echo $lang['strpassword']; ?></td>
+   <td><input type="password" name="loginPassword" size="24" /></td>
+  </tr>
+ </table>
+ <p><input type="submit" name="loginSubmit" value="<?php echo $lang['strlogin']; ?>" /></p>
+</form>
 
-       <table class="navbar" border="0" cellpadding="0" cellspacing="0" style="width: 100%; height: 100%">
-               <tr>
-                       <td height="115" align="center" valign="middle">
-                               <center>
-                               <h1><?php echo $appName ?> <?php echo $appVersion ?> <?php echo $lang['strlogin'] ?></h1>                               
-                               <?php 
-                                       if (isset($_failed) && $_failed) 
-                                               echo "<p class=\"message\">{$lang['strloginfailed']}</p>";
-                                       elseif (isset($_allowed) && !$_allowed) {
-                                               echo "<p class=\"message\">{$lang['strlogindisallowed']}\n";
-                                               echo "<br /><a href=\"{$lang['strviewfaq_url']}\">{$lang['strviewfaq']}</a></p>";
-                                       }
-                               ?>
-                               <form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post" name="login_form">
-                               <table class="navbar" border="0" cellpadding="5" cellspacing="3">
-                                       <tr>
-                                               <th><?php echo $lang['strusername'] ?>:</th>
-                                               <td><input type="text" name="formUsername" value="<?php echo (isset($_POST['formUsername'])) ? htmlspecialchars($_POST['formUsername']) : '' ?>" size="24" /></td>
-                                       </tr>
-                                       <tr>
-                                               <th><?php echo $lang['strpassword'] ?>:</th>
-                                               <td><input type="password" name="formPassword" size="24" /></td>
-                                       </tr>
-                                       <tr>
-                                               <th><?php echo $lang['strserver'] ?>:</th>
-                                               <td><select name="formServer">
-                                               <?php
-                                                       for ($i = 0; $i < sizeof($conf['servers']); $i++) {
-                                                               echo "<option value=\"{$i}\"",
-                                                                       ($i == $_POST['formServer']) ? ' selected="selected"' : '',
-                                                                       ">", htmlspecialchars($conf['servers'][$i]['desc']), "</option>\n";
-                                                       }
-                                               ?>
-                                               </select></td>
-                                       </tr>
-                                       <tr>
-                                               <th><?php echo $lang['strlanguage'] ?>:</th>
-                                               <td><select name="formLanguage">
-                                               <?php
-                                                       // Language name already encoded
-                                                       foreach ($appLangFiles as $k => $v) {
-                                                               echo "<option value=\"{$k}\"",
-                                                                       ($k == $_POST['formLanguage']) ? ' selected="selected"' : '',
-                                                                       ">{$v}</option>\n";
-                                                       }
-                                               ?>
-                                               </select></td>
-                                       </tr>
-                               </table>
-                               <p><input type="submit" name="submitLogin" value="<?php echo $lang['strlogin'] ?>" /></p>
-                               </form>
-                               </center>
-                               <script type="text/javascript">
-                               <!--
-                                       var uname = document.login_form.formUsername;
-                                       var pword = document.login_form.formPassword;
-                                       if (uname.value == "") {
-                                               uname.focus();
-                                       } else {
-                                               pword.focus();
-                                       }
-                               //-->
-                               </script>
-                       </td>
-               </tr>
-       </table>
 <?php
        // Output footer
        $misc->printFooter();
index 9924358264b1ac7f3fa109cc96dca3b92737df2a..5db505738aa0688ad316482be3f9a5bfc32438f3 100644 (file)
@@ -3,7 +3,7 @@
        /**
         * Manage opclasss in a database
         *
-        * $Id: opclasses.php,v 1.6 2004/09/01 16:35:59 jollytoad Exp $
+        * $Id: opclasses.php,v 1.7 2005/05/02 15:47:24 chriskl Exp $
         */
 
        // Include application functions
                
                $misc->printTable($opclasses, $columns, $actions, $lang['strnoopclasses']);
        }
-
+       
+       /**
+        * Generate XML for the browser tree.
+        */
+       function doTree() {
+               global $misc, $data;
+               
+               $opclasses = &$data->getOpClasses();
+               
+               // OpClass prototype: "op_class/access_method"
+               $proto = concat(field('opcname'),'/',field('amname'));
+               
+               $attrs = array(
+                       'text'   => $proto,
+                       'icon'   => 'operators',
+                       'toolTip'=> field('opccomment'),
+               );
+               
+               $misc->printTreeXML($opclasses, $attrs);
+               exit;
+       }
+       
+       if ($action == 'tree') doTree();
+       
        $misc->printHeader($lang['stropclasses']);
        $misc->printBody();
 
index 75300e269816d865b4618c11650df10ffee3ba58..5130a8154eb22b3630a56ad487da4459bb63bef9 100644 (file)
@@ -3,7 +3,7 @@
        /**
         * Manage operators in a database
         *
-        * $Id: operators.php,v 1.17 2004/09/07 13:58:21 jollytoad Exp $
+        * $Id: operators.php,v 1.18 2005/05/02 15:47:24 chriskl Exp $
         */
 
        // Include application functions
 //             echo "<p><a class=\"navlink\" href=\"$PHP_SELF?action=create&amp;{$misc->href}\">{$lang['strcreateoperator']}</a></p>\n";
        }
 
+       /**
+        * Generate XML for the browser tree.
+        */
+       function doTree() {
+               global $misc, $data, $PHP_SELF;
+               
+               $operators = &$data->getOperators();
+               
+               // Operator prototype: "type operator type"
+               $proto = concat(field('oprleftname'), ' ', field('oprname'), ' ', field('oprrightname'));
+               
+               // Alternative prototype: "operator (type,type)"
+               #$proto = concat(field('oprname'), ' (', field('oprleftname','NONE'), ',', field('oprrightname','NONE'), ')');
+               
+               $reqvars = $misc->getRequestVars('operator');
+               
+               $attrs = array(
+                       'text'   => $proto,
+                       'icon'   => 'operators',
+                       'toolTip'=> field('oprcomment'),
+                       'action' => url('operators.php',
+                                                       $reqvars,
+                                                       array(
+                                                               'action'  => 'properties',
+                                                               'operator' => $proto,
+                                                               'operator_oid' => field('oid')
+                                                       )
+                                               )
+               );
+               
+               $misc->printTreeXML($operators, $attrs);
+               exit;
+       }
+       
+       if ($action == 'tree') doTree();
+       
        $misc->printHeader($lang['stroperators']);
        $misc->printBody();
 
index b864a315627415710cd5ba1ddc51ec69160dcddf..2e07187f6fbc1820dd0cff1245b1a967c965041c 100644 (file)
@@ -1,7 +1,12 @@
 <?php
+       $subject = isset($_REQUEST['subject']) ? $_REQUEST['subject'] : 'root'; 
+       
+       if ($subject == 'root')
+               $_no_db_connection = true;
+       
        include_once('./libraries/lib.inc.php');
        
-       $url = parse_url($misc->getLastTabURL($_REQUEST['section']));
+       $url = parse_url($misc->getLastTabURL($subject));
        
        $_SERVER['PHP_SELF'] = $url['path'];
        
index df78fe6c00c60d9e78e381c351b6581c491d22fa..05a24b3dbfe5defabe1ad2020fabff72894be174 100644 (file)
@@ -3,7 +3,7 @@
        /**
         * List reports in a database
         *
-        * $Id: reports.php,v 1.19 2004/09/02 13:53:56 jollytoad Exp $
+        * $Id: reports.php,v 1.20 2005/05/02 15:47:24 chriskl Exp $
         */
 
        // Include application functions
@@ -37,6 +37,7 @@
                $misc->printMsg($msg);
 
                echo "<form action=\"$PHP_SELF\" method=\"post\">\n";
+               echo $misc->form;
                echo "<table width=\"100%\">\n";
                echo "<tr><th class=\"data left required\">{$lang['strname']}</th>\n";
                echo "<td class=\"data1\"><input name=\"report_name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"",
                }
                else echo "<p>{$lang['strinvalidparam']}</p>\n";
 
-               echo "<p><a class=\"navlink\" href=\"$PHP_SELF\">{$lang['strshowallreports']}</a> |\n";
-               echo "<a class=\"navlink\" href=\"$PHP_SELF?action=edit&amp;report_id={$report->f['report_id']}\">{$lang['stredit']}</a></p>\n";
+               echo "<p><a class=\"navlink\" href=\"{$PHP_SELF}?{$misc->href}\">{$lang['strshowallreports']}</a> |\n";
+               echo "<a class=\"navlink\" href=\"$PHP_SELF?action=edit&amp;{$misc->href}&amp;report_id={$report->f['report_id']}\">{$lang['stredit']}</a></p>\n";
        }
 
        /**
                $misc->printMsg($msg);
 
                echo "<form action=\"$PHP_SELF\" method=\"post\">\n";
+               echo $misc->form;
                echo "<table width=\"100%\">\n";
                echo "<tr><th class=\"data left required\">{$lang['strname']}</th>\n";
                echo "<td class=\"data1\"><input name=\"report_name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"",
                        echo "<p>", sprintf($lang['strconfdropreport'], $misc->printVal($report->f['report_name'])), "</p>\n";
 
                        echo "<form action=\"$PHP_SELF\" method=\"post\">\n";
+                       echo $misc->form;
                        echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n";
                        echo "<input type=\"hidden\" name=\"report_id\" value=\"", htmlspecialchars($_REQUEST['report_id']), "\" />\n";
                        echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n";
                global $PHP_SELF, $lang;
 
                $misc->printTrail('server');
-               $misc->printTitle($lang['strreports']);
+               $misc->printTabs('server','reports');
                $misc->printMsg($msg);
                
                $reports = &$reportsdb->getReports();
                        ),
                );
                
+               $return_url = urlencode("{$PHP_SELF}?{$misc->href}");
+               
                $actions = array(
                        'properties' => array(
                                'title' => $lang['strproperties'],
-                               'url'   => "{$PHP_SELF}?action=properties&amp;",
+                               'url'   => "{$PHP_SELF}?action=properties&amp;{$misc->href}&amp;",
                                'vars'  => array('report_id' => 'report_id'),
                        ),
                        'run' => array(
                                'title' => $lang['strrun'],
-                               'url'   => "display.php?subject=report&amp;return_url={$PHP_SELF}&amp;return_desc=".urlencode($lang['strback'])."&amp;",
+                               'url'   => "display.php?subject=report&amp;{$misc->href}&amp;return_url={$return_url}&amp;return_desc=".urlencode($lang['strback'])."&amp;",
                                'vars'  => array('report' => 'report_name', 'database' => 'db_name', 'query' => 'report_sql'),
                        ),
                        'edit' => array(
                                'title' => $lang['stredit'],
-                               'url'   => "{$PHP_SELF}?action=edit&amp;",
+                               'url'   => "{$PHP_SELF}?action=edit&amp;{$misc->href}&amp;",
                                'vars'  => array('report_id' => 'report_id'),
                        ),
                        'drop' => array(
                                'title' => $lang['strdrop'],
-                               'url'   => "{$PHP_SELF}?action=confirm_drop&amp;",
+                               'url'   => "{$PHP_SELF}?action=confirm_drop&amp;{$misc->href}&amp;",
                                'vars'  => array('report_id' => 'report_id'),
                        ),
                );
                
                $misc->printTable($reports, $columns, $actions, $lang['strnoreports']);
                
-               echo "<p><a class=\"navlink\" href=\"$PHP_SELF?action=create\">{$lang['strcreatereport']}</a></p>\n";
+               echo "<p><a class=\"navlink\" href=\"{$PHP_SELF}?action=create&amp;{$misc->href}\">{$lang['strcreatereport']}</a></p>\n";
        }
        
        $misc->printHeader($lang['strreports']);
        include_once('./classes/Reports.php');
        $reportsdb = new Reports($status);
        if ($status != 0) {
-               echo "<p>{$lang['strnoreportsdb']}</p>\n";
+               $misc->printTrail('server');
+               $misc->printTabs('server','reports');
+               $misc->printMsg($lang['strnoreportsdb']);
        }
        else {
                switch ($action) {
index ac4a8096d2c1ce0fba3194b8a01e60474e1f00e5..b5b27d1b8ed35e82ab84d40267f954b20ba05514 100644 (file)
@@ -3,7 +3,7 @@
        /**
         * Manage sequences in a database
         *
-        * $Id: sequences.php,v 1.27 2004/09/07 13:58:21 jollytoad Exp $
+        * $Id: sequences.php,v 1.28 2005/05/02 15:47:24 chriskl Exp $
         */
        
        // Include application functions
                echo "<p><a class=\"navlink\" href=\"$PHP_SELF?action=create&amp;{$misc->href}\">{$lang['strcreatesequence']}</a></p>\n";
        }
        
+       /**
+        * Generate XML for the browser tree.
+        */
+       function doTree() {
+               global $misc, $data;
+               
+               $sequences = &$data->getSequences();
+               
+               $reqvars = $misc->getRequestVars('sequence');
+               
+               $attrs = array(
+                       'text'   => field('seqname'),
+                       'icon'   => 'sequences',
+                       'toolTip'=> field('seqcomment'),
+                       'action' => url('sequences.php',
+                                                       $reqvars,
+                                                       array (
+                                                               'action' => 'properties',
+                                                               'sequence' => field('seqname')
+                                                       )
+                                               )
+               );
+               
+               $misc->printTreeXML($sequences, $attrs);
+               exit;
+       }
+       
        /**
         * Display the properties of a sequence
         */      
                        doProperties($lang['strsequenceresetbad']);
        }
        
+       if ($action == 'tree') doTree();
+       
        // Print header
        $misc->printHeader($lang['strsequences']);
        $misc->printBody();
diff --git a/servers.php b/servers.php
new file mode 100644 (file)
index 0000000..ee1b65f
--- /dev/null
@@ -0,0 +1,133 @@
+<?php
+
+       /**
+        * Manage servers
+        *
+        * $Id: servers.php,v 1.2 2005/05/02 15:47:24 chriskl Exp $
+        */
+
+       // Include application functions
+       $_no_db_connection = true;
+       include_once('./libraries/lib.inc.php');
+       
+       $action = (isset($_REQUEST['action'])) ? $_REQUEST['action'] : '';
+       if (!isset($msg)) $msg = '';
+       $PHP_SELF = $_SERVER['PHP_SELF'];
+       
+       function doLogout() {
+               global $misc, $lang, $_reload_browser;
+               
+               $server_info = $misc->getServerInfo($_REQUEST['logoutServer']);
+               $misc->setServerInfo(null,null,$_REQUEST['logoutServer']);
+               doDefault(sprintf($lang['strlogoutmsg'], $server_info['desc']));
+               
+               $_reload_browser = true;
+       }
+
+       function doDefault($msg = '') {
+               global $conf, $misc;
+               global $PHP_SELF, $lang;
+               
+               $misc->printTabs('root','servers');
+               $misc->printMsg($msg);
+               
+               $servers =& $misc->getServers(true);
+               
+               function svPre(&$rowdata, $actions) {
+                       $actions['logout']['disable'] = empty($rowdata->f['username']);
+                       return $actions;
+               }
+               
+               $columns = array(
+                       'server' => array(
+                               'title' => $lang['strserver'],
+                               'field' => 'desc',
+                       ),
+                       'host' => array(
+                               'title' => $lang['strhost'],
+                               'field' => 'host',
+                       ),
+                       'port' => array(
+                               'title' => $lang['strport'],
+                               'field' => 'port',
+                       ),
+                       'username' => array(
+                               'title' => $lang['strusername'],
+                               'field' => 'username',
+                       ),
+                       'actions' => array(
+                               'title' => $lang['stractions'],
+                       ),
+               );
+               
+               $actions = array(
+                       'properties' => array(
+                               'title' => $lang['strproperties'],
+                               'url'   => "redirect.php?subject=server&amp;",
+                               'vars'  => array('server' => 'id'),
+                       ),
+                       'logout' => array(
+                               'title' => $lang['strlogout'],
+                               'url'   => "{$PHP_SELF}?action=logout&amp;",
+                               'vars'  => array('logoutServer' => 'id'),
+                       ),
+               );
+               
+               $misc->printTable($servers, $columns, $actions, $lang['strnoobjects'], 'svPre');
+       }
+       
+       function doTree() {
+               global $misc;
+               
+               $servers =& $misc->getServers(true);
+               
+               $reqvars = $misc->getRequestVars('server');
+               
+               $attrs = array(
+                       'text'   => field('desc'),
+                       
+                       // Show different icons for logged in/out
+                       'icon'   => ifempty(field('username'), 'serverOut', 'server'),
+                       
+                       'toolTip'=> field('id'),
+                       
+                       'action' => url('redirect.php',
+                                                       $reqvars,
+                                                       array('server' => field('id'))
+                                               ),
+                       
+                       // Only create a branch url if the user has
+                       // logged into the server.
+                       'branch' => ifempty(field('username'), false,
+                                                       url('all_db.php',
+                                                               $reqvars,
+                                                               array(
+                                                                       'action' => 'tree',
+                                                                       'server' => field('id')
+                                                               )
+                                                       )
+                                               ),
+               );
+               
+               $misc->printTreeXML($servers, $attrs);
+               exit;
+       }
+       
+       if ($action == 'tree') doTree();
+       
+       $misc->printHeader($lang['strservers']);
+       $misc->printBody();
+       $misc->printTrail('root');
+
+       switch ($action) {
+               case 'logout':
+                       doLogout();
+                       break;
+               case 'tree':
+               default:
+                       doDefault($msg);
+                       break;
+       }
+
+       $misc->printFooter();
+?>
index 1480b95ea367808560e799b9382ae9dafc1ab207..4fce292597a47c2cd75c24b9886b334869ada138 100644 (file)
@@ -3,7 +3,7 @@
        /**
         * Alternative SQL editing window
         *
-        * $Id: sqledit.php,v 1.25 2004/09/30 16:32:05 jollytoad Exp $
+        * $Id: sqledit.php,v 1.26 2005/05/02 15:47:24 chriskl Exp $
         */
 
        // Include application functions
        $PHP_SELF = $_SERVER['PHP_SELF'];
 
        /**
-        * Private function to display list of databases
+        * Private function to display server and list of databases
         */
-       function _printDatabases() {
+       function _printConnection() {
                global $data, $lang, $conf, $action, $misc;
-
+               
+               // The javascript action on the select box reloads the
+               // popup whenever the server or database is changed.
+               // This ensures that the correct page encoding is used.
+               $onchange = "onchange=\"location.href='sqledit.php?action=" . 
+                               urlencode($action) . "&server=' + encodeURI(server.options[server.selectedIndex].value) + '&database=' + encodeURI(database.options[database.selectedIndex].value) + ";
+               
+               // The exact URL to reload to is different between SQL and Find mode, however.
+               if ($action == 'find') {
+                       $onchange .= "'&term=' + encodeURI(term.value) + '&filter=' + encodeURI(filter.value) + '&" . SID . "'\">\n";
+               } else {
+                       $onchange .= "'&query=' + encodeURI(query.value) ";
+                       if ($data->hasSchemas()) $onchange .= "+ '&search_path=' + encodeURI(search_path.value) ";
+                       $onchange .= "+ (paginate.checked ? '&paginate=on' : '')  + '&" . SID . "'\"";
+               }
+               
+               echo "<table width=\"100%\"><tr><td>\n";
+               echo "<label>";
+               $misc->printHelp($lang['strserver'], 'pg.server');
+               echo ": <select name=\"server\" {$onchange}>\n";
+               
+               $servers = $misc->getServers();
+               foreach($servers as $info) {
+                       if (empty($info['username'])) continue;
+                       echo "<option value=\"", htmlspecialchars($info['id']), "\"",
+                               ((isset($_REQUEST['server']) && $info['id'] == $_REQUEST['server'])) ? ' selected="selected"' : '', ">",
+                               htmlspecialchars("{$info['desc']} ({$info['id']})"), "</option>\n";
+               }
+               echo "</select>\n</td><td align=\"right\">\n";
+               
                // Get the list of all databases
                $databases = &$data->getDatabases();
 
-               if ($databases->recordCount() > 0) {                    
-                       // The javascript action on the select box reloads the popup whenever the database is changed.
-                       // This ensures that the correct page encoding is used.  The exact URL to reload to is different
-                       // between SQL and Find mode, however.
-                       if ($action == 'sql') {
-                               echo "<p>";
-                               $misc->printHelp($lang['strdatabase'], 'pg.database');
-                               echo ": <select name=\"database\" onChange=\"location.href='sqledit.php?action=" . 
-                                               urlencode($action) . "&database=' + encodeURI(options[selectedIndex].value) + '&query=' + encodeURI(query.value) ";
-                               if ($data->hasSchemas()) echo "+ '&search_path=' + encodeURI(search_path.value) ";
-                               echo "+ (paginate.checked ? '&paginate=on' : '')  + '&" . SID . "'\">\n";
-                       }
-                       else
-                               echo "<p>{$lang['strdatabase']}: <select name=\"database\" onChange=\"location.href='sqledit.php?action=" . 
-                                               urlencode($action) . "&database=' + encodeURI(options[selectedIndex].value) + '&term=' + encodeURI(term.value) + '&filter=' + encodeURI(filter.value) + '&" . SID . "'\">\n";
+               if ($databases->recordCount() > 0) {
+                       // The javascript action on the select box reloads
+                       // the popup whenever the database is changed.
+                       // This ensures that the correct page encoding is used.
+
+                       echo "<label>";
+                       $misc->printHelp($lang['strdatabase'], 'pg.database');
+                       echo ": <select name=\"database\" {$onchange}>\n";
                        
                        while (!$databases->EOF) {
                                $dbname = $databases->f['datname'];
                        echo "</select></label>\n";
                }
                else {
+                       $server_info = $misc->getServerInfo();
                        echo "<input type=\"hidden\" name=\"database\" value=\"", 
-                               htmlspecialchars($conf['servers'][$_SESSION['webdbServerID']]['defaultdb']), "\" />\n";
-               }               
-       }       
+                               htmlspecialchars($server_info['defaultdb']), "\" />\n";
+               }
+               
+               echo "</td></tr></table>\n";
+       }
        
        /**
         * Searches for a named database object
        function doFind() {
                global $PHP_SELF, $data, $misc;
                global $lang, $conf;
-
+               
                if (!isset($_GET['term'])) $_GET['term'] = '';
                if (!isset($_GET['filter'])) $_GET['filter'] = '';
-
+               
+               $misc->printHeader($lang['strfind']);
+               
+               // Bring to the front always
+               echo "<body onload=\"window.focus();\">\n";
+               
                $misc->printTabs($misc->getNavTabs('popup'), 'find');
                
                echo "<form action=\"database.php\" method=\"get\" target=\"detail\">\n<p>";
-               _printDatabases();
+               _printConnection();
                echo "</p><p><input name=\"term\" value=\"", htmlspecialchars($_GET['term']), 
                        "\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" />\n";
                        
                echo "</select>\n";
                                        
                echo "<input type=\"submit\" value=\"{$lang['strfind']}\" />\n";
-               echo $misc->form;
                echo "<input type=\"hidden\" name=\"action\" value=\"find\" /></p>\n";
                echo "</form>\n";
 
        function doDefault() {
                global $PHP_SELF, $data, $misc;
                global $lang, $conf;
-
+               
                if (!isset($_REQUEST['query'])) $_REQUEST['query'] = '';
-
+               
+               $misc->printHeader($lang['strsql']);
+               
+               // Bring to the front always
+               echo "<body onload=\"window.focus();\">\n";
+               
                $misc->printTabs($misc->getNavTabs('popup'), 'sql');
-
+               
                echo "<form action=\"sql.php\" method=\"post\" target=\"detail\">\n<p>";
-
-               _printDatabases();
-
+               _printConnection();
+               echo "</p>\n";
                if ($data->hasSchemas()) {
                        if (!isset($_REQUEST['search_path']))
                                $_REQUEST['search_path'] = implode(',',$data->getSearchPath());
                
-                       echo "\n<label>";
+                       echo "<p><label>";
                        $misc->printHelp($lang['strsearchpath'], 'pg.schema.search_path');
-                       echo ": <input type=\"text\" name=\"search_path\" size=\"30\" value=\"",
-                               htmlspecialchars($_REQUEST['search_path']), "\" /></label>";
+                       echo ": <input type=\"text\" name=\"search_path\" size=\"50\" value=\"",
+                               htmlspecialchars($_REQUEST['search_path']), "\" /></label></p>\n";
                }
                
-               echo "</p>\n<textarea style=\"width: 100%;\" rows=\"10\" cols=\"50\" name=\"query\">",
+               echo "<textarea style=\"width: 100%;\" rows=\"10\" cols=\"50\" name=\"query\">",
                        htmlspecialchars($_REQUEST['query']), "</textarea>\n";
                echo "<label><input type=\"checkbox\" name=\"paginate\"", (isset($_REQUEST['paginate']) ? ' checked="checked"' : ''), " />&nbsp;{$lang['strpaginate']}</label>\n";
-
+               
                echo "<p><input type=\"submit\" value=\"{$lang['strgo']}\" />\n";
                if ($data->hasFullExplain()) {
                        echo "<input type=\"submit\" name=\"explain\" value=\"{$lang['strexplain']}\" />\n";
                        echo "<input type=\"submit\" name=\"explain_analyze\" value=\"{$lang['strexplainanalyze']}\" />\n";
                }
                echo "<input type=\"reset\" value=\"{$lang['strreset']}\" /></p>\n";
-
-               echo $misc->form;
-
                echo "</form>\n";
                
                // Default focus
                $misc->setFocus('forms[0].query');
        }
 
-       $misc->printHeader($lang['strsql']);
-
-       // Bring to the front always
-       echo "<body onLoad=\"window.focus();\">\n";
-       
        switch ($action) {
                case 'find':
                        doFind();
                        break;
        }
        
+       // Set the name of the window
+       $misc->setWindowName('sqledit');
+       
        $misc->printFooter();
        
 ?>
index a04bedabacc021b62a02bd095f404adba35e99c5..61bcbd5b113cb5486471ffc9790d5ead817bd3a6 100644 (file)
@@ -3,7 +3,7 @@
        /**
         * List tables in a database
         *
-        * $Id: tables.php,v 1.71 2005/03/18 19:51:56 xzilla Exp $
+        * $Id: tables.php,v 1.72 2005/05/02 15:47:24 chriskl Exp $
         */
 
        // Include application functions
         * Ask for select parameters and perform select
         */
        function doSelectRows($confirm, $msg = '') {
-               global $data, $misc;
+               global $data, $misc, $_no_output;
                global $lang;
                global $PHP_SELF;
 
                        }
                        
                        if (sizeof($_POST['show']) == 0)
-                               doSelectRows(true, $lang['strselectneedscol']);                 
+                               doSelectRows(true, $lang['strselectneedscol']);
                        else {
                                // Generate query SQL
                                $query = $data->getSelectSQL($_REQUEST['table'], array_keys($_POST['show']),
                                $_REQUEST['return_url'] = "tables.php?action=confselectrows&{$misc->href}&table={$_REQUEST['table']}";
                                $_REQUEST['return_desc'] = $lang['strback'];
 
+                               $_no_output = true;
                                include('./display.php');
                                exit;
                        }
                $actions = array(
                        'properties' => array(
                                'title' => $lang['strproperties'],
-                               'url'   => "redirect.php?section=table&amp;{$misc->href}&amp;",
+                               'url'   => "redirect.php?subject=table&amp;{$misc->href}&amp;",
                                'vars'  => array('table' => 'relname'),
                        ),
                        'browse' => array(
                echo "<p><a class=\"navlink\" href=\"$PHP_SELF?action=create&amp;{$misc->href}\">{$lang['strcreatetable']}</a></p>\n";
        }
        
+       /**
+        * Generate XML for the browser tree.
+        */
+       function doTree() {
+               global $misc, $data;
+               
+               $tables = &$data->getTables();
+               
+               $reqvars = $misc->getRequestVars('table');
+               
+               $attrs = array(
+                       'text'   => field('relname'),
+                       'icon'   => 'tables',
+                       'toolTip'=> field('relcomment'),
+                       'action' => url('redirect.php',
+                                                       $reqvars,
+                                                       array('table' => field('relname'))
+                                               )
+               );
+               
+               $misc->printTreeXML($tables, $attrs);
+               exit;
+       }
+       
+       if ($action == 'tree') doTree();
+       
        $misc->printHeader($lang['strtables']);
        $misc->printBody();
 
index c31c3fbd4b03f3045162d10a668957664e8d10b6..3c96590d19282454f1350686477387ecf4521a64 100755 (executable)
@@ -3,7 +3,7 @@
        /**
         * Manage tablespaces in a database cluster
         *
-        * $Id: tablespaces.php,v 1.6 2004/09/07 13:58:21 jollytoad Exp $
+        * $Id: tablespaces.php,v 1.7 2005/05/02 15:47:24 chriskl Exp $
         */
 
        // Include application functions
@@ -35,6 +35,7 @@
                        if (!isset($_POST['owner'])) $_POST['owner'] = $tablespace->f['spcowner'];
                        
                        echo "<form action=\"$PHP_SELF\" method=\"post\">\n";
+                       echo $misc->form;
                        echo "<table>\n";
                        echo "<tr><th class=\"data left required\">{$lang['strname']}</th>\n";
                        echo "<td class=\"data1\">";
@@ -52,7 +53,6 @@
                        echo "</table>\n";
                        echo "<p><input type=\"hidden\" name=\"action\" value=\"save_edit\" />\n";
                        echo "<input type=\"hidden\" name=\"tablespace\" value=\"", htmlspecialchars($_REQUEST['tablespace']), "\" />\n";
-                       echo $misc->form;
                        echo "<input type=\"submit\" name=\"alter\" value=\"{$lang['stralter']}\" />\n";
                        echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n";
                        echo "</form>\n";
@@ -98,6 +98,7 @@
                        echo "<p>", sprintf($lang['strconfdroptablespace'], $misc->printVal($_REQUEST['tablespace'])), "</p>\n";        
                        
                        echo "<form action=\"$PHP_SELF\" method=\"post\">\n";
+                       echo $misc->form;
                        echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n";
                        echo "<input type=\"hidden\" name=\"tablespace\" value=\"", htmlspecialchars($_REQUEST['tablespace']), "\" />\n";
                        echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n";
                global $data, $misc, $spcname;
                global $PHP_SELF, $lang;
                
+               $server_info = $misc->getServerInfo();
+               
                if (!isset($_POST['formSpcname'])) $_POST['formSpcname'] = '';
-               if (!isset($_POST['formOwner'])) $_POST['formOwner'] = $_SESSION['webdbUsername'];
+               if (!isset($_POST['formOwner'])) $_POST['formOwner'] = $server_info['username'];
                if (!isset($_POST['formLoc'])) $_POST['formLoc'] = '';
 
                // Fetch all users
                $misc->printMsg($msg);
 
                echo "<form action=\"$PHP_SELF\" method=\"post\">\n";
+               echo $misc->form;
                echo "<table>\n";
                echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n";
                echo "\t\t<td class=\"data1\"><input size=\"32\" name=\"formSpcname\" maxlength=\"{$data->_maxNameLen}\" value=\"", htmlspecialchars($_POST['formSpcname']), "\" /></td>\n\t</tr>\n";
                        )
                );
                
+               $href = $misc->getHREF('database');
+               
                $actions = array(
                        'alter' => array(
                                'title' => $lang['stralter'],
-                               'url'   => "{$PHP_SELF}?action=edit&amp;",
+                               'url'   => "{$PHP_SELF}?action=edit&amp;{$href}&amp;",
                                'vars'  => array('tablespace' => 'spcname')
                        ),
                        'drop' => array(
                                'title' => $lang['strdrop'],
-                               'url'   => "{$PHP_SELF}?action=confirm_drop&amp;",
+                               'url'   => "{$PHP_SELF}?action=confirm_drop&amp;{$href}&amp;",
                                'vars'  => array('tablespace' => 'spcname')
                        ),
                        'privileges' => array(
                                'title' => $lang['strprivileges'],
-                               'url'   => "privileges.php?subject=tablespace&amp;",
+                               'url'   => "privileges.php?subject=tablespace&amp;{$href}&amp;",
                                'vars'  => array('tablespace' => 'spcname')
                        )
                );
                                
                $misc->printTable($tablespaces, $columns, $actions, $lang['strnotablespaces']);
                
-               echo "<p><a class=\"navlink\" href=\"$PHP_SELF?action=create\">{$lang['strcreatetablespace']}</a></p>\n";
+               echo "<p><a class=\"navlink\" href=\"{$PHP_SELF}?action=create&amp;{$href}\">{$lang['strcreatetablespace']}</a></p>\n";
 
        }
 
index a11982dd524dfaae3a7443bc8492bcae11824a95..29fbda3364f5a3efce03f4a451e1193de75f0aa1 100644 (file)
@@ -3,7 +3,7 @@
        /**
         * List tables in a database
         *
-        * $Id: tblproperties.php,v 1.62 2004/11/02 03:33:35 chriskl Exp $
+        * $Id: tblproperties.php,v 1.63 2005/05/02 15:47:24 chriskl Exp $
         */
 
        // Include application functions
@@ -70,7 +70,9 @@
                        echo "<td class=\"data1\">";
                        echo "<input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"", 
                                htmlspecialchars($_POST['name']), "\" /></td></tr>\n";
-                       if ($data->hasAlterTableOwner() && $data->isSuperUser($_SESSION['webdbUsername'])) {
+                       
+                       $server_info = $misc->getServerInfo();
+                       if ($data->hasAlterTableOwner() && $data->isSuperUser($server_info['username'])) {
                                echo "<tr><th class=\"data left required\">{$lang['strowner']}</th>\n";
                                echo "<td class=\"data1\"><select name=\"owner\">";
                                while (!$users->EOF) {
 
                echo "<p><input type=\"hidden\" name=\"action\" value=\"export\" />\n";
                echo $misc->form;
+               echo "<input type=\"hidden\" name=\"subject\" value=\"table\" />\n";
                echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n";
                echo "<input type=\"submit\" value=\"{$lang['strexport']}\" /></p>\n";
                echo "</form>\n";
 
                echo "<ul>\n";
                $return_url = urlencode("tblproperties.php?{$misc->href}&table={$_REQUEST['table']}");
-               echo "\t<li><a href=\"display.php?{$misc->href}&table=", urlencode($_REQUEST['table']), "&subject=table&return_url={$return_url}&return_desc=",
+               echo "\t<li><a href=\"display.php?{$misc->href}&amp;table=", urlencode($_REQUEST['table']), "&subject=table&amp;return_url={$return_url}&amp;return_desc=",
                        urlencode($lang['strback']), "\">{$lang['strbrowse']}</a></li>\n";
-               echo "\t<li><a href=\"tables.php?action=confselectrows&{$misc->href}&table=", urlencode($_REQUEST['table']),"\">{$lang['strselect']}</a></li>\n";
-               echo "\t<li><a href=\"tables.php?action=confinsertrow&{$misc->href}&table=", urlencode($_REQUEST['table']),"\">{$lang['strinsert']}</a></li>\n";
-               echo "\t<li><a href=\"tables.php?action=confirm_empty&{$misc->href}&table=", urlencode($_REQUEST['table']),"\">{$lang['strempty']}</a></li>\n";
-               echo "\t<li><a href=\"tables.php?action=confirm_drop&{$misc->href}&table=", urlencode($_REQUEST['table']),"\">{$lang['strdrop']}</a></li>\n";
-               echo "\t<li><a href=\"{$PHP_SELF}?action=add_column&{$misc->href}&table=", urlencode($_REQUEST['table']),"\">{$lang['straddcolumn']}</a></li>\n";
-               echo "\t<li><a href=\"{$PHP_SELF}?action=confirm_alter&{$misc->href}&table=", urlencode($_REQUEST['table']),"\">{$lang['stralter']}</a></li>\n";
+               echo "\t<li><a href=\"tables.php?action=confselectrows&amp;{$misc->href}&amp;table=", urlencode($_REQUEST['table']),"\">{$lang['strselect']}</a></li>\n";
+               echo "\t<li><a href=\"tables.php?action=confinsertrow&amp;{$misc->href}&amp;table=", urlencode($_REQUEST['table']),"\">{$lang['strinsert']}</a></li>\n";
+               echo "\t<li><a href=\"tables.php?action=confirm_empty&amp;{$misc->href}&amp;table=", urlencode($_REQUEST['table']),"\">{$lang['strempty']}</a></li>\n";
+               echo "\t<li><a href=\"tables.php?action=confirm_drop&amp;{$misc->href}&amp;table=", urlencode($_REQUEST['table']),"\">{$lang['strdrop']}</a></li>\n";
+               echo "\t<li><a href=\"{$PHP_SELF}?action=add_column&amp;{$misc->href}&amp;table=", urlencode($_REQUEST['table']),"\">{$lang['straddcolumn']}</a></li>\n";
+               echo "\t<li><a href=\"{$PHP_SELF}?action=confirm_alter&amp;{$misc->href}&amp;table=", urlencode($_REQUEST['table']),"\">{$lang['stralter']}</a></li>\n";
                echo "</ul>\n";
        }
 
index 1e0dbb63a8e179e49e477bd3356fe0330470dba2..495f9d26e1b944aeebf8c8c8a1183c1a2b0701db 100644 (file)
@@ -1,7 +1,7 @@
 /**
  * Default style sheet
  *
- * $Id: global.css,v 1.31 2004/11/02 11:46:53 soranzo Exp $
+ * $Id: global.css,v 1.32 2005/05/02 15:47:28 chriskl Exp $
  */
 
 /** ELEMENTS */
@@ -15,14 +15,18 @@ body, td
        font-size: smaller; /*0.8em;*/
 }
 
-body.topbar
+img { border: none; }
+
+div.logo
 {
        background-color: #CECF9C;
        margin: 0px;
        padding: 0px;
        font-family: arial, tahoma, verdana, helvetica, sans-serif, serif;
        font-size: smaller; /* 1em; */
+       border: none;
        border-bottom: 2px solid #000000;
+       margin-bottom: 2px;
 }
 
 body.browser
@@ -194,7 +198,7 @@ td.opbutton2
        padding: 2px 1em;
 }
 
-.trail
+.trail, .topbar
 {
        margin-bottom: 2px;
 }
@@ -221,6 +225,19 @@ td.opbutton2
        background-color: #E6E6CC;
 }
 
+.topbar {
+       border: 2px solid #CECF9C;
+       padding: 2px 1em;
+}
+
+.topbar, .topbar td {
+       background-color: #CECF9C;
+}
+
+.topbar .platform, .topbar .host, .topbar .username {
+       font-weight: bold;
+}
+
 a:active 
 {
        color: #989973;
@@ -306,8 +323,42 @@ pre.data
        font-size: 100%;
 }
 
+.intro li
+{
+       font-weight: bold;
+}
+
 /* Syntax highlighting */
 .comment {color: #008080}
 .keyword {color: #FF8000}
 .literal {color: #808080}
 
+/* Browser Tree using XLoadTree 2 */
+.webfx-tree-row {
+       white-space: nowrap;
+       font: arial, tahoma, verdana, helvetica, sans-serif, serif;
+}
+
+.webfx-tree-children {
+       background-repeat: repeat-y;
+       background-position-y: 1px !important;  /* IE only */
+}
+
+.webfx-tree-row img {
+       vertical-align: middle;
+       height: 20px;
+}
+
+.webfx-tree-icon {
+       width: 20px;
+       cursor: hand;
+       cursor: pointer;
+}
+
+.webfx-tree-expand-icon {
+       width: 20px;
+}
+
+.webfx-tree-hide-root {
+       display: none;
+}
diff --git a/topbar.php b/topbar.php
deleted file mode 100755 (executable)
index c9a9d06..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-<?php
-
-       /**
-        * Top menu for phpPgAdmin
-        *
-        * $Id: topbar.php,v 1.25 2004/07/12 04:18:40 chriskl Exp $
-        */
-
-       // Include application functions
-       include_once('./libraries/lib.inc.php');
-       
-       // To prevent SQL popup windows from conflicting
-       $window_id = 'sqledit_' . urlencode($conf['servers'][$_SESSION['webdbServerID']]['host'] .'_' . $conf['servers'][$_SESSION['webdbServerID']]['port']);
-       
-       $misc->printHeader();
-       $misc->printBody('topbar');
-       $dbselected = isset($_REQUEST['database']) ? '&database=' . $_REQUEST['database'] : '';
-?>
-<table width="100%" border="0" cellspacing="0" cellpadding="0" class="topbar" dir="ltr">
-       <tr>
-               <td width="211" rowspan="2"><a href="intro.php" target="detail"><img style="border: none" src="images/themes/<?php echo $conf['theme'] ?>/title.png" width="211" height="50" alt="<?php echo htmlspecialchars($appName) ?>" title="<?php echo htmlspecialchars($appName) ?>" /></a></td>
-               <td class="topbar" width="5" rowspan="2">&nbsp;</td>
-               <td class="topbar">
-               <?php echo sprintf($lang['strtopbar'], htmlspecialchars($conf['description']),
-                       htmlspecialchars($conf['servers'][$_SESSION['webdbServerID']]['host']),
-                       htmlspecialchars($conf['servers'][$_SESSION['webdbServerID']]['port']),
-                       htmlspecialchars($_SESSION['webdbUsername']), 
-                       date($lang['strtimefmt'])) ?></td>
-       </tr>
-       <tr>
-               <td class="topbar">
-<?php
-       // For superuser, show user and group admin.  For normal user, show change password.
-       if ($data->isSuperUser($_SESSION['webdbUsername'])) :
-?>
-                       <a class="toplink" href="users.php" target="detail"><?php echo $lang['strusers'] ?></a> | 
-                       <a class="toplink" href="groups.php" target="detail"><?php echo $lang['strgroups'] ?></a> |
-<?php
-       endif;
-?>
-                       <a class="toplink" href="users.php?action=account" target="detail"><?php echo $lang['straccount'] ?></a> |
-<?php if ($data->hasTablespaces()) : ?>
-                       <a class="toplink" href="tablespaces.php" target="detail"><?php echo $lang['strtablespaces'] ?></a> | 
-<?php endif; ?>
-<?php if ($conf['show_reports']) : ?>
-                       <a class="toplink" href="reports.php" target="detail"><?php echo $lang['strreports'] ?></a> |
-<?php endif; ?>
-                       <a class="toplink" href="sqledit.php" target="sqledit" onclick="window.open('sqledit.php?action=sql<?php echo $dbselected ?>&<?php echo SID ?>','<?php echo htmlspecialchars($window_id) ?>','toolbar=no,width=600,height=400,resizable=yes,scrollbars=no').focus(); return false;"><?php echo $lang['strsql'] ?></a> |
-                       <a class="toplink" href="sqledit.php" target="sqledit" onclick="window.open('sqledit.php?action=find<?php echo $dbselected ?>&<?php echo SID ?>','<?php echo htmlspecialchars($window_id) ?>','toolbar=no,width=600,height=400,resizable=yes,scrollbars=no').focus(); return false;"><?php echo $lang['strfind'] ?></a> |                       
-                       <a class="toplink" href="logout.php" target="_parent"><?php echo $lang['strlogout'] ?></a>
-               </td>
-       </tr>
-</table>
-<?php
-       $misc->printFooter();
-?>
index c88e97754e6d3fe7d299968b2d1b1e9e984f85ae..4194178a0304525975cc20289fdf92063c06c781 100644 (file)
@@ -3,7 +3,7 @@
        /**
         * List triggers on a table
         *
-        * $Id: triggers.php,v 1.25 2005/04/14 18:20:10 xzilla Exp $
+        * $Id: triggers.php,v 1.26 2005/05/02 15:47:24 chriskl Exp $
         */
 
        // Include application functions
                
                $misc->printTable($triggers, $columns, $actions, $lang['strnotriggers'], 'tgPre');
                
-               echo "<p><a class=\"navlink\" href=\"$PHP_SELF?action=create&{$misc->href}&table=", urlencode($_REQUEST['table']), "\">{$lang['strcreatetrigger']}</a></p>\n";
+               echo "<p><a class=\"navlink\" href=\"$PHP_SELF?action=create&amp;{$misc->href}&amp;table=", urlencode($_REQUEST['table']), "\">{$lang['strcreatetrigger']}</a></p>\n";
        }
 
        $misc->printHeader($lang['strtables'] . ' - ' . $_REQUEST['table'] . ' - ' . $lang['strtriggers']);
index eb1bb6676a1ed486e94bd22ba57d1cfd8e590e04..38466c2d15a0d4a0c7b512a7ef2fc269f62c898d 100644 (file)
--- a/types.php
+++ b/types.php
@@ -3,7 +3,7 @@
        /**
         * Manage types in a database
         *
-        * $Id: types.php,v 1.25 2004/09/07 13:58:21 jollytoad Exp $
+        * $Id: types.php,v 1.26 2005/05/02 15:47:25 chriskl Exp $
         */
 
        // Include application functions
                $misc->printTitle($lang['strproperties'], 'pg.type');
                $misc->printMsg($msg);
                
+               function attPre(&$rowdata) {
+                       global $data;
+                       $rowdata->f['+type'] = $data->formatType($rowdata->f['type'], $rowdata->f['atttypmod']);
+               }
+               
                if ($typedata->recordCount() > 0) {
                        switch ($typedata->f['typtype']) {
                        case 'c':
-                               function attPre(&$rowdata) {
-                                       global $data;
-                                       $rowdata->f['+type'] = $data->formatType($rowdata->f['type'], $rowdata->f['atttypmod']);
-                               }
-                               
                                $attrs = &$data->getTableAttributes($_REQUEST['type']);
                                
                                $columns = array(
@@ -76,8 +76,8 @@
                                echo "</table>\n";
                        }
 
-                       echo "<p><a class=\"navlink\" href=\"$PHP_SELF?{$misc->href}\">{$lang['strshowalltypes']}</a></p>\n";           }
-               else
+                       echo "<p><a class=\"navlink\" href=\"$PHP_SELF?{$misc->href}\">{$lang['strshowalltypes']}</a></p>\n";
+               else
                        doDefault($lang['strinvalidparam']);
        }
        
                echo "</p>\n";
 
        }
-
+       
+       /**
+        * Generate XML for the browser tree.
+        */
+       function doTree() {
+               global $misc, $data;
+               
+               $types = &$data->getTypes();
+               
+               $reqvars = $misc->getRequestVars('type');
+               
+               $attrs = array(
+                       'text'   => field('basename'),
+                       'icon'   => 'types',
+                       'toolTip'=> field('typcomment'),
+                       'action' => url('types.php',
+                                                       $reqvars,
+                                                       array(
+                                                               'action' => 'properties',
+                                                               'type'   => field('basename')
+                                                       )
+                                               )
+               );
+               
+               $misc->printTreeXML($types, $attrs);
+               exit;
+       }
+       
+       if ($action == 'tree') doTree();
+       
        $misc->printHeader($lang['strtypes']);
        $misc->printBody();
 
index dea93ce51dc41ce39beba7152e10335142120b4a..ef8fba9be80eea1c211bd2036a39c06b86daed04 100644 (file)
--- a/users.php
+++ b/users.php
@@ -3,7 +3,7 @@
        /**
         * Manage users in a database cluster
         *
-        * $Id: users.php,v 1.29 2004/09/07 13:58:21 jollytoad Exp $
+        * $Id: users.php,v 1.30 2005/05/02 15:47:25 chriskl Exp $
         */
 
        // Include application functions
                global $data, $misc;
                global $PHP_SELF, $lang;
                
-               $userdata = &$data->getUser($_SESSION['webdbUsername']);
-               $_REQUEST['user'] = $_SESSION['webdbUsername'];
+               $server_info = $misc->getServerInfo();
+               
+               $userdata = &$data->getUser($server_info['username']);
+               $_REQUEST['user'] = $server_info['username'];
                
                $misc->printTrail('user');
-               $misc->printTitle($lang['straccount'],'pg.user');
+               $misc->printTabs('server','account');
                $misc->printMsg($msg);
 
                if ($userdata->recordCount() > 0) {
@@ -46,7 +48,7 @@
                }
                else echo "<p>{$lang['strnodata']}</p>\n";
                
-               echo "<p><a class=\"navlink\" href=\"$PHP_SELF?action=confchangepassword\">{$lang['strchangepassword']}</a></p>\n";
+               echo "<p><a class=\"navlink\" href=\"{$PHP_SELF}?action=confchangepassword&amp;{$misc->href}\">{$lang['strchangepassword']}</a></p>\n";
        }
        
        /**
        function doChangePassword($confirm, $msg = '') {
                global $data, $misc;
                global $PHP_SELF, $lang, $conf;
-
+               
+               $server_info = $misc->getServerInfo();
+               
                if ($confirm) {
-                       $_REQUEST['user'] = $_SESSION['webdbUsername'];
+                       $_REQUEST['user'] = $server_info['username'];
                        $misc->printTrail('user');
                        $misc->printTitle($lang['strchangepassword'],'pg.user.alter');
                        $misc->printMsg($msg);
@@ -66,6 +70,7 @@
                        if (!isset($_POST['confirm'])) $_POST['confirm'] = '';
                        
                        echo "<form action=\"$PHP_SELF\" method=\"post\">\n";
+                       echo $misc->form;
                        echo "<table>\n";
                        echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strpassword']}</th>\n";
                        echo "\t\t<td><input type=\"password\" name=\"password\" size=\"32\" value=\"", 
@@ -86,7 +91,7 @@
                        elseif ($_POST['password'] != $_POST['confirm'])
                                doChangePassword(true, $lang['strpasswordconfirm']);
                        else {
-                               $status = $data->changePassword($_SESSION['webdbUsername'], 
+                               $status = $data->changePassword($server_info['username'], 
                                        $_POST['password']);
                                if ($status == 0)
                                        doAccount($lang['strpasswordchanged']);
                $userdata = &$data->getUser($_REQUEST['username']);
                
                if ($userdata->recordCount() > 0) {
-                       $canRename = $data->hasUserRename() && ($_REQUEST['username'] != $_SESSION['webdbUsername']);
+                       $server_info = $misc->getServerInfo();
+                       $canRename = $data->hasUserRename() && ($_REQUEST['username'] != $server_info['username']);
                        $userdata->f['usesuper'] = $data->phpBool($userdata->f['usesuper']);
                        $userdata->f['usecreatedb'] = $data->phpBool($userdata->f['usecreatedb']);
 
                        }
                
                        echo "<form action=\"$PHP_SELF\" method=\"post\">\n";
+                       echo $misc->form;
                        echo "<table>\n";
                        echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strusername']}</th>\n";
                        echo "\t\t<td class=\"data1\">", ($canRename ? "<input name=\"newname\" size=\"15\" value=\"" . htmlspecialchars($_POST['newname']) . "\" />" : $misc->printVal($userdata->f['usename'])), "</td>\n\t</tr>\n";
                        echo "<p>", sprintf($lang['strconfdropuser'], $misc->printVal($_REQUEST['username'])), "</p>\n";        
                        
                        echo "<form action=\"$PHP_SELF\" method=\"post\">\n";
+                       echo $misc->form;
                        echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n";
                        echo "<input type=\"hidden\" name=\"username\" value=\"", htmlspecialchars($_REQUEST['username']), "\" />\n";
                        echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n";
                $misc->printMsg($msg);
 
                echo "<form action=\"$PHP_SELF\" method=\"post\">\n";
+               echo $misc->form;
                echo "<table>\n";
                echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strusername']}</th>\n";
                echo "\t\t<td class=\"data1\"><input size=\"15\" name=\"formUsername\" value=\"", htmlspecialchars($_POST['formUsername']), "\" /></td>\n\t</tr>\n";
                
                $misc->printTable($users, $columns, $actions, $lang['strnousers']);
 
-               echo "<p><a class=\"navlink\" href=\"$PHP_SELF?action=create\">{$lang['strcreateuser']}</a></p>\n";
+               echo "<p><a class=\"navlink\" href=\"{$PHP_SELF}?action=create&amp;{$misc->href}\">{$lang['strcreateuser']}</a></p>\n";
 
        }
 
index cb52ba944d7ff9218b45f1aa3cb09b617af8b127..9d0ccab76420c8305f6584ed27d50c674b57e095 100755 (executable)
@@ -3,7 +3,7 @@
        /**
         * List views in a database
         *
-        * $Id: viewproperties.php,v 1.13 2004/09/07 13:58:21 jollytoad Exp $
+        * $Id: viewproperties.php,v 1.14 2005/05/02 15:47:25 chriskl Exp $
         */
 
        // Include application functions
 
                echo "<p><input type=\"hidden\" name=\"action\" value=\"export\" />\n";
                echo $misc->form;
-               echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['view']), "\" />\n";
+               echo "<input type=\"hidden\" name=\"subject\" value=\"view\" />\n";
+               echo "<input type=\"hidden\" name=\"view\" value=\"", htmlspecialchars($_REQUEST['view']), "\" />\n";
                echo "<input type=\"submit\" value=\"{$lang['strexport']}\" /></p>\n";
                echo "</form>\n";
        }
                echo "<br />\n";
 
                echo "<ul>\n";
-               $return_url = urlencode("viewproperties.php?{$misc->href}&view=" . urlencode($_REQUEST['view']));
-               echo "\t<li><a href=\"display.php?{$misc->href}&view=", urlencode($_REQUEST['view']), "&subject=view&return_url={$return_url}&return_desc=",
+               $return_url = urlencode("viewproperties.php?{$misc->href}&amp;view=" . urlencode($_REQUEST['view']));
+               echo "\t<li><a href=\"display.php?{$misc->href}&amp;view=", urlencode($_REQUEST['view']), "&amp;subject=view&amp;return_url={$return_url}&amp;return_desc=",
                        urlencode($lang['strback']), "\">{$lang['strbrowse']}</a></li>\n";
-               echo "\t<li><a href=\"views.php?action=confselectrows&{$misc->href}&view=", urlencode($_REQUEST['view']),"\">{$lang['strselect']}</a></li>\n";
-               echo "\t<li><a href=\"views.php?action=confirm_drop&{$misc->href}&view=", urlencode($_REQUEST['view']),"\">{$lang['strdrop']}</a></li>\n";
+               echo "\t<li><a href=\"views.php?action=confselectrows&amp;{$misc->href}&amp;view=", urlencode($_REQUEST['view']),"\">{$lang['strselect']}</a></li>\n";
+               echo "\t<li><a href=\"views.php?action=confirm_drop&amp;{$misc->href}&amp;view=", urlencode($_REQUEST['view']),"\">{$lang['strdrop']}</a></li>\n";
                echo "</ul>\n";
        }
 
index dd8022d805cb03becd2ab76b086e86e99446192c..dde9d89c37c04b9e091181e8637f1ea8b2923931 100644 (file)
--- a/views.php
+++ b/views.php
@@ -3,7 +3,7 @@
        /**
         * Manage views in a database
         *
-        * $Id: views.php,v 1.52 2005/01/23 12:42:35 soranzo Exp $
+        * $Id: views.php,v 1.53 2005/05/02 15:47:25 chriskl Exp $
         */
 
        // Include application functions
                $actions = array(
                        'properties' => array(
                                'title' => $lang['strproperties'],
-                               'url'   => "redirect.php?section=view&amp;{$misc->href}&amp;",
+                               'url'   => "redirect.php?subject=view&amp;{$misc->href}&amp;",
                                'vars'  => array('view' => 'relname'),
                        ),
                        'browse' => array(
                
                $misc->printTable($views, $columns, $actions, $lang['strnoviews']);
                
-               echo "<p><a class=\"navlink\" href=\"$PHP_SELF?action=create&{$misc->href}\">{$lang['strcreateview']}</a> |\n";
-               echo "<a class=\"navlink\" href=\"$PHP_SELF?action=wiz_create&{$misc->href}\">{$lang['strcreateviewwiz']}</a></p>\n";
+               echo "<p><a class=\"navlink\" href=\"$PHP_SELF?action=create&amp;{$misc->href}\">{$lang['strcreateview']}</a> |\n";
+               echo "<a class=\"navlink\" href=\"$PHP_SELF?action=wiz_create&amp;{$misc->href}\">{$lang['strcreateviewwiz']}</a></p>\n";
 
        }
-
+       
+       /**
+        * Generate XML for the browser tree.
+        */
+       function doTree() {
+               global $misc, $data;
+               
+               $views = &$data->getViews();
+               
+               $reqvars = $misc->getRequestVars('view');
+               
+               $attrs = array(
+                       'text'   => field('relname'),
+                       'icon'   => 'views',
+                       'toolTip'=> field('relcomment'),
+                       'action' => url('redirect.php',
+                                                       $reqvars,
+                                                       array('view' => field('relname'))
+                                               )
+               );
+               
+               $misc->printTreeXML($views, $attrs);
+               exit;
+       }
+       
+       if ($action == 'tree') doTree();
+       
        $misc->printHeader($lang['strviews']);
        $misc->printBody();
 
diff --git a/xloadtree/xloadtree2.js b/xloadtree/xloadtree2.js
new file mode 100644 (file)
index 0000000..2346132
--- /dev/null
@@ -0,0 +1,534 @@
+/*----------------------------------------------------------------------------\\r
+|                        XLoadTree 2 PRE RELEASE                              |\r
+|                                                                             |\r
+| This is a pre release and redistribution is discouraged.                    |\r
+| Watch http://webfx.eae.net for the final version                            |\r
+|                                                                             |\r
+|-----------------------------------------------------------------------------|\r
+|                   Created by Erik Arvidsson & Emil A Eklund                 |\r
+|                  (http://webfx.eae.net/contact.html#erik)                   |\r
+|                  (http://webfx.eae.net/contact.html#emil)                   |\r
+|                      For WebFX (http://webfx.eae.net/)                      |\r
+|-----------------------------------------------------------------------------|\r
+| A tree menu system for IE 5.5+, Mozilla 1.4+, Opera 7.5+                    |\r
+|-----------------------------------------------------------------------------|\r
+|         Copyright (c) 1999 - 2004 Erik Arvidsson & Emil A Eklund            |\r
+|-----------------------------------------------------------------------------|\r
+| This software is provided "as is", without warranty of any kind, express or |\r
+| implied, including  but not limited  to the warranties of  merchantability, |\r
+| fitness for a particular purpose and noninfringement. In no event shall the |\r
+| authors or  copyright  holders be  liable for any claim,  damages or  other |\r
+| liability, whether  in an  action of  contract, tort  or otherwise, arising |\r
+| from,  out of  or in  connection with  the software or  the  use  or  other |\r
+| dealings in the software.                                                   |\r
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |\r
+| This  software is  available under the  three different licenses  mentioned |\r
+| below.  To use this software you must chose, and qualify, for one of those. |\r
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |\r
+| The WebFX Non-Commercial License          http://webfx.eae.net/license.html |\r
+| Permits  anyone the right to use the  software in a  non-commercial context |\r
+| free of charge.                                                             |\r
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |\r
+| The WebFX Commercial license           http://webfx.eae.net/commercial.html |\r
+| Permits the  license holder the right to use  the software in a  commercial |\r
+| context. Such license must be specifically obtained, however it's valid for |\r
+| any number of  implementations of the licensed software.                    |\r
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |\r
+| GPL - The GNU General Public License    http://www.gnu.org/licenses/gpl.txt |\r
+| Permits anyone the right to use and modify the software without limitations |\r
+| as long as proper  credits are given  and the original  and modified source |\r
+| code are included. Requires  that the final product, software derivate from |\r
+| the original  source or any  software  utilizing a GPL  component, such  as |\r
+| this, is also licensed under the GPL license.                               |\r
+|-----------------------------------------------------------------------------|\r
+| 2004-02-21 | Pre release distributed to a few selected tester               |\r
+|-----------------------------------------------------------------------------|\r
+| Dependencies: xtree2.js Supplies the tree control                           |\r
+|-----------------------------------------------------------------------------|\r
+| Created 2003-??-?? | All changes are in the log above. | Updated 2004-02-21 |\r
+\----------------------------------------------------------------------------*/\r
+\r
+\r
+webFXTreeConfig.loadingText = "Loading...";\r
+webFXTreeConfig.loadingIcon = "images/loading.gif";\r
+webFXTreeConfig.errorIcon = "images/exclamation.16.gif";\r
+webFXTreeConfig.errorLoadingText = "Error Loading";\r
+webFXTreeConfig.reloadText = "Click to reload";\r
+\r
+\r
+function WebFXLoadTree(sText, sXmlSrc, oAction, sBehavior, sIcon, sOpenIcon)\r
+{\r
+       WebFXTree.call(this, sText, oAction, sBehavior, sIcon, sOpenIcon);\r
+\r
+       // setup default property values\r
+       this.src = sXmlSrc;\r
+       this.loading = !sXmlSrc;\r
+       this.loaded = !sXmlSrc;\r
+       this.errorText = "";\r
+\r
+       if (this.src)\r
+       {\r
+               /// add loading Item\r
+               this._loadingItem = WebFXLoadTree.createLoadingItem();\r
+               this.add(this._loadingItem);\r
+\r
+               if (this.getExpanded())\r
+                       WebFXLoadTree.loadXmlDocument(this);\r
+       }\r
+}\r
+\r
+WebFXLoadTree.createLoadingItem = function ()\r
+{\r
+       return new WebFXTreeItem(webFXTreeConfig.loadingText, null, null,\r
+                                                        webFXTreeConfig.loadingIcon);\r
+};\r
+\r
+WebFXLoadTree.prototype = new WebFXTree;\r
+\r
+WebFXLoadTree.prototype.setExpanded = function (b)\r
+{\r
+       WebFXTree.prototype.setExpanded.call(this, b);\r
+\r
+       if (this.src && b)\r
+       {\r
+               if (!this.loaded && !this.loading)\r
+               {\r
+                       // load\r
+                       WebFXLoadTree.loadXmlDocument(this);\r
+               }\r
+       }\r
+};\r
+\r
+function WebFXLoadTreeItem(sText, sXmlSrc, oAction, eParent, sIcon, sOpenIcon)\r
+{\r
+       WebFXTreeItem.call(this, sText, oAction, eParent, sIcon, sOpenIcon);\r
+\r
+// setup default property values\r
+       this.src = sXmlSrc;\r
+       this.loading = !sXmlSrc;\r
+       this.loaded = !sXmlSrc;\r
+       this.errorText = "";\r
+\r
+       if (this.src)\r
+       {\r
+               /// add loading Item\r
+               this._loadingItem = WebFXLoadTree.createLoadingItem();\r
+               this.add(this._loadingItem);\r
+\r
+               if (this.getExpanded())\r
+                       WebFXLoadTree.loadXmlDocument(this);\r
+       }\r
+}\r
+\r
+WebFXLoadTreeItem.prototype = new WebFXTreeItem;\r
+\r
+WebFXLoadTreeItem.prototype.setExpanded = function (b)\r
+{\r
+       WebFXTreeItem.prototype.setExpanded.call(this, b);\r
+\r
+       if (this.src && b)\r
+       {\r
+               if (!this.loaded && !this.loading)\r
+               {\r
+                       // load\r
+                       WebFXLoadTree.loadXmlDocument(this);\r
+               }\r
+       }\r
+};\r
+\r
+// reloads the src file if already loaded\r
+WebFXLoadTree.prototype.reload =\r
+WebFXLoadTreeItem.prototype.reload = function ()\r
+{\r
+       // if loading do nothing\r
+       if (this.loaded)\r
+       {\r
+               var t = this.getTree();\r
+               var expanded = this.getExpanded();\r
+               var sr = t.getSuspendRedraw();\r
+               t.setSuspendRedraw(true);\r
+\r
+               // remove\r
+               while (this.childNodes.length > 0)\r
+                       this.remove(this.childNodes[this.childNodes.length - 1]);\r
+\r
+               this.loaded = false;\r
+\r
+               this._loadingItem = WebFXLoadTree.createLoadingItem();\r
+               this.add(this._loadingItem);\r
+\r
+               if (expanded)\r
+                       this.setExpanded(true);\r
+\r
+               t.setSuspendRedraw(sr);\r
+               this.update();\r
+       }\r
+       else if (this.open && !this.loading)\r
+               WebFXLoadTree.loadXmlDocument(this);\r
+};\r
+\r
+\r
+\r
+WebFXLoadTree.prototype.setSrc =\r
+WebFXLoadTreeItem.prototype.setSrc = function (sSrc)\r
+{\r
+       var oldSrc = this.src;\r
+       if (sSrc == oldSrc) return;\r
+\r
+       var expanded = this.getExpanded();\r
+\r
+       // remove all\r
+       this._callSuspended(function ()\r
+       {\r
+               // remove\r
+               while (this.childNodes.length > 0)\r
+                       this.remove(this.childNodes[this.childNodes.length - 1]);\r
+       });\r
+       this.update();\r
+\r
+       this.loaded = false;\r
+       this.loading = false;\r
+       if (this._loadingItem)\r
+       {\r
+               this._loadingItem.dispose();\r
+               this._loadingItem = null;\r
+       }\r
+       this.src = sSrc;\r
+\r
+       if (sSrc)\r
+       {\r
+               this._loadingItem = WebFXLoadTree.createLoadingItem();\r
+               this.add(this._loadingItem);\r
+       }\r
+\r
+       this.setExpanded(expanded);\r
+};\r
+\r
+WebFXLoadTree.prototype.getSrc =\r
+WebFXLoadTreeItem.prototype.getSrc = function ()\r
+{\r
+       return this.src;\r
+};\r
+\r
+WebFXLoadTree.prototype.dispose = function ()\r
+{\r
+       WebFXTree.prototype.dispose.call(this);\r
+       if (this._xmlHttp)\r
+       {\r
+               if (this._xmlHttp.dispose)\r
+                       this._xmlHttp.dispose();\r
+               try\r
+               {\r
+                       this._xmlHttp.onreadystatechange = null;\r
+                       this._xmlHttp.abort();\r
+               }\r
+               catch (ex) {}\r
+               this._xmlHttp = null;\r
+       }\r
+};\r
+\r
+WebFXLoadTreeItem.prototype.dispose = function ()\r
+{\r
+       WebFXTreeItem.prototype.dispose.call(this);\r
+       if (this._xmlHttp)\r
+       {\r
+               if (this._xmlHttp.dispose)\r
+                       this._xmlHttp.dispose();\r
+               try\r
+               {\r
+                       this._xmlHttp.onreadystatechange = null;\r
+                       this._xmlHttp.abort();\r
+               }\r
+               catch (ex) {}\r
+               this._xmlHttp = null;\r
+       }\r
+};\r
+\r
+\r
+// The path is divided by '/' and the item is identified by the text\r
+WebFXLoadTree.prototype.openPath =\r
+WebFXLoadTreeItem.prototype.openPath = function (sPath, bSelect, bFocus)\r
+{\r
+       // remove any old pending paths to open\r
+       delete this._pathToOpen;\r
+       //delete this._pathToOpenById;\r
+       this._selectPathOnLoad = bSelect;\r
+       this._focusPathOnLoad = bFocus;\r
+\r
+       if (sPath == "")\r
+       {\r
+               if (bSelect)\r
+                       this.select();\r
+               if (bFocus)\r
+                       window.setTimeout("WebFXTreeAbstractNode._onTimeoutFocus(\"" + this.getId() + "\")", 10);\r
+               return;\r
+       }\r
+\r
+       var parts = sPath.split("/");\r
+       var remainingPath = parts.slice(1).join("/");\r
+\r
+       if (sPath.charAt(0) == "/")\r
+       {\r
+               this.getTree().openPath(remainingPath, bSelect, bFocus);\r
+       }\r
+       else\r
+       {\r
+               // open\r
+               this.setExpanded(true);\r
+               if (this.loaded)\r
+               {\r
+                       parts = sPath.split("/");\r
+                       var ti = this.findChildByText(parts[0]);\r
+                       if (!ti)\r
+                               throw "Could not find child node with text \"" + parts[0] + "\"";\r
+\r
+                       ti.openPath(remainingPath, bSelect, bFocus);\r
+               }\r
+               else\r
+               {\r
+                       this._pathToOpen = sPath;\r
+               }\r
+       }\r
+};\r
+\r
+\r
+// Opera has some serious attribute problems. We need to use getAttribute\r
+// for certain attributes\r
+WebFXLoadTree._attrs = ["text", "src", "action", "id", "target"];\r
+\r
+WebFXLoadTree.createItemFromElement = function (oNode)\r
+{\r
+       var jsAttrs = {};\r
+       var domAttrs = oNode.attributes;\r
+       var i, l;\r
+\r
+       l = domAttrs.length;\r
+       for (i = 0; i < l; i++)\r
+       {\r
+               if (domAttrs[i] == null)\r
+               {\r
+                       continue;\r
+               }\r
+               jsAttrs[domAttrs[i].nodeName] = domAttrs[i].nodeValue;\r
+       }\r
+\r
+\r
+       var name, val;\r
+       for (i = 0; i < WebFXLoadTree._attrs.length; i++)\r
+       {\r
+               name = WebFXLoadTree._attrs[i];\r
+               value = oNode.getAttribute(name);\r
+               if (value)\r
+                       jsAttrs[name] = value;\r
+       }\r
+\r
+       var action;\r
+       if (jsAttrs.onaction)\r
+               action = new Function(jsAttrs.onaction);\r
+       else if (jsAttrs.action)\r
+               action = jsAttrs.action;\r
+       var jsNode = new WebFXLoadTreeItem(jsAttrs.html || "", jsAttrs.src, action,\r
+                                                                          null, jsAttrs.icon, jsAttrs.openIcon);\r
+       if (jsAttrs.text)\r
+               jsNode.setText(jsAttrs.text);\r
+\r
+       if (jsAttrs.target)\r
+               jsNode.target = jsAttrs.target;\r
+       if (jsAttrs.id)\r
+               jsNode.setId(jsAttrs.id);\r
+       if (jsAttrs.toolTip)\r
+               jsNode.toolTip = jsAttrs.toolTip;\r
+       if (jsAttrs.expanded)\r
+               jsNode.setExpanded(jsAttrs.expanded != "false");\r
+       if (jsAttrs.onload)\r
+               jsNode.onload = new Function(jsAttrs.onload);\r
+       if (jsAttrs.onerror)\r
+               jsNode.onerror = new Function(jsAttrs.onerror);\r
+\r
+       jsNode.attributes = jsAttrs;\r
+\r
+       // go through childNodes\r
+       var cs = oNode.childNodes;\r
+       l = cs.length;\r
+       for (i = 0; i < l; i++)\r
+       {\r
+               if (cs[i].tagName == "tree")\r
+                       jsNode.add(WebFXLoadTree.createItemFromElement(cs[i]));\r
+       }\r
+\r
+       return jsNode;\r
+};\r
+\r
+WebFXLoadTree.loadXmlDocument = function (jsNode)\r
+{\r
+       if (jsNode.loading || jsNode.loaded)\r
+               return;\r
+       jsNode.loading = true;\r
+       var id = jsNode.getId();\r
+       jsNode._xmlHttp = XmlHttp.create();\r
+       jsNode._xmlHttp.open("GET", jsNode.src, true);  // async\r
+       jsNode._xmlHttp.onreadystatechange = new Function("WebFXLoadTree._onload(\"" + id + "\")");\r
+\r
+       // call in new thread to allow ui to update\r
+       window.setTimeout("WebFXLoadTree._ontimeout(\"" + id + "\")", 10);\r
+};\r
+\r
+WebFXLoadTree._onload = function (sId)\r
+{\r
+       var jsNode = webFXTreeHandler.all[sId];\r
+       if (jsNode._xmlHttp.readyState == 4)\r
+       {\r
+               WebFXLoadTree.documentLoaded(jsNode);\r
+               webFXLoadTreeQueue.remove(jsNode);\r
+               if (jsNode._xmlHttp.dispose)\r
+                       jsNode._xmlHttp.dispose();\r
+               jsNode._xmlHttp = null;\r
+       }\r
+};\r
+\r
+WebFXLoadTree._ontimeout = function (sId)\r
+{\r
+       var jsNode = webFXTreeHandler.all[sId];\r
+       webFXLoadTreeQueue.add(jsNode);\r
+};\r
+\r
+\r
+\r
+// Inserts an xml document as a subtree to the provided node\r
+WebFXLoadTree.documentLoaded = function (jsNode)\r
+{\r
+       if (jsNode.loaded)\r
+               return;\r
+\r
+       jsNode.errorText = "";\r
+       jsNode.loaded = true;\r
+       jsNode.loading = false;\r
+\r
+       var t = jsNode.getTree();\r
+       var oldSuspend = t.getSuspendRedraw();\r
+       t.setSuspendRedraw(true);\r
+\r
+       var doc = jsNode._xmlHttp.responseXML;\r
+\r
+       // check that the load of the xml file went well\r
+       if(!doc || doc.parserError && doc.parseError.errorCode != 0 || !doc.documentElement)\r
+       {\r
+               if (!doc || doc.parseError.errorCode == 0)\r
+               {\r
+                       jsNode.errorText = webFXTreeConfig.errorLoadingText + " " + jsNode.src + " (" + jsNode._xmlHttp.status + ": " + jsNode._xmlHttp.statusText + ")";\r
+               }\r
+               else\r
+               {\r
+                       jsNode.errorText =  webFXTreeConfig.errorLoadingText + " " + jsNode.src + " (" + doc.parseError.reason + ")";\r
+               }\r
+       }\r
+       else\r
+       {\r
+               // there is one extra level of tree elements\r
+               var root = doc.documentElement;\r
+\r
+               // loop through all tree children\r
+               var count = 0;\r
+               var cs = root.childNodes;\r
+               var l = cs.length;\r
+               for (var i = 0; i < l; i++)\r
+               {\r
+                       if (cs[i].tagName == "tree")\r
+                       {\r
+                               jsNode.add(WebFXLoadTree.createItemFromElement(cs[i]));\r
+                               count++;\r
+                       }\r
+               }\r
+\r
+               // if no children we got an error\r
+               if (count == 0)\r
+               {\r
+                       jsNode.errorText =  webFXTreeConfig.errorLoadingText + " " + jsNode.src + " (???)";\r
+               }\r
+       }\r
+\r
+       if (jsNode.errorText != "")\r
+       {\r
+               jsNode._loadingItem.icon = webFXTreeConfig.errorIcon;\r
+               jsNode._loadingItem.text = jsNode.errorText;\r
+               jsNode._loadingItem.action = WebFXLoadTree._reloadParent;\r
+               jsNode._loadingItem.toolTip = webFXTreeConfig.reloadText;\r
+\r
+               t.setSuspendRedraw(oldSuspend);\r
+\r
+               jsNode._loadingItem.update();\r
+\r
+               if (typeof jsNode.onerror == "function")\r
+                       jsNode.onerror();\r
+       }\r
+       else\r
+       {\r
+               // remove dummy\r
+               if (jsNode._loadingItem != null)\r
+                       jsNode.remove(jsNode._loadingItem);\r
+\r
+               if (jsNode._pathToOpen)\r
+                       jsNode.openPath(jsNode._pathToOpen, jsNode._selectPathOnLoad, jsNode._focusPathOnLoad);\r
+\r
+               t.setSuspendRedraw(oldSuspend);\r
+               jsNode.update();\r
+               if (typeof jsNode.onload == "function")\r
+                       jsNode.onload();\r
+       }\r
+};\r
+\r
+WebFXLoadTree._reloadParent = function ()\r
+{\r
+       this.getParent().reload();\r
+};\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+var webFXLoadTreeQueue = {\r
+       _nodes: [],\r
+       _ie:    /msie/i.test(navigator.userAgent),\r
+       _opera: /opera/i.test(navigator.userAgent),\r
+\r
+       add: function (jsNode)\r
+       {\r
+               if (this._ie || this._opera)\r
+               {\r
+                       this._nodes.push(jsNode);\r
+                       if (this._nodes.length == 1)\r
+                               this._send();\r
+               }\r
+               else\r
+               {\r
+                       jsNode._xmlHttp.send(null);\r
+               }\r
+       },\r
+\r
+\r
+       remove: function (jsNode)\r
+       {\r
+               if (this._ie || this._opera)\r
+               {\r
+                       arrayHelper.remove(this._nodes, jsNode);\r
+                       if (this._nodes.length > 0)\r
+                               this._send();\r
+               }\r
+       },\r
+\r
+       // IE only\r
+       _send:  function ()\r
+       {\r
+               var id = this._nodes[0].getId();\r
+               var jsNode = webFXTreeHandler.all[id];\r
+               if (!jsNode)\r
+                       return;\r
+               // if no _xmlHttp then remove it\r
+               if (!jsNode._xmlHttp)\r
+                       this.remove(jsNode);\r
+               else\r
+                       jsNode._xmlHttp.send(null);\r
+       }\r
+};\r
diff --git a/xloadtree/xmlextras.js b/xloadtree/xmlextras.js
new file mode 100644 (file)
index 0000000..6a67512
--- /dev/null
@@ -0,0 +1,232 @@
+/*----------------------------------------------------------------------------\\r
+|                               XML Extras 1.01                               |\r
+|-----------------------------------------------------------------------------|\r
+|                         Created by Erik Arvidsson                           |\r
+|                  (http://webfx.eae.net/contact.html#erik)                   |\r
+|                      For WebFX (http://webfx.eae.net/)                      |\r
+|-----------------------------------------------------------------------------|\r
+| A library that makes working with XML documents in Mozilla more similar to  |\r
+| working with MSXML.                                                         |\r
+|-----------------------------------------------------------------------------|\r
+|                   Copyright (c) 1999 - 2003 Erik Arvidsson                  |\r
+|-----------------------------------------------------------------------------|\r
+| This software is provided "as is", without warranty of any kind, express or |\r
+| implied, including  but not limited  to the warranties of  merchantability, |\r
+| fitness for a particular purpose and noninfringement. In no event shall the |\r
+| authors or  copyright  holders be  liable for any claim,  damages or  other |\r
+| liability, whether  in an  action of  contract, tort  or otherwise, arising |\r
+| from,  out of  or in  connection with  the software or  the  use  or  other |\r
+| dealings in the software.                                                   |\r
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |\r
+| This  software is  available under the  three different licenses  mentioned |\r
+| below.  To use this software you must chose, and qualify, for one of those. |\r
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |\r
+| The WebFX Non-Commercial License          http://webfx.eae.net/license.html |\r
+| Permits  anyone the right to use the  software in a  non-commercial context |\r
+| free of charge.                                                             |\r
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |\r
+| The WebFX Commercial license           http://webfx.eae.net/commercial.html |\r
+| Permits the  license holder the right to use  the software in a  commercial |\r
+| context. Such license must be specifically obtained, however it's valid for |\r
+| any number of  implementations of the licensed software.                    |\r
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |\r
+| GPL - The GNU General Public License    http://www.gnu.org/licenses/gpl.txt |\r
+| Permits anyone the right to use and modify the software without limitations |\r
+| as long as proper  credits are given  and the original  and modified source |\r
+| code are included. Requires  that the final product, software derivate from |\r
+| the original  source or any  software  utilizing a GPL  component, such  as |\r
+| this, is also licensed under the GPL license.                               |\r
+|-----------------------------------------------------------------------------|\r
+| ????-??-?? | Original Version Posted.                                       |\r
+| 2003-09-25 | Added support for parseError getters. Also changed to extend   |\r
+|            | only XMLDocument instead of Document                           |\r
+|-----------------------------------------------------------------------------|\r
+| Created ????-??-?? | All changes are in the log above. | Updated 2003-09-25 |\r
+\----------------------------------------------------------------------------*/\r
+\r
+\r
+//////////////////\r
+// Helper Stuff //\r
+//////////////////\r
+\r
+// used to find the Automation server name\r
+function getDomDocumentPrefix() {\r
+       if (getDomDocumentPrefix.prefix)\r
+               return getDomDocumentPrefix.prefix;\r
+\r
+       var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];\r
+       var o;\r
+       for (var i = 0; i < prefixes.length; i++) {\r
+               try {\r
+                       // try to create the objects\r
+                       o = new ActiveXObject(prefixes[i] + ".DomDocument");\r
+                       return getDomDocumentPrefix.prefix = prefixes[i];\r
+               }\r
+               catch (ex) {};\r
+       }\r
+\r
+       throw new Error("Could not find an installed XML parser");\r
+}\r
+\r
+function getXmlHttpPrefix() {\r
+       if (getXmlHttpPrefix.prefix)\r
+               return getXmlHttpPrefix.prefix;\r
+\r
+       var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];\r
+       var o;\r
+       for (var i = 0; i < prefixes.length; i++) {\r
+               try {\r
+                       // try to create the objects\r
+                       o = new ActiveXObject(prefixes[i] + ".XmlHttp");\r
+                       return getXmlHttpPrefix.prefix = prefixes[i];\r
+               }\r
+               catch (ex) {};\r
+       }\r
+\r
+       throw new Error("Could not find an installed XML parser");\r
+}\r
+\r
+//////////////////////////\r
+// Start the Real stuff //\r
+//////////////////////////\r
+\r
+\r
+// XmlHttp factory\r
+function XmlHttp() {}\r
+\r
+XmlHttp.create = function () {\r
+       try {\r
+               if (window.XMLHttpRequest) {\r
+                       var req = new XMLHttpRequest();\r
+\r
+                       // some versions of Moz do not support the readyState property\r
+                       // and the onreadystate event so we patch it!\r
+                       if (req.readyState == null) {\r
+                               req.readyState = 1;\r
+                               req.addEventListener("load", function () {\r
+                                       req.readyState = 4;\r
+                                       if (typeof req.onreadystatechange == "function")\r
+                                               req.onreadystatechange();\r
+                               }, false);\r
+                       }\r
+\r
+                       return req;\r
+               }\r
+               if (window.ActiveXObject) {\r
+                       return new ActiveXObject(getXmlHttpPrefix() + ".XmlHttp");\r
+               }\r
+       }\r
+       catch (ex) {}\r
+       // fell through\r
+       throw new Error("Your browser does not support XmlHttp objects");\r
+};\r
+\r
+// XmlDocument factory\r
+function XmlDocument() {}\r
+\r
+XmlDocument.create = function () {\r
+       try {\r
+               // DOM2\r
+               if (document.implementation && document.implementation.createDocument) {\r
+                       var doc = document.implementation.createDocument("", "", null);\r
+\r
+                       // some versions of Moz do not support the readyState property\r
+                       // and the onreadystate event so we patch it!\r
+                       if (doc.readyState == null) {\r
+                               doc.readyState = 1;\r
+                               doc.addEventListener("load", function () {\r
+                                       doc.readyState = 4;\r
+                                       if (typeof doc.onreadystatechange == "function")\r
+                                               doc.onreadystatechange();\r
+                               }, false);\r
+                       }\r
+\r
+                       return doc;\r
+               }\r
+               if (window.ActiveXObject)\r
+                       return new ActiveXObject(getDomDocumentPrefix() + ".DomDocument");\r
+       }\r
+       catch (ex) {}\r
+       throw new Error("Your browser does not support XmlDocument objects");\r
+};\r
+\r
+// Create the loadXML method and xml getter for Mozilla\r
+if (window.DOMParser &&\r
+       window.XMLSerializer &&\r
+       window.Node && Node.prototype && Node.prototype.__defineGetter__) {\r
+\r
+       // XMLDocument did not extend the Document interface in some versions\r
+       // of Mozilla. Extend both!\r
+       //XMLDocument.prototype.loadXML =\r
+       XMLDocument.prototype.loadXML = function (s) {\r
+\r
+               // parse the string to a new doc\r
+               var doc2 = (new DOMParser()).parseFromString(s, "text/xml");\r
+\r
+               // remove all initial children\r
+               while (this.hasChildNodes())\r
+                       this.removeChild(this.lastChild);\r
+\r
+               // insert and import nodes\r
+               for (var i = 0; i < doc2.childNodes.length; i++) {\r
+                       this.appendChild(this.importNode(doc2.childNodes[i], true));\r
+               }\r
+       };\r
+\r
+\r
+       /*\r
+        * xml getter\r
+        *\r
+        * This serializes the DOM tree to an XML String\r
+        *\r
+        * Usage: var sXml = oNode.xml\r
+        *\r
+        */\r
+\r
+       // Node, should really be XMLNode but there is no such interface\r
+       Node.prototype.__defineGetter__("xml", function () {\r
+               return (new XMLSerializer()).serializeToString(this);\r
+       });\r
+\r
+       XMLDocument.prototype.__defineGetter__("parseError", function () {\r
+               var hasError = !this.documentElement ||\r
+                       this.documentElement.localName == "parsererror" &&\r
+                       this.documentElement.getAttribute("xmlns") == "http://www.mozilla.org/newlayout/xml/parsererror.xml";\r
+               var res = {\r
+                       errorCode:      0,\r
+                       filepos:        0,      // not supported\r
+                       line:           0,\r
+                       linepos:        0,\r
+                       reason:         "",\r
+                       srcText:        "",\r
+                       url:            ""\r
+               };\r
+               if (hasError) {\r
+                       res.errorCode = -1;\r
+                       try {\r
+                               res.srcText = this.getElementsByTagName("sourcetext")[0].firstChild.data;\r
+                               res.srcText = res.srcText.replace( /\n\-\^$/, "");\r
+                       }\r
+                       catch (ex) {\r
+                               res.srcText = "";\r
+                       }\r
+\r
+                       try {\r
+                               // now we need to parse the first text node\r
+                               var s = this.documentElement.firstChild.data;\r
+\r
+                               var re = /XML Parsing Error\: (.+)\nLocation\: (.+)\nLine Number (\d+)\, Column (\d+)/;\r
+                               var a = re.exec( s );\r
+                               res.reason = a[1];\r
+                               res.url = a[2];\r
+                               res.line = a[3];\r
+                               res.linepos = a[4];\r
+                       }\r
+                       catch (ex) {\r
+                               res.reason = "Uknown";\r
+                       }\r
+               }\r
+\r
+               return res;\r
+       });\r
+}
\ No newline at end of file
diff --git a/xloadtree/xtree2.js b/xloadtree/xtree2.js
new file mode 100644 (file)
index 0000000..26244ba
--- /dev/null
@@ -0,0 +1,1664 @@
+/*----------------------------------------------------------------------------\
+|                            XTree 2 PRE RELEASE                              |
+|                                                                             |
+| This is a pre release and redistribution is discouraged.                    |
+| Watch http://webfx.eae.net for the final version                            |
+|                                                                             |
+|-----------------------------------------------------------------------------|
+|                   Created by Erik Arvidsson & Emil A Eklund                 |
+|                  (http://webfx.eae.net/contact.html#erik)                   |
+|                  (http://webfx.eae.net/contact.html#emil)                   |
+|                      For WebFX (http://webfx.eae.net/)                      |
+|-----------------------------------------------------------------------------|
+| A tree menu system for IE 5.5+, Mozilla 1.4+, Opera 7, KHTML                |
+|-----------------------------------------------------------------------------|
+|         Copyright (c) 1999 - 2004 Erik Arvidsson & Emil A Eklund            |
+|-----------------------------------------------------------------------------|
+| This software is provided "as is", without warranty of any kind, express or |
+| implied, including  but not limited  to the warranties of  merchantability, |
+| fitness for a particular purpose and noninfringement. In no event shall the |
+| authors or  copyright  holders be  liable for any claim,  damages or  other |
+| liability, whether  in an  action of  contract, tort  or otherwise, arising |
+| from,  out of  or in  connection with  the software or  the  use  or  other |
+| dealings in the software.                                                   |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| This  software is  available under the  three different licenses  mentioned |
+| below.  To use this software you must chose, and qualify, for one of those. |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| The WebFX Non-Commercial License          http://webfx.eae.net/license.html |
+| Permits  anyone the right to use the  software in a  non-commercial context |
+| free of charge.                                                             |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| The WebFX Commercial license           http://webfx.eae.net/commercial.html |
+| Permits the  license holder the right to use  the software in a  commercial |
+| context. Such license must be specifically obtained, however it's valid for |
+| any number of  implementations of the licensed software.                    |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| GPL - The GNU General Public License    http://www.gnu.org/licenses/gpl.txt |
+| Permits anyone the right to use and modify the software without limitations |
+| as long as proper  credits are given  and the original  and modified source |
+| code are included. Requires  that the final product, software derivate from |
+| the original  source or any  software  utilizing a GPL  component, such  as |
+| this, is also licensed under the GPL license.                               |
+|-----------------------------------------------------------------------------|
+| 2004-02-21 | Pre release distributed to a few selected tester               |
+|-----------------------------------------------------------------------------|
+| Dependencies: xtree2.css Used to define the look and feel                   |
+|-----------------------------------------------------------------------------|
+| Created 2003-??-?? | All changes are in the log above. | Updated 2004-02-21 |
+\----------------------------------------------------------------------------*/
+
+
+//
+// WebFXTreePersisitance
+function WebFXTreePersistence() {}
+WebFXTreePersistence.prototype.getExpanded = function (oNode) { return false; };
+WebFXTreePersistence.prototype.setExpanded = function (oNode, bOpen) {};
+
+
+
+// Cookie handling
+function WebFXCookie() {}
+
+WebFXCookie.prototype.setCookie = function (sName, sValue, nDays)
+{
+       var expires = "";
+       if (typeof nDays == "number")
+       {
+               var d = new Date();
+               d.setTime(d.getTime() + nDays * 24 * 60 * 60 * 1000);
+               expires = "; expires=" + d.toGMTString();
+       }
+
+       document.cookie = sName + "=" + escape(sValue) + expires + "; path=/";
+};
+
+WebFXCookie.prototype.getCookie = function (sName)
+{
+       var re = new RegExp("(\;|^)[^;]*(" + sName + ")\=([^;]*)(;|$)");
+       var res = re.exec(document.cookie);
+       return res != null ? unescape(res[3]) : null;
+};
+
+WebFXCookie.prototype.removeCookie = function (name)
+{
+       this.setCookie(name, "", -1);
+};
+
+
+//
+// persistence using cookies
+//
+// This is uses one cookie with the ids of the expanded nodes separated using '+'
+//
+function WebFXTreeCookiePersistence()
+{
+       this._openedMap = {};
+       this._cookies = new WebFXCookie;
+       var s = this._cookies.getCookie(this.cookieName);
+       if (s)
+       {
+               var a = s.split("+");
+               for (var i = a.length - 1; i >= 0; i--)
+                       this._openedMap[a[i]] = true;
+       }
+}
+
+WebFXTreeCookiePersistence.prototype = new WebFXTreePersistence;
+
+WebFXTreeCookiePersistence.prototype.cookieName = "webfx-tree-cookie-persistence"
+
+WebFXTreeCookiePersistence.prototype.getExpanded = function (oNode)
+{
+       return oNode.id in this._openedMap;
+};
+
+WebFXTreeCookiePersistence.prototype.setExpanded = function (oNode, bOpen)
+{
+       var old = this.getExpanded(oNode);
+       if (old != bOpen)
+       {
+               if (bOpen)
+                       this._openedMap[oNode.id] = true;
+               else
+                       delete this._openedMap[oNode.id];
+
+               var res = [];
+               var i = 0;
+               for (var id in this._openedMap)
+                       res[i++] = id;
+               this._cookies.setCookie(this.cookieName, res.join("+"));
+       }
+};
+
+
+
+// this object provides a few useful methods when working with arrays
+var arrayHelper =
+{
+       indexOf:                function (a, o)
+       {
+               for (var i = 0; i < a.length; i++)
+               {
+                       if (a[i] == o)
+                               return i;
+               }
+               return -1;
+       },
+
+       insertBefore:   function (a, o, o2)
+       {
+               var i = this.indexOf(a, o2);
+               if (i == -1)
+                       a.push(o);
+               else
+                       a.splice(i, 0, o);
+       },
+
+       remove:                 function (a, o)
+       {
+               var i = this.indexOf(a, o);
+               if (i != -1)
+                       a.splice(i, 1);
+       }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// WebFX Tree Config object                                                  //
+///////////////////////////////////////////////////////////////////////////////
+var webFXTreeConfig = {
+       rootIcon        : 'images/folder.png',
+       openRootIcon    : 'images/openfolder.png',
+       folderIcon      : 'images/folder.png',
+       openFolderIcon  : 'images/openfolder.png',
+       fileIcon        : 'images/file.png',
+       iIcon           : 'images/I.png',
+       lIcon           : 'images/L.png',
+       lMinusIcon      : 'images/Lminus.png',
+       lPlusIcon       : 'images/Lplus.png',
+       tIcon           : 'images/T.png',
+       tMinusIcon      : 'images/Tminus.png',
+       tPlusIcon       : 'images/Tplus.png',
+       plusIcon        : 'images/plus.png',
+       minusIcon       : 'images/minus.png',
+       blankIcon       : 'images/blank.png',
+       defaultText     : 'Tree Item',
+       defaultAction   : null,
+       defaultBehavior : 'classic',
+       usePersistence  : true
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// WebFX Tree Handler object                                                 //
+///////////////////////////////////////////////////////////////////////////////
+
+var webFXTreeHandler = {
+       ie:             /msie/i.test(navigator.userAgent),
+       idCounter : 0,
+       idPrefix  : "wfxt-",
+       getUniqueId:    function ()
+       {
+               return this.idPrefix + this.idCounter++;
+       },
+       all       : {},
+       getNodeById:    function (sId)
+       {
+               return all[sId];
+       },
+       addNode:        function (oNode)
+       {
+               this.all[oNode.id] = oNode;
+       },
+       removeNode:     function (oNode)
+       {
+               delete this.all[oNode.id];
+       },
+
+       handleEvent:    function (e)
+       {
+               var el = e.target || e.srcElement;
+               while (el != null && !this.all[el.id])
+                       el = el.parentNode;
+
+               if (el == null)
+                       return false;
+               var node = this.all[el.id];
+               switch (e.type)
+               {
+                       case "mousedown":
+                               return node._onMouseDown(e);
+                       case "click":
+                               return node._onClick(e);
+                       case "dblclick":
+                               return node._onDblClick(e);
+                       case "focus":
+                               return node._onFocus(e);
+                       case "blur":
+                               return node._onBlur(e);
+                       case "keydown":
+                               return node._onKeyDown(e);
+                       case "keypress":
+                               return node._onKeyPress(e);
+               }
+               return false;
+       },
+
+       dispose:        function ()
+       {
+               if (this.disposed) return;
+               for (var id in this.all)
+                       this.all[id].dispose();
+               this.disposed = true;
+       },
+
+       opera:          /opera/i.test(navigator.userAgent),
+
+       htmlToText:             function (s)
+       {
+               return String(s).replace(/\s+|<([^>])+>|&amp;|&lt;|&gt;|&quot;|&nbsp;/gi, this._htmlToText);
+       },
+
+       _htmlToText:    function (s)
+       {
+               switch (s)
+               {
+                       case "&amp;":
+                               return "&";
+                       case "&lt;":
+                               return "<";
+                       case "&gt;":
+                               return ">";
+                       case "&quot;":
+                               return "\"";
+                       case "&nbsp;":
+                               return String.fromCharCode(160);
+                       default:
+                               if (/\s+/.test(s))
+                                       return " ";
+                               if (/^<BR/gi.test(s))
+                                       return "\n";
+                               return "";
+               }
+       },
+
+       textToHtml:             function (s)
+       {
+               return String(s).replace(/&|<|>|\n|\"\u00A0/g, this._textToHtml);
+       },
+
+       _textToHtml:    function (s)
+       {
+               switch (s)
+               {
+                       case "&":
+                               return "&amp;";
+                       case "<":
+                               return "&lt;";
+                       case ">":
+                               return "&gt;";
+                       case "\n":
+                               return "<BR>";
+                       case "\"":
+                               return "&quot;";        // so we can use this in attributes
+                       default:
+                               return "&nbsp;";
+               }
+       },
+
+       persistenceManager:     new WebFXTreeCookiePersistence()
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// WebFXTreeAbstractNode
+///////////////////////////////////////////////////////////////////////////////
+
+function WebFXTreeAbstractNode(sText, oAction)
+{
+       this.childNodes = [];
+       if (sText) this.text = sText;
+       if (oAction) this.action = oAction;
+       this.id = webFXTreeHandler.getUniqueId();
+       if (webFXTreeConfig.usePersistence)
+               this.open = webFXTreeHandler.persistenceManager.getExpanded(this);
+       webFXTreeHandler.addNode(this);
+}
+
+
+var _p = WebFXTreeAbstractNode.prototype;
+_p._selected = false;
+_p.indentWidth = 19;
+_p.open = false;
+_p.text = webFXTreeConfig.defaultText;
+_p.action = null;
+_p.target = null;
+_p.toolTip = null;
+_p._focused = false;
+
+/* begin tree model */
+
+_p.add = function (oChild, oBefore)
+{
+       var oldLast;
+       var emptyBefore = this.childNodes.length == 0;
+       var p = oChild.parentNode;
+
+       if (oBefore == null)
+       { // append
+               if (p != null)
+                       p.remove(oChild);
+               oldLast = this.getLastChild();
+               this.childNodes.push(oChild);
+       }
+       else
+       { // insertBefore
+               if (oBefore.parentNode != this)
+                       throw new Error("Can only add nodes before siblings");
+               if (p != null)
+                       p.remove(oChild);
+
+               arrayHelper.insertBefore(this.childNodes, oChild, oBefore);
+       }
+
+       oChild.parentNode = this;
+       var t = this.getTree();
+       if (t)
+               oChild.tree = t;
+       var d = this.getDepth();
+       if (d != null)
+               oChild.depth = d + 1;
+
+       if (this.getCreated() && !t.getSuspendRedraw())
+       {
+               var el = this.getChildrenElement();
+               var newEl = oChild.create();
+               var refEl = oBefore ? oBefore.getElement() : null;
+               el.insertBefore(newEl, refEl);
+
+               if (oldLast)
+               {
+                       oldLast.updateExpandIcon();
+               }
+               if (emptyBefore)
+               {
+                       this.setExpanded(this.getExpanded());
+                       // if we are using classic expand will not update icon
+                       if (t && t.getBehavior() != "classic")
+                               this.updateIcon();
+               }
+       }
+
+       return oChild;
+};
+
+
+
+_p.remove = function (oChild)
+{
+       // backwards compatible. If no argument remove the node
+       if (arguments.length == 0)
+       {
+               if (this.parentNode)
+                       return this.parentNode.remove(this);
+               return null;
+       }
+
+       // if we remove selected or tree with the selected we should select this
+       var t = this.getTree();
+       var si = t ? t.getSelected() : null;
+       if (si == oChild || oChild.contains(si))
+       {
+               if (si.getFocused())
+               {
+                       this.select();
+                       window.setTimeout("WebFXTreeAbstractNode._onTimeoutFocus(\"" + this.id + "\")", 10);
+               }
+               else
+                       this.select();
+       }
+
+       var wasLast = oChild.isLastSibling();
+
+       if (oChild.parentNode != this)
+               throw new Error("Can only remove children");
+       arrayHelper.remove(this.childNodes, oChild);
+
+       oChild.parentNode = null;
+       oChild.tree = null;
+       oChild.depth = null;
+
+       if (t && this.getCreated() && !t.getSuspendRedraw())
+       {
+               var el = this.getChildrenElement();
+               var childEl = oChild.getElement();
+               el.removeChild(childEl);
+               if (wasLast)
+               {
+                       var newLast = this.getLastChild();
+                       if (newLast)
+                               newLast.updateExpandIcon();
+               }
+               if (!this.hasChildren())
+               {
+                       //this.setExpanded(this.getExpanded());
+                       el.style.display = "none";
+                       this.updateExpandIcon();
+                       this.updateIcon();
+               }
+       }
+
+       return oChild;
+};
+
+WebFXTreeAbstractNode._onTimeoutFocus = function (sId)
+{
+       var jsNode = webFXTreeHandler.all[sId];
+       jsNode.focus();
+};
+
+_p.getId = function ()
+{
+       return this.id;
+};
+
+_p.getTree = function ()
+{
+       throw new Error("getTree called on Abstract Node");
+};
+
+_p.getDepth = function ()
+{
+       throw new Error("getDepth called on Abstract Node");
+};
+
+_p.getCreated = function ()
+{
+       var t = this.getTree();
+       return t && t.rendered;
+};
+
+_p.getParent = function ()
+{
+       return this.parentNode;
+};
+
+_p.contains = function (oDescendant)
+{
+       if (oDescendant == null) return false;
+       if (oDescendant == this) return true;
+       var p = oDescendant.parentNode;
+       return this.contains(p);
+};
+
+_p.getChildren = _p.getChildNodes = function ()
+{
+       return this.childNodes;
+};
+
+_p.getFirstChild = function ()
+{
+       return this.childNodes[0];
+};
+
+_p.getLastChild = function ()
+{
+       return this.childNodes[this.childNodes.length - 1];
+};
+
+_p.getPreviousSibling = function ()
+{
+       var p = this.parentNode;
+       if (p == null) return null;
+       var cs = p.childNodes;
+       return cs[arrayHelper.indexOf(cs, this) - 1]
+};
+
+_p.getNextSibling = function ()
+{
+       var p = this.parentNode;
+       if (p == null) return null;
+       var cs = p.childNodes;
+       return cs[arrayHelper.indexOf(cs, this) + 1]
+};
+
+_p.hasChildren = function ()
+{
+       return this.childNodes.length > 0;
+};
+
+
+_p.isLastSibling = function ()
+{
+       return this.parentNode && this == this.parentNode.getLastChild();
+};
+
+_p.findChildByText = function (s, n)
+{
+       if (!n)
+               n = 0;
+       var isRe = s instanceof RegExp;
+       for (var i = 0; i < this.childNodes.length; i++)
+       {
+               if (isRe && s.test(this.childNodes[i].getText()) || this.childNodes[i].getText() == s)
+               {
+                       if (n == 0)
+                               return this.childNodes[i];
+                       n--;
+               }
+       }
+       return null;
+};
+
+_p.findNodeByText = function (s, n)
+{
+       if (!n)
+               n = 0;
+       var isRe = s instanceof RegExp;
+
+       if (isRe && s.test(this.getText()) || this.getText() == s)
+       {
+               if (n == 0)
+                       return this.childNodes[i];
+               n--;
+       }
+
+       var res;
+       for (var i = 0; i < this.childNodes.length; i++)
+       {
+               res = this.childNodes[i].findNodeByText(s, n);
+               if (res)
+                       return res;
+       }
+       return null;
+};
+
+/* end tree model */
+
+_p.setId = function (sId)
+{
+       var el = this.getElement();
+       webFXTreeHandler.removeNode(this);
+       this.id = sId;
+       if (el)
+               el.id = sId;
+       webFXTreeHandler.addNode(this);
+};
+
+_p.isSelected = function ()
+{
+       return this._selected;
+};
+
+_p.select = function () { this._setSelected(true); };
+_p.deselect = function () { this._setSelected(false); };
+
+_p._setSelected = function (b)
+{
+       var t = this.getTree();
+       if (!t) return;
+       if (this._selected != b)
+       {
+               this._selected = b;
+
+               var wasFocused = false; // used to keep focus state
+               var si = t.getSelected();
+               if (b && si != null && si != this)
+               {
+                       var oldFireChange = t._fireChange;
+                       wasFocused = si._focused;
+                       t._fireChange = false;
+                       si._setSelected(false);
+                       t._fireChange = oldFireChange;
+               }
+
+               var el = this.getRowElement();
+               if (el)
+               {
+                       el.className = this.getRowClassName();
+               }
+               if (b)
+               {
+                       t._selectedItem = this;
+                       t._fireOnChange();
+                       t.setSelected(this);
+                       if (wasFocused)
+                               this.focus();
+               }
+
+               if (t.getBehavior() != "classic")
+                       this.updateIcon();
+       }
+};
+
+
+_p.getExpanded = function ()
+{
+       return this.open;
+};
+
+_p.setExpanded = function (b)
+{
+       var ce;
+       this.open = b;
+       var t = this.getTree();
+       if (this.hasChildren())
+       {
+               var si = t ? t.getSelected() : null;
+               if (!b && this.contains(si))
+                       this.select();
+
+               var el = this.getElement();
+               if (el)
+               {
+                       ce = this.getChildrenElement();
+                       if (ce)
+                               ce.style.display = b ? "block" : "none";
+                       var eie = this.getExpandIconElement();
+                       if (eie)
+                               eie.src = this.getExpandIconSrc();
+               }
+
+               if (webFXTreeConfig.usePersistence)
+                       webFXTreeHandler.persistenceManager.setExpanded(this, b);
+       }
+       else
+       {
+               ce = this.getChildrenElement();
+               if (ce)
+                       ce.style.display = "none";
+       }
+       if (t && t.getBehavior() == "classic")
+               this.updateIcon();
+};
+
+_p.toggle = function ()
+{
+       this.setExpanded(!this.getExpanded());
+};
+
+_p.expand = function ()
+{
+       this.setExpanded(true);
+};
+
+_p.collapse = function ()
+{
+       this.setExpanded(false);
+};
+
+_p.collapseChildren = function()
+{
+       var cs = this.childNodes;
+       for (var i = 0; i < cs.length; i++)
+               cs[i].collapseAll();
+};
+
+_p.collapseAll = function()
+{
+       this.collapseChildren();
+       this.collapse();
+};
+
+_p.expandChildren = function()
+{
+       var cs = this.childNodes;
+       for (var i = 0; i < cs.length; i++)
+               cs[i].expandAll();
+};
+
+_p.expandAll = function ()
+{
+       this.expandChildren();
+       this.expand();
+};
+
+_p.reveal = function ()
+{
+       var p = this.getParent();
+       if (p)
+       {
+               p.setExpanded(true);
+               p.reveal();
+       }
+};
+
+_p.openPath = function (sPath, bSelect, bFocus)
+{
+       if (sPath == "")
+       {
+               if (bSelect)
+                       this.select();
+               if (bFocus)
+                       window.setTimeout("WebFXTreeAbstractNode._onTimeoutFocus(\"" + this.id + "\")", 10);
+               return;
+       }
+
+       var parts = sPath.split("/");
+       var remainingPath = parts.slice(1).join("/");
+       var t = this.getTree();
+       if (sPath.charAt(0) == "/")
+       {
+               if (t)
+                       t.openPath(remainingPath, bSelect, bFocus);
+               else
+                       throw "Invalid path";
+       }
+       else
+       {
+               // open
+               this.setExpanded(true);
+               parts = sPath.split("/");
+               var ti = this.findChildByText(parts[0]);
+               if (!ti)
+                       throw "Could not find child node with text \"" + parts[0] + "\"";
+               ti.openPath(remainingPath, bSelect, bFocus);
+       }
+};
+
+_p.focus = function ()
+{
+       var el = this.getLabelElement();
+       if (el)
+               el.focus();
+};
+
+_p.getFocused = function ()
+{
+       return this._focused;
+};
+
+// HTML generation
+
+_p.toHtml = function ()
+{
+       var childrenSb = [];
+       var cs = this.childNodes;
+       var l = cs.length;
+       for (var y = 0; y < l; y++)
+               childrenSb[y] = cs[y].toHtml();
+
+       var t = this.getTree();
+       var hideLines = !t.getShowLines() || t == this.parentNode && !t.getShowRootLines();
+
+       var childrenHtml = "<div class=\"webfx-tree-children" +
+               (hideLines ? "-nolines" : "") + "\" style=\"" +
+               this.getLineStyle() +
+               (this.getExpanded() && this.hasChildren() ? "" : "display:none;") +
+               "\">" +
+               childrenSb.join("") +
+               "</div>";
+
+       return "<div class=\"webfx-tree-item\" id=\"" +
+               this.id + "\"" + this.getEventHandlersHtml() + ">" +
+               this.getRowHtml() +
+               childrenHtml +
+               "</div>";
+};
+
+_p.getRowHtml = function ()
+{
+       var t = this.getTree();
+       return "<div class=\"" + this.getRowClassName() + "\" style=\"padding-left:" +
+               (this.getDepth() - 1) * this.indentWidth + "px\">" +
+               this.getExpandIconHtml() +
+               //"<span class=\"webfx-tree-icon-and-label\">" +
+               this.getIconHtml() +
+               this.getLabelHtml() +
+               //"</span>" +
+               "</div>";
+};
+
+_p.getRowClassName = function ()
+{
+       return "webfx-tree-row" + (this.isSelected() ? " selected" : "") +
+               (this.action ? "" : " no-action");
+};
+
+_p.getLabelHtml = function ()
+{
+       var toolTip = this.getToolTip();
+       var target = this.getTarget();
+       return "<a href=\"" + webFXTreeHandler.textToHtml(this._getHref()) +
+               "\" class=\"webfx-tree-item-label\"" +
+               (toolTip ? " title=\"" + webFXTreeHandler.textToHtml(toolTip) + "\"" : "") +
+               (target ? " target=\"" + target + "\"" : "") +
+               " onfocus=\"webFXTreeHandler.handleEvent(event)\"" +
+               " onblur=\"webFXTreeHandler.handleEvent(event)\">" +
+               this.getHtml() + "</a>";
+};
+
+_p._getHref = function ()
+{
+       if (typeof this.action == "string")
+               return this.action;
+       else
+               return "#";
+};
+
+_p.getEventHandlersHtml = function ()
+{
+       return "";
+};
+
+_p.getIconHtml = function ()
+{
+       // here we are not using textToHtml since the file names rarerly contains
+       // HTML...
+       return "<img class=\"webfx-tree-icon\" src=\"" + this.getIconSrc() + "\">";
+};
+
+_p.getIconSrc = function ()
+{
+       throw new Error("getIconSrc called on Abstract Node");
+};
+
+_p.getExpandIconHtml = function ()
+{
+       // here we are not using textToHtml since the file names rarerly contains
+       // HTML...
+       return "<img class=\"webfx-tree-expand-icon\" src=\"" +
+               this.getExpandIconSrc() + "\">";
+};
+
+
+_p.getExpandIconSrc = function ()
+{
+       var src;
+       var t = this.getTree();
+       var hideLines = !t.getShowLines() || t == this.parentNode && !t.getShowRootLines();
+
+       if (this.hasChildren())
+       {
+               var bits = 0;
+               /*
+                       Bitmap used to determine which icon to use
+                       1  Plus
+                       2  Minus
+                       4  T Line
+                       8  L Line
+               */
+
+               if (t && t.getShowExpandIcons())
+               {
+                       if (this.getExpanded())
+                               bits = 2;
+                       else
+                               bits = 1;
+               }
+
+               if (t && !hideLines)
+               {
+                       if (this.isLastSibling())
+                               bits += 4;
+                       else
+                               bits += 8;
+               }
+
+               switch (bits)
+               {
+                       case 1:
+                               return webFXTreeConfig.plusIcon;
+                       case 2:
+                               return webFXTreeConfig.minusIcon;
+                       case 4:
+                               return webFXTreeConfig.lIcon;
+                       case 5:
+                               return webFXTreeConfig.lPlusIcon;
+                       case 6:
+                               return webFXTreeConfig.lMinusIcon;
+                       case 8:
+                               return webFXTreeConfig.tIcon;
+                       case 9:
+                               return webFXTreeConfig.tPlusIcon;
+                       case 10:
+                               return webFXTreeConfig.tMinusIcon;
+                       default:        // 0
+                               return webFXTreeConfig.blankIcon;
+               }
+       }
+       else
+       {
+               if (t && hideLines)
+                       return webFXTreeConfig.blankIcon;
+               else if (this.isLastSibling())
+                       return webFXTreeConfig.lIcon;
+               else
+                       return webFXTreeConfig.tIcon;
+       }
+};
+
+_p.getLineStyle = function ()
+{
+       return "background-position:" + this.getLineStyle2() + ";";
+};
+
+_p.getLineStyle2 = function ()
+{
+       return (this.isLastSibling() ? "-100" : (this.getDepth() - 1) * this.indentWidth) + "px 0";
+};
+
+// End HTML generation
+
+// DOM
+// this returns the div for the tree node
+_p.getElement = function ()
+{
+       return document.getElementById(this.id);
+};
+
+// the row is the div that is used to draw the node without the children
+_p.getRowElement = function ()
+{
+       var el = this.getElement();
+       if (!el) return null;
+       return el.firstChild;
+};
+
+// plus/minus image
+_p.getExpandIconElement = function ()
+{
+       var el = this.getRowElement();
+       if (!el) return null;
+       return el.firstChild;
+};
+
+_p.getIconElement = function ()
+{
+       var el = this.getRowElement();
+       if (!el) return null;
+       return el.childNodes[1];
+};
+
+// anchor element
+_p.getLabelElement = function ()
+{
+       var el = this.getRowElement();
+       if (!el) return null;
+       return el.lastChild;
+};
+
+// the div containing the children
+_p.getChildrenElement = function ()
+{
+       var el = this.getElement();
+       if (!el) return null;
+       return el.lastChild;
+};
+
+
+// IE uses about:blank if not attached to document and this can cause Win2k3
+// to fail
+if (webFXTreeHandler.ie)
+{
+       _p.create = function ()
+       {
+               var dummy = document.createElement("div");
+               dummy.style.display = "none";
+               document.body.appendChild(dummy);
+               dummy.innerHTML = this.toHtml();
+               var res = dummy.removeChild(dummy.firstChild);
+               document.body.removeChild(dummy);
+               return res;
+       };
+}
+else
+{
+       _p.create = function ()
+       {
+               var dummy = document.createElement("div");
+               dummy.innerHTML = this.toHtml();
+               return dummy.removeChild(dummy.firstChild);
+       };
+
+}
+
+// Getters and setters for some common fields
+
+_p.setIcon = function (s)
+{
+       this.icon = s;
+       if (this.getCreated())
+               this.updateIcon();
+};
+
+_p.getIcon = function ()
+{
+       return this.icon;
+};
+
+_p.setOpenIcon = function (s)
+{
+       this.openIcon = s;
+       if (this.getCreated())
+               this.updateIcon();
+};
+
+_p.getOpenIcon = function ()
+{
+       return this.openIcon;
+};
+
+_p.setText = function (s)
+{
+       this.setHtml(webFXTreeHandler.textToHtml(s));
+};
+
+_p.getText = function ()
+{
+       return webFXTreeHandler.htmlToText(this.getHtml());
+};
+
+_p.setHtml = function (s)
+{
+       this.text = s;
+       var el = this.getLabelElement();
+       if (el)
+               el.innerHTML = s;
+};
+
+_p.getHtml = function ()
+{
+       return this.text;
+};
+
+_p.setTarget = function (s)
+{
+       this.target = s;
+};
+
+_p.getTarget = function ()
+{
+       return this.target;
+};
+
+_p.setToolTip = function (s)
+{
+       this.toolTip = s;
+       var el = this.getLabelElement();
+       if (el)
+               el.title = s;
+};
+
+_p.getToolTip = function ()
+{
+       return this.toolTip;
+};
+
+_p.setAction = function (oAction)
+{
+       this.action = oAction;
+       var el = this.getLabelElement();
+       if (el)
+               el.href = this._getHref();
+       el = this.getRowElement();
+       if (el)
+               el.className = this.getRowClassName();
+};
+
+_p.getAction = function ()
+{
+       return this.action;
+};
+
+// update methods
+
+_p.update = function ()
+{
+       var t = this.getTree();
+       if (t.suspendRedraw) return;
+       var el = this.getElement();
+       if (!el || !el.parentNode) return;
+       var newEl = this.create();
+       el.parentNode.replaceChild(newEl, el);
+
+       var si = t.getSelected();
+       if (si && si.getFocused())
+               si.focus();
+};
+
+_p.updateExpandIcon = function ()
+{
+       var t = this.getTree();
+       if (t.suspendRedraw) return;
+       var img = this.getExpandIconElement();
+       img.src = this.getExpandIconSrc();
+       var cel = this.getChildrenElement();
+       cel.style.backgroundPosition = this.getLineStyle2();
+};
+
+_p.updateIcon = function ()
+{
+       var t = this.getTree();
+       if (t.suspendRedraw) return;
+       var img = this.getIconElement();
+       img.src = this.getIconSrc();
+};
+
+// End DOM
+
+
+_p._callSuspended = function (f)
+{
+       var t = this.getTree();
+       var sr = t.getSuspendRedraw();
+       t.setSuspendRedraw(true);
+       f.call(this);
+       t.setSuspendRedraw(sr);
+};
+
+// Event handlers
+
+_p._onMouseDown = function (e)
+{
+       var el = e.target || e.srcElement;
+       // expand icon
+       if (/webfx-tree-expand-icon/.test(el.className) && this.hasChildren())
+       {
+               this.toggle();
+               if ( webFXTreeHandler.ie )
+                       window.setTimeout("WebFXTreeAbstractNode._onTimeoutFocus(\"" + this.id + "\")", 10);
+               return false;
+       }
+
+       this.select();
+       if (!/webfx-tree-item-label/.test(el.className) && !webFXTreeHandler.opera)     // opera cancels the click if focus is called
+       {
+               // in case we are not clicking on the label
+               if (webFXTreeHandler.ie)
+                       window.setTimeout("WebFXTreeAbstractNode._onTimeoutFocus(\"" + this.id + "\")", 10);
+               else
+                       this.focus();
+       }
+       var rowEl = this.getRowElement();
+       if (rowEl)
+               rowEl.className = this.getRowClassName();
+
+       return false;
+};
+
+_p._onClick = function (e)
+{
+       var el = e.target || e.srcElement;
+       // expand icon
+       if (/webfx-tree-expand-icon/.test(el.className) && this.hasChildren())
+               return false;
+
+       if (typeof this.action == "function")
+               this.action();
+       else if (this.action != null)
+               window.open(this.action, this.target || "_self");
+       return false;
+};
+
+
+_p._onDblClick = function (e)
+{
+       var el = e.target || e.srcElement;
+       // expand icon
+       if (/webfx-tree-expand-icon/.test(el.className) && this.hasChildren())
+               return;
+
+       this.toggle();
+};
+
+_p._onFocus = function (e)
+{
+       this.select();
+       this._focused = true;
+};
+
+_p._onBlur = function (e)
+{
+       this._focused = false;
+};
+
+_p._onKeyDown = function (e)
+{
+       var n;
+       var rv = true;
+       switch (e.keyCode)
+       {
+               case 39:        // RIGHT
+                       if (e.altKey)
+                       {
+                               rv = true;
+                               break;
+                       }
+                       if (this.hasChildren())
+                       {
+                               if (!this.getExpanded())
+                                       this.setExpanded(true);
+                               else
+                               {
+                                       this.getFirstChild().focus();
+                               }
+                       }
+                       rv = false;
+                       break;
+               case 37:        // LEFT
+                       if (e.altKey)
+                       {
+                               rv = true;
+                               break;
+                       }
+                       if (this.hasChildren() && this.getExpanded())
+                               this.setExpanded(false);
+                       else
+                       {
+                               var p = this.getParent();
+                               var t = this.getTree();
+                               // don't go to root if hidden
+                               if (p && (t.showRootNode || p != t))
+                               {
+                                       p.focus();
+                               }
+                       }
+                       rv = false;
+                       break;
+
+               case 40:        // DOWN
+                       n = this.getNextShownNode();
+                       if (n)
+                       {
+                               n.focus();
+                       }
+                       rv = false;
+                       break;
+               case 38:        // UP
+                       n = this.getPreviousShownNode()
+                       if (n)
+                       {
+                               n.focus();
+                       }
+                       rv = false;
+                       break;
+       }
+
+       if (!rv && e.preventDefault)
+               e.preventDefault();
+       e.returnValue = rv;
+       return rv;
+};
+
+_p._onKeyPress = function (e)
+{
+       if (!e.altKey && e.keyCode >= 37 && e.keyCode <= 40)
+       {
+               if (e.preventDefault)
+                       e.preventDefault();
+               e.returnValue = false;
+               return false;
+       }
+};
+
+// End event handlers
+
+_p.dispose = function ()
+{
+       if (this.disposed) return;
+       for (var i = this.childNodes.length - 1; i >= 0; i--)
+               this.childNodes[i].dispose();
+       this.tree = null;
+       this.parentNode = null;
+       this.childNodes = null;
+       this.disposed = true;
+};
+
+// Some methods that are usable when navigating the tree using the arrows
+_p.getLastShownDescendant = function ()
+{
+       if (!this.getExpanded() || !this.hasChildren())
+               return this;
+       // we know there is at least 1 child
+       return this.getLastChild().getLastShownDescendant();
+};
+
+_p.getNextShownNode = function ()
+{
+       if (this.hasChildren() && this.getExpanded())
+               return this.getFirstChild();
+       else
+       {
+               var p = this;
+               var next;
+               while (p != null)
+               {
+                       next = p.getNextSibling();
+                       if (next != null)
+                               return next;
+                       p = p.getParent();
+               }
+               return null;
+       }
+};
+
+_p.getPreviousShownNode = function ()
+{
+       var ps = this.getPreviousSibling();
+       if (ps != null)
+       {
+               return ps.getLastShownDescendant();
+       }
+       var p = this.getParent();
+       var t = this.getTree();
+       if (!t.showRootNode && p == t)
+               return null;
+       return p;
+};
+
+
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// WebFXTree
+///////////////////////////////////////////////////////////////////////////////
+
+function WebFXTree(sText, oAction, sBehavior, sIcon, sOpenIcon)
+{
+       WebFXTreeAbstractNode.call(this, sText, oAction);
+
+       if (sIcon)
+               this.icon = sIcon;
+       if (sOpenIcon)
+               this.openIcon = sOpenIcon;
+       if (sBehavior)
+               this.behavior = sBehavior;
+}
+
+_p = WebFXTree.prototype = new WebFXTreeAbstractNode;
+_p.indentWidth = 19;
+_p.open = true;
+_p._selectedItem = null;
+_p._fireChange = true;
+_p.rendered = false;
+_p.suspendRedraw = false;
+_p.showLines = true;
+_p.showExpandIcons = true;
+_p.showRootNode = true;
+_p.showRootLines = true;
+
+_p.getTree = function ()
+{
+       return this;
+};
+
+_p.getDepth = function ()
+{
+       return 0;
+};
+
+_p.getCreated = function ()
+{
+       return this.rendered;
+};
+
+
+/* end tree model */
+
+_p.getExpanded = function ()
+{
+       return !this.showRootNode || WebFXTreeAbstractNode.prototype.getExpanded.call(this);
+};
+
+_p.setExpanded = function (b)
+{
+       if (!this.showRootNode)
+               this.open = b;
+       else
+               WebFXTreeAbstractNode.prototype.setExpanded.call(this, b);
+};
+
+_p.getExpandIconHtml = function ()
+{
+       return "";
+};
+
+// we don't have an expand icon here
+_p.getIconElement = function ()
+{
+       var el = this.getRowElement();
+       if (!el) return null;
+       return el.firstChild;
+};
+
+// no expand icon for root element
+_p.getExpandIconElement = function (oDoc)
+{
+       return null;
+};
+
+_p.updateExpandIcon = function ()
+{
+       // no expand icon
+};
+
+_p.getRowClassName = function ()
+{
+       return WebFXTreeAbstractNode.prototype.getRowClassName.call(this) +
+               (this.showRootNode ? "" : " webfx-tree-hide-root");
+};
+
+
+// if classic then the openIcon is used for expanded, otherwise openIcon is used
+// for selected
+
+_p.getIconSrc = function ()
+{
+       var behavior = this.getTree() ? this.getTree().getBehavior() : webFXTreeConfig.defaultBehavior;
+       var open = behavior == "classic" && this.getExpanded() ||
+                          behavior != "classic" && this.isSelected();
+       if (open && this.openIcon)
+               return this.openIcon;
+       if (!open && this.icon)
+               return this.icon;
+       // fall back on default icons
+       return open ? webFXTreeConfig.openRootIcon : webFXTreeConfig.rootIcon;
+};
+
+_p.getEventHandlersHtml = function ()
+{
+       return " onclick=\"return webFXTreeHandler.handleEvent(event)\" " +
+               "onmousedown=\"return webFXTreeHandler.handleEvent(event)\" " +
+               "ondblclick=\"return webFXTreeHandler.handleEvent(event)\" " +
+               "onkeydown=\"return webFXTreeHandler.handleEvent(event)\" " +
+               "onkeypress=\"return webFXTreeHandler.handleEvent(event)\"";
+};
+
+_p.setSelected = function (o)
+{
+       if (this._selectedItem != o)
+       {
+               if (o)
+                       o._setSelected(true);
+       }
+};
+
+_p._fireOnChange = function ()
+{
+       if (this._fireChange && typeof this.onchange == "function")
+               this.onchange();
+};
+
+_p.getSelected = function ()
+{
+       return this._selectedItem;
+};
+
+_p.setBehavior = function (s)
+{
+       this.behavior = s;
+};
+
+_p.getBehavior = function ()
+{
+       return this.behavior || webFXTreeConfig.defaultBehavior;
+};
+
+_p.setShowLines = function (b)
+{
+       if (this.showLines != b)
+       {
+               this.showLines = b;
+               if (this.rendered)
+                       this.update();
+       }
+};
+
+_p.getShowLines = function ()
+{
+       return this.showLines;
+};
+
+_p.setShowRootLines = function (b)
+{
+       if (this.showRootLines != b)
+       {
+               this.showRootLines = b;
+               if (this.rendered)
+                       this.update();
+       }
+};
+
+_p.getShowRootLines = function ()
+{
+       return this.showRootLines;
+};
+
+_p.setShowExpandIcons = function (b)
+{
+       if (this.showExpandIcons != b)
+       {
+               this.showExpandIcons = b;
+               if (this.rendered)
+                       this.getTree().update();
+       }
+};
+
+_p.getShowExpandIcons = function ()
+{
+       return this.showExpandIcons;
+};
+
+_p.setShowRootNode = function (b)
+{
+       if (this.showRootNode != b)
+       {
+               this.showRootNode = b;
+               if (this.rendered)
+                       this.getTree().update();
+       }
+};
+
+_p.getShowRoootNode = function ()
+{
+       return this.showRootNode;
+};
+
+_p.onchange = function () {};
+
+_p.create = function ()
+{
+       var el = WebFXTreeAbstractNode.prototype.create.call(this);
+       this.rendered = true;
+       return el;
+};
+
+_p.write = function ()
+{
+       document.write(this.toHtml());
+       this.rendered = true;
+};
+
+_p.setSuspendRedraw = function (b)
+{
+       this.suspendRedraw = b;
+};
+
+_p.getSuspendRedraw = function ()
+{
+       return this.suspendRedraw;
+};
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// WebFXTreeItem
+///////////////////////////////////////////////////////////////////////////////
+
+function WebFXTreeItem(sText, oAction, eParent, sIcon, sOpenIcon)
+{
+       WebFXTreeAbstractNode.call(this, sText, oAction);
+       if (sIcon)
+               this.icon = sIcon;
+       if (sOpenIcon)
+               this.openIcon = sOpenIcon;
+       if (eParent)
+               eParent.add(this);
+}
+
+_p = WebFXTreeItem.prototype = new WebFXTreeAbstractNode;
+_p.tree = null;
+
+/* tree model */
+
+_p.getDepth = function ()
+{
+       if (this.depth != null)
+               return this.depth;
+       if (this.parentNode)
+       {
+               var pd = this.parentNode.getDepth();
+               return this.depth = (pd != null ? pd + 1 : null);
+       }
+       return null;
+};
+
+_p.getTree = function ()
+{
+       if (this.tree)
+               return this.tree;
+       if (this.parentNode)
+               return this.tree = this.parentNode.getTree();
+       return null;
+};
+
+_p.getCreated = function ()
+{
+       var t = this.getTree();
+       return t && t.getCreated();
+};
+
+// if classic then the openIcon is used for expanded, otherwise openIcon is used
+// for selected
+_p.getIconSrc = function ()
+{
+       var behavior = this.getTree() ? this.getTree().getBehavior() : webFXTreeConfig.defaultBehavior;
+       var open = behavior == "classic" && this.getExpanded() ||
+                  behavior != "classic" && this.isSelected();
+       if (open && this.openIcon)
+               return this.openIcon;
+       if (!open && this.icon)
+               return this.icon;
+
+       // fall back on default icons
+       if (this.hasChildren())
+               return open ? webFXTreeConfig.openFolderIcon : webFXTreeConfig.folderIcon;
+       return webFXTreeConfig.fileIcon;
+};
+
+/* end tree model */
+
+
+
+
+if (window.attachEvent)
+{
+       window.attachEvent("onunload", function ()
+       {
+               for (var id in webFXTreeHandler.all)
+                       webFXTreeHandler.all[id].dispose();
+       });
+}