Richard Siddall <richard.siddall@elirion.net> sent in Mason fixes and other
things I'm probably forgetting.
-Contains "JS Calendar" v0.9.3 <http://dynarch.com/mishoo/calendar.epl>
+Contains "JS Calendar" <http://dynarch.com/mishoo/calendar.epl>
by Mihai Bazon <mishoo@infoiasi.ro> licensed under the terms of the GNU LGPL.
Latex invoice template based on a template from eBills
Troy Hammonds <troyh@netsignia.net> sent in RADIUS session history viewing
code and other things I'm probably forgetting.
+Contains the "Javascript Remote Scripting (JSRS)" client library
+<http://www.ashleyit.com/rs/main.htm> by Brent Ashley <brent@ashleyit.com>
+licensed under the "No Nonsense Copyright and License" (see the included
+JSRS-LICENSE file).
+
+Contains the QLIB JavaScript library <http://qlib.quazzle.com/> by
+Quazzle.com, Serge Dolgov, licensed under the terms of the GNU GPL.
+
Everything else is my (Ivan Kohler <ivan@420.am>) fault.
}
sub myconnect {
- $dbh = DBI->connect( getsecrets, {'AutoCommit' => 0, 'ChopBlanks' => 1, } )
+ DBI->connect( getsecrets, {'AutoCommit' => 0, 'ChopBlanks' => 1, } )
or die "DBI->connect error: $DBI::errstr\n";
}
use strict;
use vars qw( @ISA @EXPORT_OK $DEBUG $conf $jobnums);
use Exporter;
-use FS::UID;
+use FS::UID qw(myconnect);
use FS::Conf;
use FS::Record qw( qsearch qsearchs dbh );
#use FS::queue;
@EXPORT_OK = qw( joblisting );
$DEBUG = 0;
-#$DEBUG = 1;
$FS::UID::callback{'FS::queue'} = sub {
$conf = new FS::Conf;
}
}
+=item update_statustext VALUE
+
+Updates the statustext value of this job to supplied value, in the database.
+If there is an error, returns the error, otherwise returns false.
+
+=cut
+
+use vars qw($_update_statustext_dbh);
+sub update_statustext {
+ my( $self, $statustext ) = @_;
+ return '' if $statustext eq $self->statustext;
+ warn "updating statustext for $self to $statustext" if $DEBUG;
+
+ $_update_statustext_dbh ||= myconnect;
+
+ my $sth = $_update_statustext_dbh->prepare(
+ 'UPDATE queue set statustext = ? WHERE jobnum = ?'
+ ) or return $_update_statustext_dbh->errstr;
+
+ $sth->execute($statustext, $self->jobnum) or return $sth->errstr;
+ $_update_statustext_dbh->commit or die $_update_statustext_dbh->errstr;
+ $self->statustext($statustext);
+ '';
+
+ #my $new = new FS::queue { $self->hash };
+ #$new->statustext($statustext);
+ #my $error = $new->replace($self);
+ #return $error if $error;
+ #$self->statustext($statustext);
+ #'';
+}
+
=back
=head1 SUBROUTINES
package FS::rate;
use strict;
-use vars qw( @ISA );
-use FS::Record qw( qsearch qsearchs dbh );
+use vars qw( @ISA $DEBUG );
+use FS::Record qw( qsearch qsearchs dbh fields );
use FS::rate_detail;
@ISA = qw(FS::Record);
+$DEBUG = 1;
+
=head1 NAME
FS::rate - Object methods for rate records
}
if ( $options{'rate_detail'} ) {
+
+ my( $num, $last, $min_sec ) = (0, time, 5); #progressbar foo
+
foreach my $rate_detail ( @{$options{'rate_detail'}} ) {
+
$rate_detail->ratenum($self->ratenum);
$error = $rate_detail->insert;
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
return $error;
}
+
+ if ( $options{'job'} ) {
+ $num++;
+ if ( time - $min_sec > $last ) {
+ my $error = $options{'job'}->update_statustext(
+ int( 100 * $num / scalar( @{$options{'rate_detail'}} ) )
+ );
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+ $last = time;
+ }
+ }
+
}
}
local $FS::UID::AutoCommit = 0;
my $dbh = dbh;
- my @old_rate_detail = ();
- @old_rate_detail = $old->rate_detail if $options{'rate_detail'};
+# my @old_rate_detail = ();
+# @old_rate_detail = $old->rate_detail if $options{'rate_detail'};
my $error = $new->SUPER::replace($old);
if ($error) {
return $error;
}
- foreach my $old_rate_detail ( @old_rate_detail ) {
- my $error = $old_rate_detail->delete;
- if ($error) {
+# foreach my $old_rate_detail ( @old_rate_detail ) {
+#
+# my $error = $old_rate_detail->delete;
+# if ($error) {
+# $dbh->rollback if $oldAutoCommit;
+# return $error;
+# }
+#
+# if ( $options{'job'} ) {
+# $num++;
+# if ( time - $min_sec > $last ) {
+# my $error = $options{'job'}->update_statustext(
+# int( 50 * $num / scalar( @old_rate_detail ) )
+# );
+# if ( $error ) {
+# $dbh->rollback if $oldAutoCommit;
+# return $error;
+# }
+# $last = time;
+# }
+# }
+#
+# }
+ if ( $options{'rate_detail'} ) {
+ my $sth = $dbh->prepare('DELETE FROM rate_detail WHERE ratenum = ?') or do {
$dbh->rollback if $oldAutoCommit;
- return $error;
- }
- }
-
- foreach my $rate_detail ( @{$options{'rate_detail'}} ) {
- $rate_detail->ratenum($new->ratenum);
- $error = $rate_detail->insert;
- if ( $error ) {
+ return $dbh->errstr;
+ };
+
+ $sth->execute($old->ratenum) or do {
$dbh->rollback if $oldAutoCommit;
- return $error;
+ return $sth->errstr;
+ };
+
+ my( $num, $last, $min_sec ) = (0, time, 5); #progresbar foo
+# $num = 0;
+ foreach my $rate_detail ( @{$options{'rate_detail'}} ) {
+
+ $rate_detail->ratenum($new->ratenum);
+ $error = $rate_detail->insert;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+
+ if ( $options{'job'} ) {
+ $num++;
+ if ( time - $min_sec > $last ) {
+ my $error = $options{'job'}->update_statustext(
+ int( 100 * $num / scalar( @{$options{'rate_detail'}} ) )
+ );
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+ $last = time;
+ }
+ }
+
}
+
}
$dbh->commit or die $dbh->errstr if $oldAutoCommit;
=back
+=head1 SUBROUTINES
+
+=over 4
+
+=item process
+
+Experimental job-queue processor for web interface adds/edits
+
+=cut
+
+sub process {
+ my $job = shift;
+
+ #my %param = @_;
+
+ my $param = shift;
+ my %param = split(/[;=]/, $param);
+
+ my $old = qsearchs('rate', { 'ratenum' => $param{'ratenum'} } )
+ if $param{'ratenum'};
+
+ my @rate_detail = map {
+
+ my $regionnum = $_->regionnum;
+ if ( $param{"sec_granularity$regionnum"} ) {
+
+ new FS::rate_detail {
+ 'dest_regionnum' => $regionnum,
+ map { $_ => $param{"$_$regionnum"} }
+ qw( min_included min_charge sec_granularity )
+ };
+
+ } else {
+
+ new FS::rate_detail {
+ 'dest_regionnum' => $regionnum,
+ 'min_included' => 0,
+ 'min_charge' => 0,
+ 'sec_granularity' => '60'
+ };
+
+ }
+
+ } qsearch('rate_region', {} );
+
+ my $rate = new FS::rate {
+ map { $_ => $param{$_} }
+ fields('rate')
+ };
+
+ my $error = '';
+ if ( $param{'ratenum'} ) {
+ warn "$rate replacing $old ($param{'ratenum'})\n" if $DEBUG;
+ $error = $rate->replace( $old,
+ 'rate_detail' => \@rate_detail,
+ 'job' => $job,
+ );
+ } else {
+ warn "inserting $rate\n" if $DEBUG;
+ $error = $rate->insert( 'rate_detail' => \@rate_detail,
+ 'job' => $job,
+ );
+ #$ratenum = $rate->getfield('ratenum');
+ }
+
+ die $error if $error;
+
+}
+
+# begin JSRPC code...
+
+package FS::rate::JSRPC;
+use vars qw(@ISA $DEBUG);
+use JavaScript::RPC::Server::CGI;
+use FS::UID;
+@ISA = qw( JavaScript::RPC::Server::CGI );
+$DEBUG = 1;
+
+sub process_rate {
+ my $self = shift;
+
+ my %param = @_;
+ warn "FS::rate::JSRPC::process_rate\n".
+ join('', map " $_ => $param{$_}\n", keys %param )
+ if $DEBUG;
+
+ #progressbar prototype code... should be generalized
+
+ #first get the CGI params shipped off to a job ASAP so an id can be returned
+ #to the caller
+
+ my $job = new FS::queue { 'job' => 'FS::rate::process' };
+
+ #too slow to insert all the cgi params as individual args..,?
+ #my $error = $queue->insert('_JOB', $cgi->Vars);
+
+ #my $bigstring = join(';', map { "$_=". scalar($cgi->param($_)) } $cgi->param );
+ my $bigstring = join(';', map { "$_=". $param{$_} } keys %param );
+ my $error = $job->insert('_JOB', $bigstring);
+
+ if ( $error ) {
+ $error;
+ } else {
+ $job->jobnum;
+ }
+
+}
+
+sub get_new_query {
+ FS::UID::cgi();
+}
+
+# end JSRPC code...
+
=head1 BUGS
=head1 SEE ALSO
unless ( dbh && dbh->ping ) {
warn "WARNING: connection to database lost, reconnecting...\n";
- eval { myconnect; };
+ eval { $FS::UID::dbh = myconnect; };
unless ( !$@ && dbh && dbh->ping ) {
warn "WARNING: still no connection to database, sleeping for retry...\n";
#}
my @args = $ljob->args;
+ splice @args, 0, 1, $ljob if $args[0] eq '_JOB';
defined( my $pid = fork ) or do {
warn "WARNING: can't fork: $!\n";
forksuidsetup($user);
- #auto-use export classes...
- if ( $ljob->job =~ /(FS::part_export::\w+)::/ ) {
+ #auto-use classes...
+ #if ( $ljob->job =~ /(FS::part_export::\w+)::/ ) {
+ if ( $ljob->job =~ /(FS::part_export::\w+)::/
+ || $ljob->job =~ /(FS::\w+)::/
+ )
+ {
my $class = $1;
eval "use $class;";
if ( $@ ) {
--- /dev/null
+\r
+No Nonsense Copyright and License for JSRS JavaScript Remote Scripting\r
+======================================================================\r
+\r
+Copyright:\r
+\r
+This JSRS stuff was written by me. I find it useful. Others find it useful. \r
+You are welcome to use it, modify it to suit your needs, distribute it as you \r
+see fit. I'm happy if you use it for personal stuff or for commercial gain.\r
+\r
+The only thing you can't do is to restrict anyone else from using it however \r
+they see fit. You may not copyright it yourself or change the rules I have \r
+set on how it can be used.\r
+\r
+JSRS Javascript Remote Scripting Copyright (C) 2001 by Brent Ashley\r
+\r
+License:\r
+\r
+You can use this however you like. I make no guarantees whatsoever that it \r
+will suit your purpose. You take full responsibility for getting it working \r
+properly and for any implications of its failure or inability to satisfy your \r
+every need.\r
+\r
+======================================================================\r
+\r
+email inquiries: jsrs@megahuge.com\r
+\r
+\r
+\r
<li><a href="http://search.cpan.org/search?dist=NetAddr-IP">NetAddr-IP</a>
<li><a href="http://search.cpan.org/search?dist=Chart">Chart</a>
<li><a href="http://search.cpan.org/search?dist=Crypt-PasswdMD5">Crypt::PasswdMD5</a>
+ <li><a href="http://search.cpan.org/search?dist=JavaScript-RPC">JavaScript::RPC (JavaScript::RPC::Server::CGI)</a>
<li><a href="http://search.cpan.org/search?dist=ApacheDBI">Apache::DBI</a> <i>(optional but recommended for better webinterface performance)</i>
</ul>
</ul>
--- /dev/null
+<%
+my $server = new FS::rate::JSRPC;
+$server->process;
+%>
<%
-my($rate, $error);
-
-if ( $cgi->param('magic') eq 'process' ) {
-
- my $ratenum = $cgi->param('ratenum');
-
- my $old = qsearchs('rate', { 'ratenum' => $ratenum } ) if $ratenum;
-
- my @rate_detail = map {
- my $regionnum = $_->regionnum;
- if ( $cgi->param("sec_granularity$regionnum") ) {
- new FS::rate_detail {
- 'dest_regionnum' => $regionnum,
- map { $_ => scalar($cgi->param("$_$regionnum")) }
- qw( min_included min_charge sec_granularity )
- };
- } else {
- new FS::rate_detail {
- 'dest_regionnum' => $regionnum,
- 'min_included' => 0,
- 'min_charge' => 0,
- 'sec_granularity' => '60'
- };
- }
- } qsearch('rate_region', {} );
-
- $rate = new FS::rate ( {
- map {
- $_, scalar($cgi->param($_));
- } fields('rate')
- } );
-
- if ( $ratenum ) {
- warn "$rate replacing $old ($ratenum)\n";
- $error = $rate->replace($old, 'rate_detail' => \@rate_detail );
- } else {
- warn "inserting $rate\n";
- $error = $rate->insert( 'rate_detail' => \@rate_detail );
- $ratenum = $rate->getfield('ratenum');
- }
-
- unless ( $error ) {
- print $cgi->redirect("${p}browse/rate.cgi");
- myexit;
- }
-
-} elsif ( $cgi->keywords ) {
+my $rate;
+if ( $cgi->keywords ) {
my($query) = $cgi->keywords;
$query =~ /^(\d+)$/;
$rate = qsearchs( 'rate', { 'ratenum' => $1 } );
))
%>
-<% if ( $error ) { %>
-<FONT SIZE="+1" COLOR="#ff0000">Error: <%= $error %></FONT><BR>
-<% } %>
+<!-- <FORM ACTION="<%=$p1%>rate.cgi" NAME="OneTrueForm" METHOD=POST onSubmit="document.OneTrueForm.submit.disabled=true"> -->
+
+<SCRIPT TYPE="text/javascript" SRC="../elements/jsrsClient.js"></SCRIPT>
+<SCRIPT TYPE="text/javascript">
+function process () {
+ document.OneTrueForm.submit.disabled=true;
+
+ var Hash = new Array();
+ var x = 0;
+ var fieldName;
+ for (var i = 0; i<document.OneTrueForm.elements.length; i++) {
+ fieldName = document.OneTrueForm.elements[i].name;
+ if ( (fieldName.indexOf('rate') > -1)
+ || (fieldName.indexOf('min_') > -1)
+ || (fieldName.indexOf('sec_') > -1)
+ )
+ {
+ Hash[x++] = fieldName;
+ Hash[x++] = document.OneTrueForm.elements[i].value;
+ }
+ }
+
+ jsrsPOST = true;
+ jsrsExecute( 'process/rate.cgi', myCallback, 'process_rate', Hash );
+
+ function myCallback( jobnum ) {
+ var progressWindow = window.open('../../misc/progress.html?jobnum=' + jobnum + ';url=<%=$p%>browse/rate.cgi', 'progressWindow', 'toolbar=no,location=no,directories=no,scrollbars=no,menubar=no,status=no,width=420,height=128');
+ progressWindow.opener = self;
+ //progressWindow.opener = document;
+ }
+
+}
+</SCRIPT>
-<FORM ACTION="<%=$p1%>rate.cgi" NAME="OneTrueForm" METHOD=POST onSubmit="document.OneTrueForm.submit.disabled=true">
-<INPUT TYPE="hidden" NAME="magic" VALUE="process">
+<FORM NAME="OneTrueForm">
<INPUT TYPE="hidden" NAME="ratenum" VALUE="<%= $rate->ratenum %>">
Rate plan
</TABLE>
-<BR><INPUT NAME="submit" TYPE="submit" VALUE="<%=
+<BR><INPUT NAME="submit" TYPE="button" VALUE="<%=
$rate->ratenum ? "Apply changes" : "Add rate plan"
-%>">
-Please be patient, <%= $rate->ratenum ? 'editing' : 'adding' %>
-a rate plan can take a few minutes...
+%>" onClick="document.OneTrueForm.submit.disabled=true; process();">
+Please make sure to allow popups from this site in order to view the progress window.
+<!-- Please be patient, <%= $rate->ratenum ? 'editing' : 'adding' %>
+a rate plan can take a few minutes... -->
</FORM>
</BODY>
--- /dev/null
+//
+// jsrsClient.js - javascript remote scripting client include
+//
+// Author: Brent Ashley [jsrs@megahuge.com]
+//
+// make asynchronous remote calls to server without client page refresh
+//
+// see license.txt for copyright and license information
+
+/*
+see history.txt for full history
+2.0 26 Jul 2001 - added POST capability for IE/MOZ
+2.2 10 Aug 2003 - added Opera support
+2.3(beta) 10 Oct 2003 - added Konqueror support - **needs more testing**
+*/
+
+// callback pool needs global scope
+var jsrsContextPoolSize = 0;
+var jsrsContextMaxPool = 10;
+var jsrsContextPool = new Array();
+var jsrsBrowser = jsrsBrowserSniff();
+var jsrsPOST = true;
+var containerName;
+
+// constructor for context object
+function jsrsContextObj( contextID ){
+
+ // properties
+ this.id = contextID;
+ this.busy = true;
+ this.callback = null;
+ this.container = contextCreateContainer( contextID );
+
+ // methods
+ this.GET = contextGET;
+ this.POST = contextPOST;
+ this.getPayload = contextGetPayload;
+ this.setVisibility = contextSetVisibility;
+}
+
+// method functions are not privately scoped
+// because Netscape's debugger chokes on private functions
+function contextCreateContainer( containerName ){
+ // creates hidden container to receive server data
+ var container;
+ switch( jsrsBrowser ) {
+ case 'NS':
+ container = new Layer(100);
+ container.name = containerName;
+ container.visibility = 'hidden';
+ container.clip.width = 100;
+ container.clip.height = 100;
+ break;
+
+ case 'IE':
+ document.body.insertAdjacentHTML( "afterBegin", '<span id="SPAN' + containerName + '"></span>' );
+ var span = document.all( "SPAN" + containerName );
+ var html = '<iframe name="' + containerName + '" src=""></iframe>';
+ span.innerHTML = html;
+ span.style.display = 'none';
+ container = window.frames[ containerName ];
+ break;
+
+ case 'MOZ':
+ var span = document.createElement('SPAN');
+ span.id = "SPAN" + containerName;
+ document.body.appendChild( span );
+ var iframe = document.createElement('IFRAME');
+ iframe.name = containerName;
+ iframe.id = containerName;
+ span.appendChild( iframe );
+ container = iframe;
+ break;
+
+ case 'OPR':
+ var span = document.createElement('SPAN');
+ span.id = "SPAN" + containerName;
+ document.body.appendChild( span );
+ var iframe = document.createElement('IFRAME');
+ iframe.name = containerName;
+ iframe.id = containerName;
+ span.appendChild( iframe );
+ container = iframe;
+ break;
+
+ case 'KONQ':
+ var span = document.createElement('SPAN');
+ span.id = "SPAN" + containerName;
+ document.body.appendChild( span );
+ var iframe = document.createElement('IFRAME');
+ iframe.name = containerName;
+ iframe.id = containerName;
+ span.appendChild( iframe );
+ container = iframe;
+
+ // Needs to be hidden for Konqueror, otherwise it'll appear on the page
+ span.style.display = none;
+ iframe.style.display = none;
+ iframe.style.visibility = hidden;
+ iframe.height = 0;
+ iframe.width = 0;
+
+ break;
+ }
+ return container;
+}
+
+function contextPOST( rsPage, func, parms ){
+
+ var d = new Date();
+ var unique = d.getTime() + '' + Math.floor(1000 * Math.random());
+ var doc = (jsrsBrowser == "IE" ) ? this.container.document : this.container.contentDocument;
+ doc.open();
+ doc.write('<html><body>');
+ doc.write('<form name="jsrsForm" method="post" target="" ');
+ doc.write(' action="' + rsPage + '?U=' + unique + '">');
+ doc.write('<input type="hidden" name="C" value="' + this.id + '">');
+
+ // func and parms are optional
+ if (func != null){
+ doc.write('<input type="hidden" name="F" value="' + func + '">');
+
+ if (parms != null){
+ if (typeof(parms) == "string"){
+ // single parameter
+ doc.write( '<input type="hidden" name="P0" '
+ + 'value="[' + jsrsEscapeQQ(parms) + ']">');
+ } else {
+ // assume parms is array of strings
+ for( var i=0; i < parms.length; i++ ){
+ doc.write( '<input type="hidden" name="P' + i + '" '
+ + 'value="[' + jsrsEscapeQQ(parms[i]) + ']">');
+ }
+ } // parm type
+ } // parms
+ } // func
+
+ doc.write('</form></body></html>');
+ doc.close();
+ doc.forms['jsrsForm'].submit();
+}
+
+function contextGET( rsPage, func, parms ){
+
+ // build URL to call
+ var URL = rsPage;
+
+ // always send context
+ URL += "?C=" + this.id;
+
+ // func and parms are optional
+ if (func != null){
+ URL += "&F=" + escape(func);
+
+ if (parms != null){
+ if (typeof(parms) == "string"){
+ // single parameter
+ URL += "&P0=[" + escape(parms+'') + "]";
+ } else {
+ // assume parms is array of strings
+ for( var i=0; i < parms.length; i++ ){
+ URL += "&P" + i + "=[" + escape(parms[i]+'') + "]";
+ }
+ } // parm type
+ } // parms
+ } // func
+
+ // unique string to defeat cache
+ var d = new Date();
+ URL += "&U=" + d.getTime();
+
+ // make the call
+ switch( jsrsBrowser ) {
+ case 'NS':
+ this.container.src = URL;
+ break;
+ case 'IE':
+ this.container.document.location.replace(URL);
+ break;
+ case 'MOZ':
+ this.container.src = '';
+ this.container.src = URL;
+ break;
+ case 'OPR':
+ this.container.src = '';
+ this.container.src = URL;
+ break;
+ case 'KONQ':
+ this.container.src = '';
+ this.container.src = URL;
+ break;
+ }
+}
+
+function contextGetPayload(){
+ switch( jsrsBrowser ) {
+ case 'NS':
+ return this.container.document.forms['jsrs_Form'].elements['jsrs_Payload'].value;
+ case 'IE':
+ return this.container.document.forms['jsrs_Form']['jsrs_Payload'].value;
+ case 'MOZ':
+ return window.frames[this.container.name].document.forms['jsrs_Form']['jsrs_Payload'].value;
+ case 'OPR':
+ var textElement = window.frames[this.container.name].document.getElementById("jsrs_Payload");
+ case 'KONQ':
+ var textElement = window.frames[this.container.name].document.getElementById("jsrs_Payload");
+ return textElement.value;
+ }
+}
+
+function contextSetVisibility( vis ){
+ switch( jsrsBrowser ) {
+ case 'NS':
+ this.container.visibility = (vis)? 'show' : 'hidden';
+ break;
+ case 'IE':
+ document.all("SPAN" + this.id ).style.display = (vis)? '' : 'none';
+ break;
+ case 'MOZ':
+ document.getElementById("SPAN" + this.id).style.visibility = (vis)? '' : 'hidden';
+ case 'OPR':
+ document.getElementById("SPAN" + this.id).style.visibility = (vis)? '' : 'hidden';
+ this.container.width = (vis)? 250 : 0;
+ this.container.height = (vis)? 100 : 0;
+ break;
+ }
+}
+
+// end of context constructor
+
+function jsrsGetContextID(){
+ var contextObj;
+ for (var i = 1; i <= jsrsContextPoolSize; i++){
+ contextObj = jsrsContextPool[ 'jsrs' + i ];
+ if ( !contextObj.busy ){
+ contextObj.busy = true;
+ return contextObj.id;
+ }
+ }
+ // if we got here, there are no existing free contexts
+ if ( jsrsContextPoolSize <= jsrsContextMaxPool ){
+ // create new context
+ var contextID = "jsrs" + (jsrsContextPoolSize + 1);
+ jsrsContextPool[ contextID ] = new jsrsContextObj( contextID );
+ jsrsContextPoolSize++;
+ return contextID;
+ } else {
+ alert( "jsrs Error: context pool full" );
+ return null;
+ }
+}
+
+function jsrsExecute( rspage, callback, func, parms, visibility ){
+ // call a server routine from client code
+ //
+ // rspage - href to asp file
+ // callback - function to call on return
+ // or null if no return needed
+ // (passes returned string to callback)
+ // func - sub or function name to call
+ // parm - string parameter to function
+ // or array of string parameters if more than one
+ // visibility - optional boolean to make container visible for debugging
+
+ // get context
+ var contextObj = jsrsContextPool[ jsrsGetContextID() ];
+ contextObj.callback = callback;
+
+ var vis = (visibility == null)? false : visibility;
+ contextObj.setVisibility( vis );
+
+ if ( jsrsPOST && ((jsrsBrowser == 'IE') || (jsrsBrowser == 'MOZ'))){
+ contextObj.POST( rspage, func, parms );
+ } else {
+ contextObj.GET( rspage, func, parms );
+ }
+
+ return contextObj.id;
+}
+
+function jsrsLoaded( contextID ){
+ // get context object and invoke callback
+ var contextObj = jsrsContextPool[ contextID ];
+ if( contextObj.callback != null){
+ contextObj.callback( jsrsUnescape( contextObj.getPayload() ), contextID );
+ }
+ // clean up and return context to pool
+ contextObj.callback = null;
+ contextObj.busy = false;
+}
+
+function jsrsError( contextID, str ){
+ alert( unescape(str) );
+ jsrsContextPool[ contextID ].busy = false
+}
+
+function jsrsEscapeQQ( thing ){
+ return thing.replace(/'"'/g, '\\"');
+}
+
+function jsrsUnescape( str ){
+ // payload has slashes escaped with whacks
+ return str.replace( /\\\//g, "/" );
+}
+
+function jsrsBrowserSniff(){
+ if (document.layers) return "NS";
+ if (document.all) {
+ // But is it really IE?
+ // convert all characters to lowercase to simplify testing
+ var agt=navigator.userAgent.toLowerCase();
+ var is_opera = (agt.indexOf("opera") != -1);
+ var is_konq = (agt.indexOf("konqueror") != -1);
+ if(is_opera) {
+ return "OPR";
+ } else {
+ if(is_konq) {
+ return "KONQ";
+ } else {
+ // Really is IE
+ return "IE";
+ }
+ }
+ }
+ if (document.getElementById) return "MOZ";
+ return "OTHER";
+}
+
+/////////////////////////////////////////////////
+//
+// user functions
+
+function jsrsArrayFromString( s, delim ){
+ // rebuild an array returned from server as string
+ // optional delimiter defaults to ~
+ var d = (delim == null)? '~' : delim;
+ return s.split(d);
+}
+
+function jsrsDebugInfo(){
+ // use for debugging by attaching to f1 (works with IE)
+ // with onHelp = "return jsrsDebugInfo();" in the body tag
+ var doc = window.open().document;
+ doc.open;
+ doc.write( 'Pool Size: ' + jsrsContextPoolSize + '<br><font face="arial" size="2"><b>' );
+ for( var i in jsrsContextPool ){
+ var contextObj = jsrsContextPool[i];
+ doc.write( '<hr>' + contextObj.id + ' : ' + (contextObj.busy ? 'busy' : 'available') + '<br>');
+ doc.write( contextObj.container.document.location.pathname + '<br>');
+ doc.write( contextObj.container.document.location.search + '<br>');
+ doc.write( '<table border="1"><tr><td>' + contextObj.container.document.body.innerHTML + '</td></tr></table>' );
+ }
+ doc.write('</table>');
+ doc.close();
+ return false;
+}
--- /dev/null
+/**\r
+ * QLIB 1.0 Box Control\r
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * http://qlib.quazzle.com\r
+ */\r
+\r
+function QBox(parent, name, res, x, y, width, height, body, visible, effects, opacity, zindex) {\r
+ this.init(parent, name);\r
+ if (this.res = res) {\r
+ this.x = x - 0;\r
+ this.y = y - 0;\r
+ this.width = width - 0;\r
+ this.height = (typeof(height) == "number") ? height : null;\r
+ this.body = body || " ";\r
+ var j = QBox.arguments.length;\r
+ this.visible = (j > 8) ? visible : true;\r
+ this.effects = (j > 9) ? effects : (res.effects || 0);\r
+ this.opacity = (j > 10) ? opacity : (res.opacity != null ? res.opacity : 100);\r
+ this.zindex = (j > 11) ? zindex : null;\r
+ this.create();\r
+ } else {\r
+ this.document.write("invalid resource");\r
+ }\r
+}\r
+QBox.prototype = new QBoxCtrl();\r
--- /dev/null
+/**\r
+ * QLIB 1.0 Box Abstraction\r
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * http://qlib.quazzle.com\r
+ */\r
+\r
+function QBoxCtrl_content() {\r
+ with (this) {\r
+ if (res) {\r
+ this.cwidth = width - res.L - res.R - 8;\r
+ this.cheight = height && (height - res.T - res.B - 8);\r
+ var ec = '"><table border="0" cellspacing="0" cellpadding="0"><tr><td></td></tr></table></td>';\r
+ document.write('<table class="qbox" border="0" cellspacing="0" cellpadding="0" width="' +\r
+ (width - 8) + (height != null ? '" height="' + (height - 8) : '') + '"><tr><td width="' +\r
+ res.L + '" height="' + res.T + '"><img src="' + res.TL.src + '" border="0" width="' +\r
+ res.L + '" height="' + res.T + '"></td><td width="' + cwidth + '" height="' + res.T +\r
+ '" background="' + res.TC.src + ec + '<td width="' + res.R + '" height="' + res.T +\r
+ '"><img src="' + res.TR.src + '" border="0" width="' + res.R + '" height="' + res.T +\r
+ '"></td></tr><tr><td width="' + res.L + (cheight != null ? '" height="' + cheight : '') +\r
+ '" background="' + res.ML.src + ec + '<td width="' + cwidth + '" bgcolor="' + res.bgcolor +\r
+ (cheight != null ? '" height="' + cheight : '') + (res.bgtile ? '" background="' +\r
+ res.bgtile.src : '') + '" align="left" valign="top" class="body" unselectable="on">');\r
+ if (typeof(body) == "function") {\r
+ this.body();\r
+ } else {\r
+ document.write(body);\r
+ }\r
+ document.write('</td><td width="' + res.R + (cheight != null ? '" height="' + cheight : '') +\r
+ '" background="' + res.MR.src + ec + '</tr><tr><td width="' + res.L + '" height="' + res.B +\r
+ '"><img src="' + res.BL.src + '" border="0" width="' + res.L + '" height="' + res.B +\r
+ '"></td><td width="' + cwidth + '" height="' + res.B + '" background="' + res.BC.src + ec +\r
+ '<td width="' + res.R + '" height="' + res.B + '"><img src="' + res.BR.src +\r
+ '" border="0" width="' + res.R + '" height="' + res.B + '"></td></tr></table><br>');\r
+ }\r
+ }\r
+}\r
+\r
+function QBoxCtrl() {\r
+ this.res = false;\r
+ this.body = " ";\r
+ this.cwidth = this.cheight = 0;\r
+ this.content = QBoxCtrl_content;\r
+}\r
+QBoxCtrl.prototype = new QWndCtrl();\r
--- /dev/null
+/**\r
+ * QLIB 1.0 Box Resource\r
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * http://qlib.quazzle.com\r
+ */\r
+\r
+function QBoxRes(t, r, b, l, tc, tr, mr, br, bc, bl, ml, tl, bgcolor, bgtile, effects, opacity) { \r
+ var args = QBoxRes.arguments.length;\r
+ this.T = t;\r
+ this.R = r;\r
+ this.B = b;\r
+ this.L = l;\r
+ this.TC = new Image();\r
+ this.TC.src = tc;\r
+ this.TR = new Image(r, t);\r
+ this.TR.src = tr;\r
+ this.MR = new Image();\r
+ this.MR.src = mr;\r
+ this.BR = new Image(r, b);\r
+ this.BR.src = br;\r
+ this.BC = new Image();\r
+ this.BC.src = bc;\r
+ this.BL = new Image(l, b);\r
+ this.BL.src = bl;\r
+ this.ML = new Image();\r
+ this.ML.src = ml;\r
+ this.TL = new Image(l, t);\r
+ this.TL.src = tl;\r
+ this.bgcolor = bgcolor || "#FFFFFF";\r
+ if (bgtile) {\r
+ this.bgtile = new Image();\r
+ this.bgtile.src = bgtile;\r
+ } else {\r
+ this.bgtile = false;\r
+ }\r
+ this.effects = (args > 13) ? effects : null;\r
+ this.opacity = (args > 14) ? opacity : null;\r
+}\r
--- /dev/null
+/**\r
+ * QLIB 1.0 Button Control\r
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * http://qlib.quazzle.com\r
+ */\r
+\r
+function QButton_update() {\r
+ with (this) {\r
+ image.src = ((!enabled && res.imgD) || (value ? res.imgP : res.imgN)).src;\r
+ }\r
+}\r
+\r
+function QButton_doEvent() {\r
+ with (this) {\r
+ if (enabled) {\r
+ if (res.style == 1) {\r
+ this.value = value ? 0 : 1;\r
+ update();\r
+ }\r
+ onClick(value, tag);\r
+ }\r
+ }\r
+ return false;\r
+}\r
+\r
+function QButton_enable(state) {\r
+ this.enabled = state;\r
+ this.update();\r
+}\r
+\r
+function QButton_set(value) {\r
+ if (this.enabled) {\r
+ this.value = value ? 1 : 0;\r
+ this.update();\r
+ }\r
+ return true;\r
+}\r
+\r
+function QButton(parent, name, res, tooltip) {\r
+ this.init(parent, name);\r
+ if (res) {\r
+ this.res = res;\r
+ this.tip = tooltip || "";\r
+ this.enabled = true;\r
+ this.value = 0;\r
+ this.set = QButton_set;\r
+ this.enable = QButton_enable;\r
+ this.update = QButton_update;\r
+ this.doEvent = QButton_doEvent;\r
+ this.onClick = QControl.event;\r
+ with (this) {\r
+ document.write('<a href="#" hidefocus="true" unselectable="on"' +\r
+ (tip ? ' title="' + tip + '"' : '') + ' onClick="return ' + name +\r
+ '.doEvent()" onMouseOver="' + (res.style == 2 ? name + '.set(1);' : '') +\r
+ 'window.top.status=' + name + '.tip;return true" onMouseOut="' +\r
+ (!res.style || (res.style == 2) ? name + '.set();' : '') + 'window.top.status=\'\'"' +\r
+ (!res.style ? ' onMouseDown="return ' + name + '.set(1)" onMouseUp="return ' + name + '.set()"' : '') +\r
+ '><img class="qbutton" name="' + id + '" src="' + res.imgN.src + '" border="0" width="' +\r
+ res.width + '" height="' + res.height + '"></a>');\r
+ this.image = document.images[id] || new Image(1, 1);\r
+ }\r
+ } else {\r
+ this.document.write("invalid resource");\r
+ }\r
+}\r
+QButton.prototype = new QControl();\r
+QButton.NORMAL = 0;\r
+QButton.CHECKBOX = 1;\r
+QButton.WEB = 2;\r
+QButton.SIGNAL = 3;\r
--- /dev/null
+/**\r
+ * QLIB 1.0 Button Resource\r
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * http://qlib.quazzle.com\r
+ */\r
+\r
+function QButtonRes(style, width, height, normal, pressed, disabled) {\r
+ this.style = style;\r
+ this.width = width;\r
+ this.height = height;\r
+ this.imgN = new Image(width, height);\r
+ this.imgN.src = normal;\r
+ this.imgP = new Image(width, height);\r
+ this.imgP.src = pressed;\r
+ if (disabled) {\r
+ this.imgD = new Image(width, height);\r
+ this.imgD.src = disabled;\r
+ }\r
+}\r
--- /dev/null
+/**\r
+ * QLIB 1.0 Base Abstract Control\r
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * http://qlib.quazzle.com\r
+ */\r
+\r
+function QControl_init(parent, name) {\r
+ this.parent = parent || self;\r
+ this.window = (parent && parent.window) || self;\r
+ this.document = (parent && parent.document) || self.document;\r
+ this.name = (parent && parent.name) ? (parent.name + "." + name) : ("self." + name);\r
+ this.id = "Q";\r
+ var h = this.hash(this.name);\r
+ for (var j=0; j<8; j++) {\r
+ this.id += QControl.HEXTABLE.charAt(h & 15);\r
+ h >>>= 4;\r
+ }\r
+}\r
+\r
+function QControl_hash(str) {\r
+ var h = 0;\r
+ if (str) {\r
+ for (var j=str.length-1; j>=0; j--) {\r
+ h ^= QControl.ANTABLE.indexOf(str.charAt(j)) + 1;\r
+ for (var i=0; i<3; i++) {\r
+ var m = (h = h<<7 | h>>>25) & 150994944;\r
+ h ^= m ? (m == 150994944 ? 1 : 0) : 1;\r
+ }\r
+ }\r
+ }\r
+ return h;\r
+}\r
+\r
+function QControl_nop() {\r
+}\r
+\r
+function QControl() {\r
+ this.init = QControl_init;\r
+ this.hash = QControl_hash;\r
+ this.window = self;\r
+ this.document = self.document;\r
+ this.tag = null;\r
+}\r
+QControl.ANTABLE = "w5Q2KkFts3deLIPg8Nynu_JAUBZ9YxmH1XW47oDpa6lcjMRfi0CrhbGSOTvqzEV";\r
+QControl.HEXTABLE = "0123456789ABCDEF";\r
+QControl.nop = QControl_nop;\r
+QControl.event = QControl_nop;\r
--- /dev/null
+/**\r
+ * QLIB 1.0 Animated Digital Counter\r
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * http://qlib.quazzle.com\r
+ */\r
+\r
+function QCounter_update() {\r
+ with (this) {\r
+ var v = Math.max(value, 0);\r
+ var mod;\r
+ for (var j=0; j<size; j++) {\r
+ mod = Math.floor(v % 10);\r
+ images[j].src = (v >= 1) || (!j) ? res.list[mod].src : res.list[10].src;\r
+ v /= 10;\r
+ }\r
+ }\r
+}\r
+\r
+function QCounter_count(value, step) {\r
+ this._cntt = false;\r
+ this.value += step; \r
+ if ((step * (this.value - value)) >= 0) {\r
+ this.value = value - 0; // convert to number\r
+ } else {\r
+ this._cntt = setTimeout(this.name + ".count(" + value + "," + step + ")", 50);\r
+ }\r
+ this.update();\r
+}\r
+ \r
+function QCounter_set(value) {\r
+ this.setval = value;\r
+ if (value != this.value) {\r
+ if (this._cntt) {\r
+ clearTimeout(this._cntt);\r
+ this._cntt = false;\r
+ }\r
+ var dv = value - this.value;\r
+ if (this.effect == 2) {\r
+ dv = dv / Math.min(10, Math.abs(dv));\r
+ } else if (this.effect == 3) {\r
+ dv = dv / Math.abs(dv);\r
+ }\r
+ this.count(value, dv);\r
+ }\r
+}\r
+\r
+function QCounter(parent, name, res, size, effect) {\r
+ this.init(parent, name);\r
+ if (res) {\r
+ this.res = res;\r
+ this.setval = this.value = 0;\r
+ this.size = size || 4;\r
+ this.effect = effect || 2;\r
+ this._cntt = false;\r
+ this.images = new Array(this.size);\r
+ this.set = QCounter_set;\r
+ this.update = QCounter_update;\r
+ this.count = QCounter_count;\r
+ with (this) {\r
+ document.write('<table class="qcounter" width="' + (res.width * size) + '" height="' + res.height +\r
+ '" border="0" cellspacing="0" cellpadding="0" unselectable="on"><tr>');\r
+ for (var j=(size - 1); j>=0; j--) {\r
+ document.write('<td width="' + res.width + '" height="' + res.height +\r
+ '" unselectable="on"><img name="' + id + j + '" src="' + (j ? res.list[10].src : res.list[0].src) +\r
+ '" border="0" width="' + res.width + '" height="' + res.height + '"></td>');\r
+ images[j] = document.images[id + j] || new Image(1, 1);\r
+ }\r
+ document.write('</tr></table>');\r
+ }\r
+ } else {\r
+ this.document.write("invalid resource");\r
+ }\r
+}\r
+QCounter.prototype = new QControl();\r
+QCounter.INSTANT = 1;\r
+QCounter.FAST = 2;\r
+QCounter.SLOW = 3;\r
--- /dev/null
+/**\r
+ * QLIB 1.0 ImageList Resource\r
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * http://qlib.quazzle.com\r
+ */\r
+\r
+function QImageList(width, height) {\r
+ var len = QImageList.arguments.length - 2;\r
+ if (len > 0) {\r
+ this.list = new Array(len);\r
+ this.length = len;\r
+ this.width = width;\r
+ this.height = height;\r
+ var im;\r
+ for (var j=0; j<len; j++) {\r
+ im = new Image(width, height);\r
+ im.src = QImageList.arguments[j + 2];\r
+ this.list[j] = im;\r
+ }\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+/**\r
+ * QLIB 1.0 Text Label\r
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * http://qlib.quazzle.com\r
+ */\r
+\r
+function QLabel_set_ie(value) {\r
+ this.label.innerText = (this.value = value) || "\xA0";\r
+}\r
+\r
+function QLabel_set_dom2(value) {\r
+ with (this.label) {\r
+ replaceChild(this.document.createTextNode((this.value = value) || "\xA0"), firstChild);\r
+ }\r
+}\r
+\r
+function QLabel_set_ns4(value) {\r
+ this.value = value || "";\r
+ with (this) {\r
+ document.open();\r
+ document.write('<div class="qlabel">' + (clickable ? '<a href="#" title="' + tooltip + '" onClick="return ' +\r
+ name + '.doEvent()" onMouseOut="window.top.status=\'\'" onMouseOver="window.top.status=' + name +\r
+ '.tooltip;return true">' + value + '</a>' : value) + '</div>');\r
+ document.close();\r
+ }\r
+}\r
+\r
+function QLabel_doEvent() {\r
+ this.onClick(this.value, this.tag);\r
+ return false;\r
+}\r
+\r
+function QLabel(parent, name, value, clickable, tooltip) {\r
+ this.init(parent, name);\r
+ this.value = value || "";\r
+ this.clickable = clickable || false;\r
+ this.tooltip = tooltip || "";\r
+ this.doEvent = QLabel_doEvent;\r
+ this.onClick = QControl.event;\r
+ with (this) {\r
+ if (document.getElementById || document.all) {\r
+ document.write(clickable ? '<div class="qlabel" unselectable="on"><a id="' + id + '" href="#" title="' +\r
+ tooltip + '" onClick="return ' + name + '.doEvent()" onMouseOver="window.top.status=' + name +\r
+ '.tooltip;return true" onMouseOut="window.top.status=\'\'" hidefocus="true" unselectable="on">' +\r
+ (value || ' ') + '</a></div>' : '<div id="' + id + '" class="qlabel" unselectable="on">' +\r
+ (value || ' ') + '</div>');\r
+ this.label = document.getElementById ? document.getElementById(id) :\r
+ (document.all.item ? document.all.item(id) : document.all[id]);\r
+ this.set = (label && (label.innerText ? QLabel_set_ie :\r
+ (label.replaceChild && QLabel_set_dom2))) || QControl.nop;\r
+ } else if (document.layers) {\r
+ var suffix = "";\r
+ for (var j=value.length; j<QLabel.TEXTQUOTA; j++) suffix += " ";\r
+ document.write('<div><ilayer id="i' + id + '"><layer id="' + id + '"><div class="qlabel">' +\r
+ (clickable ? '<a href="#" title="' + tooltip + '" onClick="return ' + name +\r
+ '.doEvent()" onMouseOver="window.top.status=' + name +\r
+ '.tooltip;return true" onMouseOut="window.top.status=\'\'">' + value + suffix + '</a>' :\r
+ value + suffix) + '</div></layer></ilayer></div>');\r
+ this.label = (this.label = document.layers["i" + id]) && label.document.layers[id];\r
+ this.document = label && label.document;\r
+ this.set = (label && document) ? QLabel_set_ns4 : QControl.nop;\r
+ } else {\r
+ document.write("Object is not supported");\r
+ }\r
+ }\r
+}\r
+QLabel.prototype = new QControl();\r
+QLabel.TEXTQUOTA = 50;\r
--- /dev/null
+/**\r
+ * QLIB 1.0 Message Box Control\r
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * http://qlib.quazzle.com\r
+ */\r
+\r
+function QMessageBox_alert(msg) {\r
+ if (typeof(msg) == "string") {\r
+ this.label.set(this.value = msg);\r
+ }\r
+ this.center();\r
+ this.focus();\r
+ this.show(true);\r
+}\r
+\r
+function QMessageBox_close() {\r
+ with (this.parent) {\r
+ if (!onClose(tag)) show(false);\r
+ }\r
+}\r
+\r
+function QMessageBox_body() {\r
+ with (this) {\r
+ document.write('<table border="0" width="' + cwidth + '"><tr><td align="left" valign="top" unselectable="on">');\r
+ this.label = new QLabel(this, "label", value);\r
+ document.write('</td></tr><tr><td height="' + (bres.height + 14) + '" align="center" valign="bottom" unselectable="on">');\r
+ this.button = new QButton(this, "button", bres, "Close");\r
+ document.write('</td></tr></table>');\r
+ button.onClick = QMessageBox_close;\r
+ }\r
+}\r
+\r
+function QMessageBox(parent, name, box, btn, msg, effects, opacity) {\r
+ this.init(parent, name);\r
+ if ((this.res = box) && (this.bres = btn)) {\r
+ this.value = typeof(msg) == "string" ? msg : "";\r
+ this.width = Math.max(200, Math.floor(Math.sqrt(555 * this.value.length)));\r
+ this.height = null;\r
+ this.x = this.y = 0;\r
+ this.visible = false;\r
+ this.zindex = null;\r
+ this.body = QMessageBox_body;\r
+ var j = QMessageBox.arguments.length;\r
+ this.effects = j > 5 ? effects : (box.effects != null ? box.effects : 0);\r
+ this.opacity = j > 6 ? opacity : (box.opacity != null ? box.opacity : 100);\r
+ this.create();\r
+ this.alert = QMessageBox_alert;\r
+ this.onClose = QControl.event;\r
+ } else {\r
+ this.document.write("invalid resource");\r
+ }\r
+}\r
+QMessageBox.prototype = new QBoxCtrl();\r
--- /dev/null
+/**\r
+ * QLIB 1.0 Progress Control\r
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * http://qlib.quazzle.com\r
+ */\r
+\r
+function QProgress_update() {\r
+ with (this) {\r
+ var i = low;\r
+ for (var j=0; j<size; j++) {\r
+ images[j].src = i < value ? imgsrc1 : imgsrc0;\r
+ i += delta;\r
+ }\r
+ }\r
+}\r
+\r
+function QProgress_set(value) {\r
+ this.value = value - 0;\r
+ this.update();\r
+}\r
+\r
+function QProgress_setBounds(low, high) {\r
+ this.low = Math.min(low, high);\r
+ this.high = Math.max(low, high);\r
+ this.delta = (this.high - this.low) / this.size;\r
+ this.update();\r
+}\r
+ \r
+function QProgress(parent, name, res, size, style) {\r
+ this.init(parent, name);\r
+ if (res) {\r
+ this.res = res;\r
+ this.value = 0;\r
+ this.low = 0;\r
+ this.high = 100;\r
+ this.size = size || 10;\r
+ this.delta = 100 / this.size;\r
+ this.style = style || 0;\r
+ this.images = new Array(this.size);\r
+ this.imgsrc0 = res.list[0] && res.list[0].src;\r
+ this.imgsrc1 = res.list[1] && res.list[1].src;\r
+ this.set = QProgress_set;\r
+ this.update = QProgress_update;\r
+ this.setBounds = QProgress_setBounds;\r
+ with (this) {\r
+ var hor = this.style < 2;\r
+ var rev = this.style % 2;\r
+ document.write('<table class="qprogress" border="0" cellspacing="0" cellpadding="0" unselectable="on" ' +\r
+ (hor ? 'width="' + (size * res.width) + '" height="' + res.height + '"><tr>' : 'width="' + res.width +\r
+ '" height="' + (size * res.height) + '">'));\r
+ for (var j=0; j<size; j++) {\r
+ document.write((hor ? '' : '<tr>') + '<td width="' + res.width + '" height="' + res.height +\r
+ '" unselectable="on"><img name="' + id + (rev ? size - j - 1 : j) + '" src="' + res.list[0].src +\r
+ '" border="0" width="' + res.width + '" height="' + res.height + '"></td>' + (hor ? '' : '</tr>'));\r
+ }\r
+ document.write((hor ? '</tr>' : '') + '</table>');\r
+ for (var j=0; j<size; j++) {\r
+ images[j] = document.images[id + j] || new Image(1, 1);\r
+ }\r
+ }\r
+ } else {\r
+ this.document.write("invalid resource");\r
+ }\r
+}\r
+QProgress.prototype = new QControl();\r
+QProgress.NORMAL = 0;\r
+QProgress.REVERSE = 1;\r
+QProgress.FALL = 2;\r
+QProgress.RISE = 3;\r
--- /dev/null
+/**\r
+ * QLIB 1.0 Preloaded Sound\r
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * http://qlib.quazzle.com\r
+ */\r
+\r
+function QSound_play(loop) {\r
+ this._out.loop = loop || 0;\r
+ this._out.src = this._buf.src;\r
+}\r
+\r
+function QSound_stop() {\r
+ this._out.loop = 0;\r
+ this._out.src = "";\r
+}\r
+\r
+function QSound_setVolume(volume) {\r
+ this._out.volume = this.volume = volume;\r
+}\r
+ \r
+function QSound(parent, name, src, volume) {\r
+ this.init(parent, name);\r
+ this.volume = volume || 0;\r
+ this.play = this.stop = this.setVolume = QControl.nop;\r
+ with (this) {\r
+ document.write('<bgsound id="' + id + '" src="" volume="' + volume + '">');\r
+ if (document.all && document.all.item) {\r
+ this._out = document.all.item(id);\r
+ if (_out && (typeof _out.src != "undefined") && (_out.volume === volume)) {\r
+ document.write('<bgsound id="b' + id + '" src="' + src + '" volume="-10000">');\r
+ this._buf = document.all.item("b" + id);\r
+ if (_buf) {\r
+ this.play = QSound_play;\r
+ this.stop = QSound_stop;\r
+ this.setVolume = QSound_setVolume;\r
+\r
+ _out.onreadystatechange = new Function("alert(0)");\r
+ }\r
+ }\r
+ }\r
+ }\r
+}\r
+QSound.prototype = new QControl();\r
--- /dev/null
+/**\r
+ * QLIB 1.0 Sprite Object\r
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * http://qlib.quazzle.com\r
+ */\r
+\r
+function QSprite_load(src) {\r
+ if (src) {\r
+ this.face = new Image(this.cwidth, this.cheight);\r
+ this.face.src = src;\r
+ this.valid = false;\r
+ }\r
+}\r
+ \r
+function QSprite_show(show) {\r
+ if (show && !this.valid && this.face.complete) {\r
+ this._img.src = this.face.src;\r
+ this.valid = true;\r
+ }\r
+ this._show(show);\r
+}\r
+\r
+function QSprite_moveTo(x, y) {\r
+ this.stop();\r
+ this._move(x, y);\r
+}\r
+\r
+function QSprite_slideTo(x, y) {\r
+ this.stop();\r
+ if (this.visible) {\r
+ this.doSlide(++this._spro, x, y);\r
+ } else {\r
+ this.moveTo(x, y);\r
+ }\r
+}\r
+\r
+function QSprite_shake() {\r
+ this.stop();\r
+ if (this.visible) {\r
+ this.doShake(++this._spro, 0, this.x, this.y);\r
+ }\r
+}\r
+\r
+function QSprite_stop() {\r
+ this._spro++;\r
+ if (this._sprt) {\r
+ clearTimeout(this._sprt);\r
+ this._sprt = false;\r
+ }\r
+}\r
+\r
+function QSprite_doSlide(id, x, y) {\r
+ if (this._spro == id) {\r
+ this._sprt = false;\r
+ var dx = Math.round(x - this.x);\r
+ var dy = Math.round(y - this.y);\r
+ if (dx || dy) {\r
+ if (dx) dx = dx > 0 ? Math.ceil(dx/4) : Math.floor(dx/4);\r
+ if (dy) dy = dy > 0 ? Math.ceil(dy/4) : Math.floor(dy/4);\r
+ this._move(this.x + dx, this.y + dy);\r
+ this._sprt = setTimeout(this.name + ".doSlide(" + id + "," + x + "," + y + ")", 30);\r
+ } else {\r
+ this._move(x, y);\r
+ }\r
+ }\r
+}\r
+\r
+function QSprite_doShake(id, phase, x, y) {\r
+ if (this._spro == id) {\r
+ this._sprt = false;\r
+ if (phase < 20) {\r
+ var m = 3 * Math.sin(.16 * phase);\r
+ this._move(x + m * Math.sin(phase), y + m * Math.cos(phase));\r
+ this._sprt = setTimeout(this.name + ".doShake(" + id + "," + (++phase) + "," + x + "," + y + ")", 20);\r
+ } else {\r
+ this._move(x, y);\r
+ }\r
+ }\r
+}\r
+\r
+function QSprite_doClick() {\r
+ if (!this._sprt) {\r
+ this.onClick(this.tag);\r
+ }\r
+ return false;\r
+}\r
+\r
+function QSprite(parent, name, x, y, width, height, src, visible, effects, opacity, zindex) {\r
+ this.init(parent, name);\r
+ this.x = x - 0;\r
+ this.y = y - 0;\r
+ this.width = (this.cwidth = width - 0) + 8;\r
+ this.height = (this.cheight = height - 0) + 8;\r
+ var j = QSprite.arguments.length;\r
+ this.visible = (j > 7) ? visible : true;\r
+ this.effects = (j > 8) ? effects : 0;\r
+ this.opacity = (j > 9) ? opacity : 100;\r
+ this.zindex = (j > 10) ? zindex : null;\r
+ this.valid = !!src;\r
+ this.content = '<a href="#" title="" onclick="return false" onmousedown="return ' + this.name +\r
+ '.doClick()" onmouseover="window.top.status=\'\';return true" hidefocus="true" unselectable="on"><img name="' +\r
+ this.id + '" src="' + (src || '') + '" border="0" width="' + this.cwidth + '" height="' + this.cheight +\r
+ '" alt="" unselectable="on"></a>';\r
+ this.doClick = QSprite_doClick;\r
+ this.doSlide = QSprite_doSlide;\r
+ this.doShake = QSprite_doShake;\r
+ this.onClick = QControl.event;\r
+ this.create();\r
+ this.face = this._img = this.document.images[this.id] || new Image(1, 1);\r
+ this._spro = 0;\r
+ this._sprt = false;\r
+ this._show = this.show;\r
+ this._move = this.moveTo;\r
+ this.load = QSprite_load;\r
+ this.show = QSprite_show;\r
+ this.moveTo = QSprite_moveTo;\r
+ this.slideTo = QSprite_slideTo;\r
+ this.shake = QSprite_shake;\r
+ this.stop = QSprite_stop;\r
+}\r
+QSprite.prototype = new QWndCtrl();\r
--- /dev/null
+/**\r
+ * QLIB 1.0 Window Control\r
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * http://qlib.quazzle.com\r
+ */\r
+\r
+function QWindow(parent, name, x, y, width, height, content, visible, effects, opacity, zindex) {\r
+ this.init(parent, name);\r
+ this.x = x - 0;\r
+ this.y = y - 0;\r
+ this.width = width - 0;\r
+ this.height = (typeof(height) == "number") ? height : null;\r
+ this.content = content;\r
+ var j = QWindow.arguments.length;\r
+ this.visible = (j > 7) ? visible : true;\r
+ this.effects = (j > 8) ? effects : 0;\r
+ this.opacity = (j > 9) ? opacity : 100;\r
+ this.zindex = (j > 10) ? zindex : null;\r
+ this.create();\r
+}\r
+QWindow.prototype = new QWndCtrl();\r
--- /dev/null
+/**\r
+ * QLIB 1.0 Window Abstraction\r
+ * Copyright (C) 2002 2003, Quazzle.com Serge Dolgov\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * http://qlib.quazzle.com\r
+ */\r
+\r
+function QWndCtrl_center_ie4() {\r
+ var b = this.document.body;\r
+ this.moveTo(b.scrollLeft + Math.max(0, Math.floor((b.clientWidth -\r
+ this.width) / 2)), b.scrollTop + 100);\r
+}\r
+\r
+function QWndCtrl_center_moz() {\r
+ this.moveTo(self.pageXOffset + Math.max(0, Math.floor((self.innerWidth -\r
+ this.width) / 2)), self.pageYOffset + 100);\r
+}\r
+\r
+function QWndCtrl_setEffects_ie4(fx) {\r
+ this.effects = fx;\r
+ with (this.wnd) {\r
+ filters[0].enabled = (fx & 256) != 0;\r
+ filters[1].enabled = (fx & 512) != 0;\r
+ filters[2].enabled = (fx & 1024) != 0;\r
+ filters[4].enabled = (fx & 2048) != 0;\r
+ }\r
+}\r
+\r
+function QWndCtrl_setEffects_moz(fx) {\r
+ this.effects = fx;\r
+}\r
+\r
+function QWndCtrl_setOpacity_ie4(op) {\r
+ this.opacity = Math.max(0, Math.min(100, Math.floor(op - 0)));\r
+ this.wnd.filters[3].opacity = this.opacity;\r
+ this.wnd.filters[3].enabled = (this.opacity < 100);\r
+}\r
+\r
+function QWndCtrl_setOpacity_moz(op) {\r
+ this.opacity = Math.max(0, Math.min(100, Math.floor(op - 0)));\r
+ this.wnd.style.MozOpacity = this.opacity + "%";\r
+}\r
+\r
+function QWndCtrl_setSize_css(w, h) {\r
+ this.wnd.style.width = (this.width = Math.floor(w - 0)) + "px";\r
+ this.wnd.style.height = typeof(h) == "number" ? (this.height = Math.floor(h)) + "px" : "auto";\r
+}\r
+\r
+function QWndCtrl_setSize_ns4(w, h) {\r
+ this.wnd.clip.width = this.width = Math.floor(w - 0);\r
+ if (typeof(h) == "number") {\r
+ this.wnd.clip.height = this.height = Math.floor(h);\r
+ }\r
+}\r
+\r
+function QWndCtrl_focus() {\r
+ this.setZIndex(QWndCtrl.TOPZINDEX++);\r
+}\r
+\r
+function QWndCtrl_setZIndex_css(z) {\r
+ this.wnd.style.zIndex = this.zindex = z || 0;\r
+}\r
+\r
+function QWndCtrl_setZIndex_ns4(z) {\r
+ this.wnd.zIndex = this.zindex = z || 0;\r
+}\r
+\r
+function QWndCtrl_moveTo_css(x, y) {\r
+ this.wnd.style.left = (this.x = Math.floor(x - 0)) + "px";\r
+ this.wnd.style.top = (this.y = Math.floor(y - 0)) + "px";\r
+}\r
+\r
+function QWndCtrl_moveTo_ns4(x, y) {\r
+ this.wnd.moveTo(this.x = Math.floor(x - 0), this.y = Math.floor(y - 0));\r
+}\r
+\r
+function QWndCtrl_fxhandler() {\r
+ this.fxhandler = QControl.nop;\r
+ this.onShow(this.visible, this.tag);\r
+}\r
+\r
+function QWndCtrl_show_ie4(show) {\r
+ if (this.visible != show) {\r
+ var fx = false;\r
+ switch (show ? this.effects & 15 : (this.effects & 240) >>> 4) {\r
+ case 1:\r
+ fx = this.wnd.filters[5];\r
+ break;\r
+ case 2:\r
+ (fx = this.wnd.filters[6]).transition = show ? 1 : 0;\r
+ break;\r
+ case 3:\r
+ (fx = this.wnd.filters[6]).transition = show ? 3 : 2;\r
+ break;\r
+ case 4:\r
+ (fx = this.wnd.filters[6]).transition = show ? 5 : 4;\r
+ break;\r
+ case 5:\r
+ (fx = this.wnd.filters[6]).transition = show ? 14 : 13;\r
+ break;\r
+ case 6:\r
+ (fx = this.wnd.filters[6]).transition = show ? 16 : 15;\r
+ break;\r
+ case 7:\r
+ (fx = this.wnd.filters[6]).transition = 12;\r
+ break;\r
+ case 8:\r
+ (fx = this.wnd.filters[6]).transition = 8;\r
+ break;\r
+ case 9:\r
+ (fx = this.wnd.filters[6]).transition = 9;\r
+ }\r
+ if (fx) {\r
+ fx.apply();\r
+ this.wnd.style.visibility = (this.visible = show) ? "visible" : "hidden";\r
+ this.fxhandler = QWndCtrl_fxhandler;\r
+ fx.play(0.3);\r
+ } else {\r
+ this.wnd.style.visibility = (this.visible = show) ? "visible" : "hidden";\r
+ this.onShow(show, this.tag);\r
+ }\r
+ }\r
+}\r
+\r
+function QWndCtrl_fade_moz(op, step) {\r
+ this._wndt = false;\r
+ if (step) {\r
+ op += step;\r
+ if ((op > 0) && (op < this.opacity)) {\r
+ this.wnd.style.MozOpacity = op + "%";\r
+ this._wndt = setTimeout(this.name + ".fade(" + op + "," + step + ")", 50);\r
+ } else {\r
+ if (op <= 0) {\r
+ this.wnd.style.visibility = "hidden";\r
+ this.visible = false;\r
+ }\r
+ this.wnd.style.MozOpacity = this.opacity + "%";\r
+ this.onShow(this.visible, this.tag);\r
+ }\r
+ }\r
+}\r
+\r
+function QWndCtrl_show_moz(show) {\r
+ if (this.visible != show) {\r
+ if (this._wndt) {\r
+ clearTimeout(this._wndt);\r
+ this._wndt = false;\r
+ }\r
+ var step = show ? ((this.effects & 15) == 1) && Math.floor(this.opacity / 5) :\r
+ ((this.effects & 240) == 16) && -Math.floor(this.opacity / 5);\r
+ if (step) {\r
+ if (this.visible) {\r
+ this.fade(this.opacity - 0, step);\r
+ } else {\r
+ this.wnd.style.MozOpacity = "0%";\r
+ this.wnd.style.visibility = "visible";\r
+ this.visible = true;\r
+ this.fade(0, step);\r
+ }\r
+ } else {\r
+ this.wnd.style.visibility = (this.visible = show) ? "visible" : "hidden";\r
+ this.onShow(show, this.tag);\r
+ }\r
+ }\r
+}\r
+\r
+function QWndCtrl_show_css(show) {\r
+ if (this.visible != show) {\r
+ this.wnd.style.visibility = (this.visible = show) ? "visible" : "hidden";\r
+ this.onShow(show, this.tag);\r
+ }\r
+}\r
+\r
+function QWndCtrl_show_ns4(show) {\r
+ if (this.visible != show) {\r
+ this.wnd.visibility = (this.visible = show) ? "show" : "hidden";\r
+ this.onShow(show, this.tag);\r
+ }\r
+}\r
+\r
+function QWndCtrl_create_dom2() {\r
+ with (this) {\r
+ this.fxhandler = QControl.nop;\r
+ var ie4 = document.body && document.body.filters;\r
+ var moz = document.body && document.body.style &&\r
+ typeof(document.body.style.MozOpacity) == "string";\r
+ document.write('<div unselectable="on" id="' + id +\r
+ (ie4 ? '" onfilterchange="' + name + '.fxhandler()': '') +\r
+ '" style="position:absolute;left:' + x + 'px;top:' + y +\r
+ 'px;width:' + width + (height != null ? 'px;height:' + height : '') +\r
+ 'px;visibility:' + (visible ? 'visible' : 'hidden') +\r
+ ';overflow:hidden' + (zindex ? ';z-index:' + zindex : '') +\r
+ (ie4 ? ';filter:Gray(enabled=' + (effects & 256 ? '1' : '0') +\r
+ ') Xray(enabled=' + (effects & 512 ? '1' : '0') +\r
+ ') Invert(enabled=' + (effects & 1024 ? '1' : '0') +\r
+ ') alpha(enabled=' + (opacity < 100 ? '1' : '0') + ',opacity=' + opacity +\r
+ ') shadow(enabled=' + (effects & 2048 ? '1' : '0') +\r
+ ',direction=135) BlendTrans(enabled=0) RevealTrans(enabled=0)' : '') +\r
+ (moz && (opacity < 100) ? ';-moz-opacity:' + opacity + '%' : '') +\r
+ '"><div unselectable="on" class="qwindow">');\r
+ if (typeof(content) == "function") {\r
+ this.content();\r
+ } else {\r
+ document.write(content);\r
+ }\r
+ document.write('</div></div>');\r
+ if (this.wnd = document.getElementById ? document.getElementById(id) :\r
+ (document.all.item ? document.all.item(id) : document.all[id])) {\r
+ if (wnd.style) {\r
+ ie4 = ie4 && wnd.filters;\r
+ moz = moz && typeof(wnd.style.MozOpacity) == "string";\r
+ this.moveTo = QWndCtrl_moveTo_css;\r
+ this.setZIndex = QWndCtrl_setZIndex_css;\r
+ this.focus = QWndCtrl_focus;\r
+ this.setSize = QWndCtrl_setSize_css;\r
+ this.show = ie4 ? QWndCtrl_show_ie4 : (moz ? QWndCtrl_show_moz : QWndCtrl_show_css);\r
+ this.fade = moz ? QWndCtrl_fade_moz : QControl.nop;\r
+ this.setOpacity = ie4 ? QWndCtrl_setOpacity_ie4 : (moz ? QWndCtrl_setOpacity_moz : QControl.nop);\r
+ this.setEffects = ie4 ? QWndCtrl_setEffects_ie4 : (moz ? QWndCtrl_setEffects_moz : QControl.nop);\r
+ this.center = self.innerWidth ? QWndCtrl_center_moz :\r
+ (document.body && document.body.clientWidth ? QWndCtrl_center_ie4 : QControl.nop);\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+function QWndCtrl_create_ns4(finalize) {\r
+ with (this) {\r
+ if (finalize) {\r
+ if (_wnde) {\r
+ parent.window.onload = _wnde;\r
+ parent.window.onload();\r
+ }\r
+ document.open();\r
+ document.write('<div class="qwindow">');\r
+ this.content();\r
+ document.write('</div>');\r
+ document.close();\r
+ } else {\r
+ document.write('<layer id="' + id + '" left="' + x + '" top="' + y +\r
+ '" width="' + width + '" visibility="' + (visible ? 'show' : 'hidden') +\r
+ (height != null ? '" height="' + height + '" clip="' + width + ',' + height : '') +\r
+ (zindex ? '" z-index="' + zindex : '') + (typeof(content) != "function" ?\r
+ '"><div class="qwindow">' + content + '</div></layer>' : '"> </layer>'));\r
+ if (this.window = this.wnd = document.layers[id]) {\r
+ if (this.document = wnd.document) {\r
+ this.show = QWndCtrl_show_ns4;\r
+ this.moveTo = QWndCtrl_moveTo_ns4;\r
+ this.setZIndex = QWndCtrl_setZIndex_ns4;\r
+ this.focus = QWndCtrl_focus;\r
+ this.center = QWndCtrl_center_moz;\r
+ this.setSize = QWndCtrl_setSize_ns4;\r
+ if (typeof(content) == "function") {\r
+ this._wnde = parent.window.onload;\r
+ parent.window.onload = new Function(name + ".create(true)");\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+function QWndCtrl_create_na() {\r
+ this.document.write('Object is not supported.');\r
+ this.wnd = null;\r
+}\r
+\r
+function QWndCtrl_create() {\r
+ with (this) {\r
+ this.create = (document.getElementById || document.all) ? QWndCtrl_create_dom2 :\r
+ (document.layers ? QWndCtrl_create_ns4 : QWndCtrl_create_na);\r
+ create();\r
+ }\r
+}\r
+\r
+function QWndCtrl() {\r
+ this.x = this.y = 0;\r
+ this.width = this.height = 0;\r
+ this.content = "";\r
+ this.visible = true;\r
+ this.effects = 0;\r
+ this.opacity = 100;\r
+ this.zindex = null;\r
+ this._wndt = this._wnde = false;\r
+ this.create = QWndCtrl_create;\r
+ this.show = QControl.nop;\r
+ this.focus = QControl.nop;\r
+ this.center = QControl.nop;\r
+ this.moveTo = QControl.nop;\r
+ this.setSize = QControl.nop;\r
+ this.setOpacity = QControl.nop;\r
+ this.setEffects = QControl.nop;\r
+ this.setZIndex = QControl.nop;\r
+ this.onShow = QControl.event;\r
+}\r
+QWndCtrl.prototype = new QControl();\r
+QWndCtrl.TOPZINDEX = 1000;\r
+QWndCtrl.GRAY = 256;\r
+QWndCtrl.XRAY = 512;\r
+QWndCtrl.INVERT = 1024;\r
+QWndCtrl.SHADOW = 2048;\r
+QWndCtrl.FADEIN = 1;\r
+QWndCtrl.FADEOUT = 16;\r
+QWndCtrl.BOXIN = 2;\r
+QWndCtrl.BOXOUT = 32;\r
+QWndCtrl.CIRCLEIN = 3;\r
+QWndCtrl.CIRCLEOUT = 48;\r
+QWndCtrl.WIPEIN = 4;\r
+QWndCtrl.WIPEOUT = 64;\r
+QWndCtrl.HBARNIN = 5;\r
+QWndCtrl.HBARNOUT = 80;\r
+QWndCtrl.VBARNIN = 6;\r
+QWndCtrl.VBARNOUT = 96;\r
+QWndCtrl.DISSOLVEIN = 7;\r
+QWndCtrl.DISSOLVEOUT = 112;\r
+QWndCtrl.HBLINDSIN = 8;\r
+QWndCtrl.HBLINDSOUT = 128;\r
+QWndCtrl.VBLINDSIN = 9;\r
+QWndCtrl.VBLINDSOUT = 144;\r
--- /dev/null
+<%
+ my( $jobnum ) = $cgi->param('jobnum');
+ my( $url ) = $cgi->param('url');
+ my $job = '';
+ if ( $jobnum =~ /^(\d+)$/ ) {
+ $job = qsearchs('queue', { 'jobnum' => $jobnum } );
+ }
+ if ( $job && $job->status ne 'failed' ) {
+%>
+
+<HTML>
+ <HEAD>
+ <TITLE>
+ Please wait...
+ </TITLE>
+ <META HTTP-Equiv="Cache-Control" Content="no-cache">
+ <META HTTP-Equiv="Pragma" Content="no-cache">
+ <META HTTP-Equiv="Expires" Content="0">
+
+ <!-- could do more JSRS magic and avoid refreshing... but works for now -->
+ <META HTTP-Equiv="Refresh" Content="5">
+ </HEAD>
+ <BODY BGCOLOR="#e8e8e8">
+ <P ALIGN="center">Please wait...
+ <script TYPE="text/javascript" src="../elements/qlib/control.js"></script>
+ <script TYPE="text/javascript" src="../elements/qlib/imagelist.js"></script>
+ <script TYPE="text/javascript" src="../elements/qlib/progress.js"></script>
+ <P ALIGN="center">
+ <script TYPE="text/javascript">
+ // Create imagelist
+ SEGS = new QImageList(4, 23, "../images/progressbar-empty.png", "../images/progressbar-full.png");
+
+ // Create bars
+ bar1 = new QProgress(null, "bar1", SEGS, 100);
+ bar1.set(<%= $job->statustext %>);
+ // bar1.update;
+ </script>
+ <BR><%= $job->statustext %>%
+ <P ALIGN="center">(progress of job #<%= $jobnum %>)
+ </BODY>
+</HTML>
+
+<%
+ } elsif ( !$job ) { #handle job gone case : job sucessful
+ # so close popup, redirect parent window...
+ #eidiot("write success handler (jobnum $jobnum)");
+%>
+
+<HTML>
+ <HEAD>
+ <TITLE>
+ Operation successful
+ </TITLE>
+ <META HTTP-Equiv="Cache-Control" Content="no-cache">
+ <META HTTP-Equiv="Pragma" Content="no-cache">
+ <META HTTP-Equiv="Expires" Content="0">
+
+ </HEAD>
+ <BODY BGCOLOR="#e8e8e8">
+ <SCRIPT TYPE="text/javascript">
+ top.opener.window.location.href = '<%= $cgi->param('url') %>';
+ window.close();
+ </SCRIPT>
+ </BODY>
+</HTML>
+
+<%
+ } else {
+%>
+
+ <HEAD>
+ <TITLE>
+ Error
+ </TITLE>
+ <META HTTP-Equiv="Cache-Control" Content="no-cache">
+ <META HTTP-Equiv="Pragma" Content="no-cache">
+ <META HTTP-Equiv="Expires" Content="0">
+ </HEAD>
+ <BODY BGCOLOR="#e8e8e8">
+ <P ALIGN="center"><FONT COLOR="#ff0000">Error: <%= $job ? $job->statustext : $jobnum %></FONT>
+ <P ALIGN="center"><INPUT TYPE="button" onClick="top.opener.document.OneTrueForm.submit.disabled=false; window.close();" VALUE="OK">
+ </BODY>
+</HTML>
+
+<% } %>
+
+
+