Author: spadkins
Date: Wed Mar  5 06:57:20 2008
New Revision: 10880

Added:
   p5ee/trunk/App-Widget-ExtJS/
   p5ee/trunk/App-Widget-ExtJS/CHANGES
   p5ee/trunk/App-Widget-ExtJS/MANIFEST
   p5ee/trunk/App-Widget-ExtJS/MANIFEST.SKIP
   p5ee/trunk/App-Widget-ExtJS/META.yml
   p5ee/trunk/App-Widget-ExtJS/Makefile.PL
   p5ee/trunk/App-Widget-ExtJS/README   (contents, props changed)
   p5ee/trunk/App-Widget-ExtJS/TODO
   p5ee/trunk/App-Widget-ExtJS/lib/
   p5ee/trunk/App-Widget-ExtJS/lib/App/
   p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/
   p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/
   p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS.pm
   p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/DataTable.pm
   p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/Date.pm
   p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/DualSelectWidget.pm
   p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/TabbedAppFrame.pm
   p5ee/trunk/App-Widget-ExtJS/t/
   p5ee/trunk/App-Widget-ExtJS/t/main.t   (contents, props changed)

Log:
new

Added: p5ee/trunk/App-Widget-ExtJS/CHANGES
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Widget-ExtJS/CHANGES Wed Mar  5 06:57:20 2008
@@ -0,0 +1,7 @@
+#########################################
+# CHANGE LOG
+#########################################
+
+VERSION 0.50
+ o initial release
+

Added: p5ee/trunk/App-Widget-ExtJS/MANIFEST
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Widget-ExtJS/MANIFEST        Wed Mar  5 06:57:20 2008
@@ -0,0 +1,8 @@
+CHANGES
+lib/App/Widget/ExtJS.pm
+Makefile.PL
+MANIFEST
+META.yml                       Module meta-data (added by MakeMaker)
+README
+t/main.t
+TODO

Added: p5ee/trunk/App-Widget-ExtJS/MANIFEST.SKIP
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Widget-ExtJS/MANIFEST.SKIP   Wed Mar  5 06:57:20 2008
@@ -0,0 +1,12 @@
+~$
+^MANIFEST\.
+^Makefile$
+^blib/
+^pm_to_blib$
+\.old$
+\.bak$
+\.cvsignore$
+\.tar\.gz$
+\.svn
+htdocs/.exists
+CVS/

Added: p5ee/trunk/App-Widget-ExtJS/META.yml
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Widget-ExtJS/META.yml        Wed Mar  5 06:57:20 2008
@@ -0,0 +1,11 @@
+# http://module-build.sourceforge.net/META-spec.html
+#XXXXXXX This is a prototype!!!  It will change in the future!!! XXXXX#
+name:         App-Widget-ExtJS
+version:      0.50
+version_from: 
+installdirs:  site
+requires:
+    App::Widget:                   0
+
+distribution_type: module
+generated_by: ExtUtils::MakeMaker version 6.17

Added: p5ee/trunk/App-Widget-ExtJS/Makefile.PL
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Widget-ExtJS/Makefile.PL     Wed Mar  5 06:57:20 2008
@@ -0,0 +1,22 @@
+
+######################################################################
+## File: $Id: Makefile.PL 6707 2006-07-25 02:21:19Z spadkins $
+######################################################################
+
+use ExtUtils::MakeMaker;
+# See lib/ExtUtils/MakeMaker.pm for details of how to influence
+# the contents of the Makefile that is written.
+
+%opts = (
+    'NAME'        => 'App-Widget-ExtJS',
+    'DISTNAME'    => 'App-Widget-ExtJS',
+    'VERSION'     => '0.50',
+    'PREREQ_PM'   => { 'Alien::ExtJS' => 0, },
+);
+
+######################################################################
+# MAKE THE MAKEFILE
+######################################################################
+
+WriteMakefile(%opts);
+

Added: p5ee/trunk/App-Widget-ExtJS/README
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Widget-ExtJS/README  Wed Mar  5 06:57:20 2008
@@ -0,0 +1,23 @@
+######################################################################
+## File: $Id: README 3468 2005-08-09 19:46:51Z spadkins $
+######################################################################
+
+WHAT IS THIS?
+
+This is the App-Widget-ExtJS distribution.
+It incorporates the JavaScripted ExtJS widgets
+
+   http://www.extjs.com
+
+into the App-Widget world of the App-Context framework.
+
+HOW DO I INSTALL IT?
+
+To install this module, cd to the directory that contains this README
+file and type the following:
+
+   perl Makefile.PL
+   make
+   make test
+   make install
+

Added: p5ee/trunk/App-Widget-ExtJS/TODO
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Widget-ExtJS/TODO    Wed Mar  5 06:57:20 2008
@@ -0,0 +1,7 @@
+######################################################################
+## File: $Id: TODO 3468 2005-08-09 19:46:51Z spadkins $
+######################################################################
+
+To get to Version 1.0
+ o tbd
+

Added: p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS.pm
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS.pm Wed Mar  5 06:57:20 2008
@@ -0,0 +1,398 @@
+
+######################################################################
+## $Id: ExtJS.pm 9649 2007-06-13 15:40:18Z spadkins $
+######################################################################
+
+package App::Widget::ExtJS;
+$VERSION = (q$Revision: 9649 $ =~ /(\d[\d\.]*)/)[0];  # VERSION numbers 
generated by svn
+
+use App::Widget;
[EMAIL PROTECTED] = ( "App::Widget" );
+
+use strict;
+
+=head1 NAME
+
+App::Widget::ExtJS - Dynamic, client-side widgets for the App-Context 
Framework using the ExtJS Javascript distribution
+
+=head1 SYNOPSIS
+
+   use App::Widget::ExtJS;
+
+   ...
+
+=cut
+
+sub _init {
+    &App::sub_entry if ($App::trace);
+    my ($self) = @_;
+    $self->init_js();
+    $self->SUPER::_init();
+    &App::sub_exit() if ($App::trace);
+}
+
+sub serialize_as_javascript {
+    &App::sub_entry if ($App::trace);
+    my ($self, $value) = @_;
+    my $modified_value;
+    my ($val, $oneline);
+    if (ref ($value) eq 'ARRAY') {
+        $oneline = ($#$value > -1 && ref($value->[0])) ? 0 : 1;
+        $modified_value .= "[";
+        $modified_value .= "\n   " if (!$oneline);
+        for (my $i = 0; $i <= $#$value; $i++) {
+            $val = $value->[$i];
+            if (ref($val)) { 
+                $modified_value .= $self->serialize_as_javascript($val);
+            }
+            elsif ($val =~ /^(false|true)$/) {
+                $modified_value .= "$val";
+            }
+            elsif ($val =~ /^-?[0-9]+\.?[0-9]*$/) {
+                $modified_value .= "$val";
+            }
+            else {
+                $modified_value .= "'$val'";
+            }
+            $modified_value .= "," if ($i < $#$value);
+            $modified_value .= "\n" if (!$oneline);
+            $modified_value .= "   " if (!$oneline && $i < $#$value);
+        }
+        $modified_value .= "]";
+        $modified_value .= "\n   " if (!$oneline);
+    }
+    elsif (ref($value) eq 'HASH') {
+        $modified_value .= "{";
+        foreach my $key (keys %$value) {
+            $val = $value->{$key};
+            if ($key =~ /^[a-zA-Z_][a-zA-Z0-9_]*$/) {
+                $modified_value .= "$key : ";
+            }
+            else {
+                $modified_value .= "\"$key\" : ";
+            }
+            if(ref($val) eq 'HASH') {
+                $modified_value .= $self->serialize_as_javascript($val);
+            }
+            elsif ($val =~ /^(false|true)$/) {
+                $modified_value .= $val;
+            }
+            elsif ($val =~ /^-?[0-9]+\.?[0-9]*$/) {
+                $modified_value .= $val;
+            }
+            else {
+                $modified_value .= "'$val'";
+            }
+            $modified_value .= ", ";
+        }
+
+        $modified_value =~ s/, *$//;
+        $modified_value .= "}";
+    }
+
+    $modified_value =~ s/[,\s\n]*$//s;
+    &App::sub_exit() if ($App::trace);
+    return $modified_value;
+
+}
+
+sub html {
+    &App::sub_entry if ($App::trace);
+    my $self = shift;
+    my $name = $self->{name};
+    my $context = $self->{context};
+
+    my %js_special = ( attrib => 1, hidden => 1, include_value_domain => 1, 
value_domain => 1, domain => 1, conf => 1, values_labels => 1 );
+    my (@attrib);
+    foreach my $key (keys %$self) {
+        if ($key =~ /^js_(.+)/) {
+            push(@attrib, $1, $self->{$key}) if (!$js_special{$1});
+        }
+    }
+    if (! defined $self->{js_submittable} || $self->{js_submittable}) {
+        push(@attrib, "submittable", 1);
+    }
+    my $value = $context->so_get($name);
+    $value = "" if (!defined $value);
+    $value = join(",",@$value) if (ref($value) eq "ARRAY");
+    push(@attrib, "default", $value);
+    my $js_conf = "";
+    my ($var, $val);
+    if ($#attrib > -1) {
+        $js_conf .= ", {" if (!$js_conf);
+        for (my $i = 0; $i < $#attrib; $i += 2) {
+            $js_conf .= "," if ($i > 0);
+            $var   = $attrib[$i];
+            $val   = $attrib[$i+1];
+            if (ref($val)) {
+                $js_conf .= " \"$var\" : " . 
$self->serialize_as_javascript($val);
+            }
+            else {
+                $js_conf .= " \"$var\" : \"" . 
$self->escape_double_quoted_value($val) . "\"";
+            }
+        }
+    }
+    if ($self->{js_conf}) {
+        $js_conf .= ($js_conf) ? ",\n" : ", {\n";
+        $js_conf .= $self->{js_conf};
+    }
+
+    if (defined $self->{js_attrib}) {
+        my ($value, $so_name);
+        my $attribs = $self->{js_attrib};
+        foreach my $attrib (sort keys %$attribs) {
+            $so_name = $attribs->{$attrib};
+            $so_name = $attrib if (!$so_name || $so_name eq "1");
+            $value = $context->so_get($so_name);
+            $value = join(",",@$value) if (ref($value) eq "ARRAY");
+            $js_conf .= ",\n    \"$attrib\" : \"" . 
$self->escape_double_quoted_value($value) . "\"";
+        }
+    }
+ 
+    if (defined $self->{js_value_domain}) {
+        my $value_domain_name = $self->{js_value_domain};
+        $self->include_value_domain($value_domain_name);
+        $js_conf .= ",\n    \"domain\" : \"$value_domain_name\"";
+    }
+
+    if (defined $self->{js_include_value_domain}) {
+        foreach my $value_domain_name (@{$self->{js_include_value_domain}}) {
+            $self->include_value_domain($value_domain_name);
+        }
+    }
+
+    if (defined $self->{js_domain}) {
+        my ($value_domain, $values, $labels, $domain_alias);
+        my ($values_text, $labels_text, $i);
+        foreach my $domain_name (sort keys %{$self->{js_domain}}) {
+
+            $domain_alias = $self->{js_domain}{$domain_name};
+            $domain_alias = $domain_name if (!$domain_alias || $domain_alias 
eq "1");
+            
+            $value_domain = $context->value_domain($domain_name);
+            ($values, $labels) = $value_domain->values_labels();
+
+            $values_text = "";
+            $labels_text = "";
+
+            if ($#$values > -1) {
+                $values_text = ",\n    \"${domain_alias}_values\" : [";
+                for ($i = 0; $i <= $#$values; $i++) {
+                    $values_text .= "," if ($i > 0);
+                    $values_text .= "\n     " if ($i % 10 == 0);
+                    $values_text .= " \"$values->[$i]\"";
+                }
+                $values_text .= "\n    ]";
+
+                if ($labels && %$labels) {
+                    $labels_text = ",\n    \"${domain_alias}_labels\" : {";
+                    for ($i = 0; $i <= $#$values; $i++) {
+                        next if (! defined $labels->{$values->[$i]});
+                        $labels_text .= "," if ($i > 0);
+                        $labels_text .= "\n     " if ($i % 10 == 0);
+                        $labels_text .= " \"$values->[$i]\" : 
\"$labels->{$values->[$i]}\"";
+                    }
+                    $labels_text .= "\n    }";
+                }
+            }
+            else {
+                $values_text = ",\n    \"${domain_alias}_values\" : [ ]";
+                $labels_text = ",\n    \"${domain_alias}_labels\" : { }";
+            }
+            $js_conf .= $values_text;
+            $js_conf .= $labels_text;
+        }
+    }
+
+    if ($self->{js_values_labels}) {
+        my ($values, $labels) = $self->values_labels();
+        my ($values_text, $i);
+        my $labels_text = "";
+    
+        if ($#$values > -1) {
+            $values_text = ",\n    \"values\" : [";
+            for ($i = 0; $i <= $#$values; $i++) {
+                $values_text .= "," if ($i > 0);
+                $values_text .= "\n     " if ($i % 10 == 0);
+                $values_text .= " \"$values->[$i]\"";
+            }
+            $values_text .= "\n    ]";
+    
+            if ($labels && %$labels) {
+                $labels_text = ",\n    \"labels\" : {";
+                for ($i = 0; $i <= $#$values; $i++) {
+                    next if (! defined $labels->{$values->[$i]});
+                    $labels_text .= "," if ($i > 0);
+                    $labels_text .= "\n     " if ($i % 10 == 0);
+                    $labels_text .= " \"$values->[$i]\" : 
\"$labels->{$values->[$i]}\"";
+                }
+                $labels_text .= "\n    }";
+            }
+        }
+        else {
+            $values_text = ",\n    values : [ ]";
+        }
+        $js_conf .= $values_text;
+        $js_conf .= $labels_text;
+    }
+
+    if ($js_conf) {
+        $js_conf .= " }";
+    }
+
+    my $html = <<EOF;
+<script type="text/javascript">
+  document.write("$name");
+</script>
+EOF
+    if ($self->{js_hidden}) {
+        my ($vars, @vars);
+        $vars = $self->{js_hidden};
+        if (ref($vars) eq "ARRAY") {
+            @vars = @$vars;
+        }
+        elsif ($vars =~ /,/) {
+            @vars = split(/,/, $vars);
+        }
+        else {
+            @vars = ($vars);
+        }
+        foreach my $var (@vars) {
+            $value = 
$self->escape_html_attribute_value($context->so_get($var));
+            my $hidden_input = "<input type=\"hidden\" name=\"${var}\" 
value=\"$value\" />\n";
+            $html = $hidden_input . $html;
+        }
+    }
+
+    &App::sub_exit($html) if ($App::trace);
+    return($html);
+}
+
+sub escape_double_quoted_value {
+    my ($self, $value) = @_;
+    $value =~ s/"/\\"/g;
+    $value =~ s/\r//msg;
+    $value =~ s/\n/\\n/msg;
+    return($value);
+}
+
+sub escape_html_attribute_value {
+    my ($self, $value) = @_;
+    if (!defined $value) {
+        $value = "";
+    }
+    # I'm not exactly sure that this is the right way to escape special 
characters
+    # *within* an HTML attribute value.
+    elsif ($value =~ /[\&<>"]/) {
+        $value =~ s/\&/\&amp;/g;
+        $value =~ s/</\&lt;/g;
+        $value =~ s/>/\&gt;/g;
+        $value =~ s/"/\&quot;/g;
+    }
+    return($value);
+}
+
+sub init_js {
+    &App::sub_entry if ($App::trace);
+    my ($self) = @_;
+    my $context = $self->{context};
+    my $options = $context->{options};
+
+    my $html_url_dir = $options->{html_url_dir}  || die "The parameter 
'html_url_dir' must be set in the option file";
+    my $version      = $options->{extjs_version} || die "The parameter 
'extjs_version' must be set in the option file";
+    if ($version !~ /^ext-[0-9.]+$/) {
+        die "The parameter 'extjs_version' in the option file must be of a 
form similar to 'ext-2.0.1'";
+    }
+    my $debug        = $options->{extjs_debug};
+    my $adapter      = $options->{extjs_adapter} || "ext";  # ext, jquery, 
prototype, yui
+
+    my $response = $context->response();
+
+    my $js = $debug ? "$html_url_dir/$version/ext-all-debug.js" : 
"$html_url_dir/$version/ext-all.js";
+    if (!$response->is_included("javascript", $js)) {
+        $response->include("css", 
"$html_url_dir/$version/resources/css/ext-all.css");
+        my $js_conf = $self->javascript_conf();
+        $response->include("javascript", $js_conf);
+        my $adapter_js = "$html_url_dir/$version/adapter/ext/ext-base.js";
+        if ($adapter ne "ext") {
+            $adapter_js = 
"$html_url_dir/$version/adapter/$adapter/ext-${adapter}-adapter.js";
+        }
+        $response->include("javascript", $adapter_js);
+        $response->include("javascript", $js);
+    }
+
+    &App::sub_exit() if ($App::trace);
+}
+
+sub include_value_domain {
+    &App::sub_entry if ($App::trace);
+    my ($self, $value_domain_name) = @_;
+    my $context = $self->{context};
+    my $response = $context->response();
+    my $javascript_key = "ValueDomain($value_domain_name)";
+    if (!$response->is_included("javascript", $javascript_key)) {
+        my $value_domain = $context->value_domain($value_domain_name);
+        my ($values, $labels) = $value_domain->values_labels();
+        my $values_text = "";
+        my $labels_text = "";
+        my ($i);
+        if ($#$values > -1) {
+            $values_text = ",\n    \"values\" : [";
+            for ($i = 0; $i <= $#$values; $i++) {
+                $values_text .= "," if ($i > 0);
+                $values_text .= "\n     " if ($i % 10 == 0);
+                $values_text .= " \"$values->[$i]\"";
+            }
+            $values_text .= "\n    ]";
+
+            if ($labels && %$labels) {
+                $labels_text = ",\n    \"labels\" : {";
+                for ($i = 0; $i <= $#$values; $i++) {
+                    next if (! defined $labels->{$values->[$i]});
+                    $labels_text .= "," if ($i > 0);
+                    $labels_text .= "\n     " if ($i % 10 == 0);
+                    $labels_text .= " \"$values->[$i]\" : 
\"$labels->{$values->[$i]}\"";
+                }
+                $labels_text .= "\n    }";
+            }
+        }
+        else {
+            $values_text = ",\n    \"values\" : [ ]";
+            $labels_text = ",\n    \"labels\" : { }";
+        }
+        my $js = <<EOF;
+<script type="text/javascript" language="JavaScript">
+context.valueDomain("$value_domain_name", {
+    serviceClass : "ValueDomain"$values_text$labels_text
+});
+</script>
+EOF
+        $response->include("javascript", $js, $javascript_key);
+    }
+    &App::sub_exit() if ($App::trace);
+}
+
+sub javascript_conf {
+    &App::sub_entry if ($App::trace);
+    my ($self) = @_;
+    my $context = $self->{context};
+    my $options = $context->options();
+    my $html_url_dir     = $options->{html_url_dir};
+    my $script_url_dir   = $options->{script_url_dir};
+    my $js = $options->{js_init};
+    if (!$js) {
+        $js = <<EOF;
+<script type="text/javascript" language="JavaScript">
+  var appOptions = {
+    urlDocRoot    : "$html_url_dir",
+    urlScriptRoot : "$script_url_dir"
+  };
+</script>
+EOF
+    }
+    &App::sub_exit($js) if ($App::trace);
+    return($js);
+}
+
+1;
+

Added: p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/DataTable.pm
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/DataTable.pm       Wed Mar 
 5 06:57:20 2008
@@ -0,0 +1,356 @@
+
+######################################################################
+## $Id: DataTable.pm 3681 2006-03-13 19:55:12Z spadkins $
+######################################################################
+
+package App::Widget::ExtJS::DataTable;
+$VERSION = (q$Revision: 3681 $ =~ /(\d[\d\.]*)/)[0];  # VERSION numbers 
generated by svn
+
+use App::Widget::ExtJS;
[EMAIL PROTECTED] = ( "App::Widget::ExtJS" );
+
+use strict;
+
+=head1 NAME
+
+App::Widget::ExtJS::DataTable - A data table widget
+
+=head1 SYNOPSIS
+
+   use App::Widget::ExtJS::DataTable;
+
+   ...
+
+=cut
+
+sub _init {
+    &App::sub_entry if ($App::trace);
+    my ($self) = @_;
+    $self->SUPER::_init(@_);
+    $self->{table} = $self->{name} if (!$self->{table});
+
+    if (!$self->{keycolidx}) {
+        my $context = $self->{context};
+        my $table   = $self->{table};
+        my $rep     = $self->{repository};
+        my $r       = $context->repository($rep);
+        $r->_load_table_metadata($table);
+        my $primary_key = $r->{table}{$table}{primary_key};
+        if ($primary_key && ref($primary_key) eq "ARRAY" && $#$primary_key > 
-1) {
+            my (@keycolidx, %colidx);
+            my $columns = $self->get_columns();
+            for (my $col = 0; $col <= $#$columns; $col++) {
+                $colidx{$columns->[$col]} = $col;
+            }
+            for (my $col = 0; $col <= $#$primary_key; $col++) {
+                if (defined $colidx{$primary_key->[$col]}) {
+                    push(@keycolidx, $colidx{$primary_key->[$col]});
+                }
+            }
+            $self->{keycolidx} = [EMAIL PROTECTED] if ($#keycolidx == 
$#$primary_key);
+        }
+    }
+}
+
+sub repository {
+    &App::sub_entry if ($App::trace);
+    my ($self) = @_;
+    my $repname = $self->{repository};
+    my $context = $self->{context};
+    my $rep = $context->repository($repname);
+    &App::sub_exit($rep) if ($App::trace);
+    return($rep);
+}
+
+sub get_columns {
+    &App::sub_entry if ($App::trace);
+    my ($self) = @_;
+    my ($columns);
+    $columns = $self->{columns};
+    if (defined $columns && ref($columns) eq "") {
+        $columns = [ $columns ];
+        $self->set("columns", $columns);
+    }
+    if (!defined $columns) {
+        my $rep   = $self->repository();
+        my $table = $self->{table};
+        if ($rep && $table) {
+            $columns = $rep->get_column_names($table);
+        }
+    }
+    $columns = [] if (!defined $columns || ref($columns) eq "");
+    &App::sub_exit($columns) if ($App::trace);
+    $columns;
+}
+
+sub get_headings {
+    &App::sub_entry if ($App::trace);
+    my ($self) = @_;
+    $self->{context}->dbgprint("DataTable->get_headings()")
+        if ($App::DEBUG && $self->{context}->dbg(1));
+    my ($table, $headings, $heading, $columns, $column, $lang);
+    $table    = $self->{table};
+    $columns  = $self->get_columns();
+    $headings = $self->{headings};
+    $lang     = $self->{lang};
+    my $column_attribs = $self->{column} || {};
+    if (!defined $headings) {
+        $headings = [];
+        my ($rep, $columnlabels);
+        $rep = $self->repository();
+        $columnlabels = $rep->get_column_labels($table);
+        foreach $column (@$columns) {
+            $heading = $column_attribs->{$column}{label} || 
$columnlabels->{$column} || $column;
+            $heading = $self->translate($heading, $lang) if (defined $lang);
+            push(@$headings, $heading);
+            $self->{context}->dbgprint("DataTable->get_headings(): 
column=$column(",$#$columns,") heading=$heading(",$#$headings,")")
+                if ($App::DEBUG >= 6 && $self->{context}->dbg(6));
+        }
+    }
+    $self->{context}->dbgprint("DataTable->get_headings(): columns=[", 
join(",", @{$self->get("columns",[])}), "]")
+        if ($App::DEBUG && $self->{context}->dbg(1));
+    &App::sub_exit($headings) if ($App::trace);
+    return($headings);
+}
+
+sub get_data {
+    &App::sub_entry if ($App::trace);
+    my ($self) = @_;
+    $self->{context}->dbgprint("DataTable->get_data()")
+        if ($App::DEBUG && $self->{context}->dbg(1));
+    my ($data);
+    $data = $self->{data};
+    if (!defined $data) {
+        $self->load();
+        $data = $self->{data};
+    }
+    &App::sub_exit($data) if ($App::trace);
+    return $data;
+}
+
+sub load {
+    &App::sub_entry if ($App::trace);
+    my ($self) = @_;
+    $self->{context}->dbgprint("DataTable->load()")
+        if ($App::DEBUG && $self->{context}->dbg(1));
+    my ($context, $rep, $rows, $table, $columns, $sql, $error, $data);
+    my ($params, $paramvalues, $param, $paramvalue, @paramvalues);
+    my ($startrow, $maxrows, $endrow, $keycolidx);
+    my (%paramvalues, $filter, $column);
+
+    $rep = $self->repository();
+    return if (! defined $rep);
+
+    $sql = $self->{sql};
+    $data = $self->{data};
+
+    if ($sql) {
+        $paramvalues = $self->substitute($self->{paramvalues});
+        $sql         = $self->substitute($sql, $paramvalues);
+        $startrow    = $self->get("startrow", 1, 1);
+        $maxrows     = $self->get("maxrows", 20, 1);
+        $endrow      = ($maxrows != 0) ? ($startrow + $maxrows - 1) : 0;
+        $rows        = [ $rep->exec_select($sql, $startrow, $endrow) ];
+        $error       = $rep->error();
+        if ($#$rows == -1 && $error) {
+            $context->add_message("SQL error: $error<br>$sql");
+        }
+    }
+    elsif ($data) {
+        $rows = $data;
+    }
+    else {
+        $table = $self->{table};
+
+        $columns = $self->get_columns();
+        if (! defined $columns || $#$columns == -1) {
+            $columns = $rep->get_column_names($table);
+            if (!defined $columns || $#$columns == -1) {
+                $context->add_message("No columns specified");
+                return;
+            }
+        }
+        else {
+            $columns = [ @$columns ];
+        }
+
+        $params      = $self->{params};
+        $paramvalues = $self->substitute($self->get("paramvalues",{}));
+        %paramvalues = %$paramvalues;
+        $filter      = $self->get("filter",{});
+        foreach $column (%$filter) {
+            $param = $column;
+            $paramvalue = $filter->{$column};
+            if (defined $paramvalue && $paramvalue ne "") {
+                if ($param =~ /\./) {
+                    if (!defined $paramvalues{$param} && defined $params) {
+                        push(@$params,$param);
+                    }
+                    $paramvalues{$param} = $paramvalue;
+                }
+                elsif ($paramvalue =~ /^ *[=~!<>\/]/) {
+                    @paramvalues = split(/ *([=~!<>\/]+) */,$paramvalue);
+                    my ($i, $op);
+                    for ($i = 1; $i < $#paramvalues; $i += 2) {
+                        $op = "";
+                        if    ($paramvalues[$i] eq "=")  { $op = "eq"; }
+                        elsif ($paramvalues[$i] eq "==") { $op = "eq"; }
+                        elsif ($paramvalues[$i] eq "!=") { $op = "ne"; }
+                        elsif ($paramvalues[$i] eq "<>") { $op = "ne"; }
+                        elsif ($paramvalues[$i] eq "<")  { $op = "lt"; }
+                        elsif ($paramvalues[$i] eq "<=") { $op = "le"; }
+                        elsif ($paramvalues[$i] eq ">")  { $op = "gt"; }
+                        elsif ($paramvalues[$i] eq ">=") { $op = "ge"; }
+                        elsif ($paramvalues[$i] eq "~")  { $op = "contains"; }
+                        elsif ($paramvalues[$i] eq "~=") { $op = "contains"; }
+                        elsif ($paramvalues[$i] eq "=~") { $op = "contains"; }
+                        elsif ($paramvalues[$i] eq "/")  { $op = "matches"; }
+
+                        $paramvalue = $paramvalues[$i+1];
+
+                        if ($op) {
+                            $param = "$column.$op";
+                            if (!defined $paramvalues{$param}) {
+                                push(@$params,$param) if (defined $params);
+                                $paramvalues{$param} = $paramvalue;
+                            }
+                        }
+                    }
+                }
+                elsif ($paramvalue =~ /,/) {
+                    $param = "$column.in";
+                    if (!defined $paramvalues{$param}) {
+                        push(@$params,$param) if (defined $params);
+                        $paramvalues{$param} = $paramvalue;
+                    }
+                }
+                else {
+                    $param = "$column.contains";
+                    if (!defined $paramvalues{$param} && defined $params) {
+                        push(@$params,$param);
+                    }
+                    $paramvalues{$param} = $paramvalue;
+                }
+            }
+        }
+
+        my $order_by   = $self->{order_by} || $self->{ordercols};   # 
ordercols is deprecated in favor of order_by
+        my $group_by   = $self->{group_by};
+        my $direction  = $self->{direction} || $self->{directions} || {}; # 
directions is deprecated in favor of direction
+        $startrow      = $self->get("startrow", 1, 1);
+        $maxrows       = $self->get("maxrows", 20, 1);
+        $endrow        = ($maxrows != 0) ? ($startrow + $maxrows - 1) : 0;
+
+        if ($App::DEBUG && $self->{context}->dbg(1)) {
+            $self->{context}->dbgprint("DataTable->load(): 
get_rows($table,c=$columns,p=$params,pv=$paramvalues,oc=$order_by,$startrow,$endrow,$direction);");
+            $self->{context}->dbgprint("DataTable->load(): columns=[", 
join(",", @$columns), "]") if (ref($columns) eq "ARRAY");
+            $self->{context}->dbgprint("DataTable->load(): params=[", 
join(",", @$params), "]") if (ref($params) eq "ARRAY");
+            $self->{context}->dbgprint("DataTable->load(): paramvalues=[", 
join(",", %$paramvalues), "]") if (ref($paramvalues) eq "HASH");
+            $self->{context}->dbgprint("DataTable->load(): order_by=[", 
join(",", @$order_by), "]") if (ref($order_by) eq "ARRAY");
+            $self->{context}->dbgprint("DataTable->load(): directions={", 
join(",", %$direction), "}") if (ref($direction) eq "HASH");
+        }
+
+        $rows  = $rep->get_rows($table, \%paramvalues, $columns,
+            {order_by => $order_by, startrow => $startrow, endrow => $endrow, 
direction => $direction, group_by => $group_by});
+        $error = $rep->error();
+        if ($#$rows == -1 && $error) {
+            $sql = $rep->{sql};
+            $context->add_message("SQL error: $error<br>$sql");
+        }
+    }
+
+    my ($keys, $row);
+
+    $self->{data} = $rows;
+
+    $keycolidx = $self->get("keycolidx");
+    if (defined $keycolidx && ref($keycolidx) eq "ARRAY") {
+        $keys = [];
+        foreach $row (@$rows) {
+            push(@$keys, [ @[EMAIL PROTECTED] ]);
+        }
+        $self->set("keys", $keys);
+    }
+    &App::sub_exit() if ($App::trace);
+}
+
+sub html {
+    &App::sub_entry if ($App::trace);
+    my ($self) = @_;
+    my $name = $self->{name};
+
+    my $context = $self->{context};
+    my $value = $context->so_get($name);
+    $value = "" if (!defined $value);
+    my $table = $self->{table} || "unknown";
+
+    my $rep = $self->repository();
+    my $tabledef = $rep->get_table_def($table);
+
+    my $data = $self->get_data();
+    my $js_data = $self->serialize_as_javascript($data);
+
+    my $columns = $self->get_columns();
+    my $column_data_defs = [];
+    my $column_display_defs = [];
+    my ($column_data_def, $column_display_def, $label);
+    foreach my $column (@$columns) {
+        $column_data_def = { name => $column };
+        push(@$column_data_defs, $column_data_def);
+        $label = $tabledef->{column}{$column}{label} || $column;
+        $label =~ s/<br>//g;
+        $column_display_def = { header => $label, sortable => "true", width => 
100, dataIndex => $column };
+        push(@$column_display_defs, $column_display_def);
+    }
+    my $js_column_data_defs = 
$self->serialize_as_javascript($column_data_defs);
+    my $js_column_display_defs = 
$self->serialize_as_javascript($column_display_defs);
+
+    my $height      = $self->{height} || 500;
+    my $width       = $self->{width}  || 800;
+    my $table_label = $self->{label}  || $tabledef->{label};
+    if (!$table_label) {
+        $table_label = lc($table);
+        $table_label =~ s/_/ /g;
+        $table_label = ucfirst($table_label);
+    }
+
+    my $html = <<EOF;
+<script type="text/javascript">
+Ext.onReady(function(){
+
+    // Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
+
+    var data = $js_data;
+
+    // create the data store
+    var dataStore = new Ext.data.SimpleStore({
+        fields: $js_column_data_defs
+    });
+    dataStore.loadData(data);
+
+    // create the Grid
+    var grid = new Ext.grid.GridPanel({
+        store: dataStore,
+        columns: $js_column_display_defs,
+        stripeRows: true,
+        frame:  true,
+        // stateful: true,
+        height: $height,
+        width:  $width,
+        title: '$table_label'
+    });
+
+    grid.render('$name');
+
+    grid.getSelectionModel().selectFirstRow();
+});
+</script>
+<div id="$name"></div>
+EOF
+
+    &App::sub_exit("<html...>") if ($App::trace);
+    return($html);
+}
+
+1;
+

Added: p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/Date.pm
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/Date.pm    Wed Mar  5 
06:57:20 2008
@@ -0,0 +1,50 @@
+
+######################################################################
+## $Id: Date.pm 3681 2006-03-13 19:55:12Z spadkins $
+######################################################################
+
+package App::Widget::ExtJS::Date;
+$VERSION = (q$Revision: 3681 $ =~ /(\d[\d\.]*)/)[0];  # VERSION numbers 
generated by svn
+
+use App::Widget::ExtJS;
[EMAIL PROTECTED] = ( "App::Widget::ExtJS" );
+
+use strict;
+
+=head1 NAME
+
+App::Widget::ExtJS::Date - A date widget
+
+=head1 SYNOPSIS
+
+   use App::Widget::ExtJS::Date;
+
+   ...
+
+=cut
+
+sub html {
+    my $self = shift;
+    my $name = $self->{name};
+
+    $self->init_js();
+
+    my $context = $self->{context};
+    my $value = $context->so_get($name);
+    $value = "" if (!defined $value);
+
+    my $html = <<EOF;
+<script type="text/javascript">
+  context.widget("$name", {
+    "serviceClass" : "DateWidget",
+    "submittable" : 1,
+    "default" : "$value"
+  }).write();
+</script>
+EOF
+
+    return($html);
+}
+
+1;
+

Added: p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/DualSelectWidget.pm
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/DualSelectWidget.pm        
Wed Mar  5 06:57:20 2008
@@ -0,0 +1,98 @@
+
+######################################################################
+## $Id: DualSelectWidget.pm 8534 2007-01-10 00:14:39Z spadkins $
+######################################################################
+
+package App::Widget::ExtJS::DualSelectWidget;
+$VERSION = (q$Revision: 8534 $ =~ /(\d[\d\.]*)/)[0];  # VERSION numbers 
generated by svn
+
+use App::Widget::ExtJS;
[EMAIL PROTECTED] = ( "App::Widget::ExtJS" );
+
+use strict;
+
+=head1 NAME
+
+App::Widget::ExtJS::DualSelectWidget - An ordered multi-select widget made up 
of two HTML <select> tags and four buttons,
+enhanced by JavaScript
+
+=head1 SYNOPSIS
+
+   use App::Widget::ExtJS::DualSelectWidget;
+
+   ...
+
+=cut
+
+sub html {
+    my $self = shift;
+    my $name = $self->{name};
+
+    $self->init_js();
+
+    my $extra_attribs = "";
+    $extra_attribs .= ",\n    \"size\" : $self->{size}" if ($self->{size});
+    $extra_attribs .= ",\n    \"maxselected\" : $self->{maxselected}" if 
($self->{maxselected});
+
+    if (defined $self->{js_include_value_domain}) {
+        foreach my $value_domain_name (@{$self->{js_include_value_domain}}) {
+            $self->include_value_domain($value_domain_name);
+        }
+    }
+
+    my $values_text = "";
+    my $labels_text = "";
+
+    if ($self->{domain}) {
+        $self->include_value_domain($self->{domain});
+        $extra_attribs .= ",\n    \"domain\" : \"$self->{domain}\"";
+    }
+    else {
+        my ($values, $labels) = $self->values_labels();
+        my ($i);
+
+        if ($#$values > -1) {
+            $values_text = ",\n    \"values\" : [";
+            for ($i = 0; $i <= $#$values; $i++) {
+                $values_text .= "," if ($i > 0);
+                $values_text .= "\n     " if ($i % 10 == 0);
+                $values_text .= " \"$values->[$i]\"";
+            }
+            $values_text .= "\n    ]";
+
+            if ($labels && %$labels) {
+                $labels_text = ",\n    \"labels\" : {";
+                for ($i = 0; $i <= $#$values; $i++) {
+                    next if (! defined $labels->{$values->[$i]});
+                    $labels_text .= "," if ($i > 0);
+                    $labels_text .= "\n     " if ($i % 10 == 0);
+                    $labels_text .= " \"$values->[$i]\" : 
\"$labels->{$values->[$i]}\"";
+                }
+                $labels_text .= "\n    }";
+            }
+        }
+        else {
+            $values_text = ",\n    values : [ ]";
+        }
+    }
+    my $context = $self->{context};
+    my $value = $context->so_get($name);
+    $value = "" if (!defined $value);
+
+    my $class = $self->{js_serviceClass} || 'DualSelectWidget';     
+
+    my $html = <<EOF;
+<script type="text/javascript">
+  context.widget("$name", {
+    "serviceClass" : "$class",
+    "submittable" : 1,
+    "default" : "$value"$extra_attribs$values_text$labels_text
+  }).write();
+</script>
+EOF
+
+    return($html);
+}
+
+1;
+

Added: p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/TabbedAppFrame.pm
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Widget-ExtJS/lib/App/Widget/ExtJS/TabbedAppFrame.pm  Wed Mar 
 5 06:57:20 2008
@@ -0,0 +1,72 @@
+
+######################################################################
+## $Id: TabbedAppFrame.pm 5896 2006-04-11 17:47:00Z spadkins $
+######################################################################
+
+package App::Widget::ExtJS::TabbedAppFrame;
+$VERSION = (q$Revision: 5896 $ =~ /(\d[\d\.]*)/)[0];  # VERSION numbers 
generated by svn
+
+use App;
+use App::Widget::TabbedAppFrame;
+use App::Widget::ExtJS;
[EMAIL PROTECTED] = ( "App::Widget::TabbedAppFrame", "App::Widget::ExtJS" );
+
+use strict;
+
+=head1 NAME
+
+App::Widget::ExtJS::TabbedAppFrame - An application frame.
+
+=head1 SYNOPSIS
+
+   $name = "office";
+
+   # official way
+   use Widget;
+   $context = App->context();
+   $w = $context->widget($name);
+
+   # internal way
+   use App::Widget::ExtJS::TabbedAppFrame;
+   $w = App::Widget::ExtJS::TabbedAppFrame->new($name);
+
+=cut
+
+######################################################################
+# CONSTANTS
+######################################################################
+
+######################################################################
+# ATTRIBUTES
+######################################################################
+
+# INPUTS FROM THE ENVIRONMENT
+
+=head1 DESCRIPTION
+
+This class implements an application frame.
+This includes a menu, an application toolbar, a screen selector, 
+a screen title, a screen toolbar, and 
+a screen frame.  The application is actually implemented by the set
+of screens that the application frame is configured to allow navigation
+to.
+
+The application frame can implement itself in frames if it is
+configured to do so.  Otherwise, it implements itself as a table.
+
+=cut
+
+######################################################################
+# OUTPUT METHODS
+######################################################################
+
+sub _init {
+    &App::sub_entry if ($App::trace);
+    my $self = shift;
+    $self->SUPER::_init(@_);
+    $self->init_js();
+    &App::sub_exit() if ($App::trace);
+}
+
+1;
+

Added: p5ee/trunk/App-Widget-ExtJS/t/main.t
==============================================================================
--- (empty file)
+++ p5ee/trunk/App-Widget-ExtJS/t/main.t        Wed Mar  5 06:57:20 2008
@@ -0,0 +1,11 @@
+#!/usr/local/bin/perl -w
+
+use Test::More qw(no_plan);
+use lib "lib";
+use lib "../lib";
+
+use strict;
+
+ok(1, "no tests");
+exit(0);
+

Reply via email to