summaryrefslogtreecommitdiff
path: root/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util
diff options
context:
space:
mode:
authorDerrell Lipman <derrell@samba.org>2007-01-03 20:17:37 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:36:09 -0500
commit626bb8efb0c825f332c937ffaaadc9b402079539 (patch)
tree1c95f69d157b24f64edff470143f5f55a09cfca6 /webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util
parenteeddcf8cc8eb655d7c40f1fd5f7fd422529f4f98 (diff)
downloadsamba-626bb8efb0c825f332c937ffaaadc9b402079539.tar.gz
samba-626bb8efb0c825f332c937ffaaadc9b402079539.tar.bz2
samba-626bb8efb0c825f332c937ffaaadc9b402079539.zip
r20517: re-add cleaned-up webapps
(This used to be commit 5a3d6ad0b7cf0ecf8b57b4088b19f7d4291c990b)
Diffstat (limited to 'webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util')
-rw-r--r--webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/ColorUtil.js162
-rw-r--r--webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/Compare.js86
-rw-r--r--webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/FormUtil.js109
-rw-r--r--webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/Normalization.js56
-rw-r--r--webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/Return.js74
-rw-r--r--webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/Textile.js178
-rw-r--r--webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/Validation.js172
-rw-r--r--webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/format/DateFormat.js614
-rw-r--r--webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/format/Format.js51
-rw-r--r--webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/format/NumberFormat.js216
-rw-r--r--webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/FiniteStateMachine.js1189
-rw-r--r--webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/State.js613
-rw-r--r--webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/Transition.js383
-rw-r--r--webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/example.txt210
14 files changed, 4113 insertions, 0 deletions
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/ColorUtil.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/ColorUtil.js
new file mode 100644
index 0000000000..3a8406f029
--- /dev/null
+++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/ColorUtil.js
@@ -0,0 +1,162 @@
+/* ************************************************************************
+
+ qooxdoo - the new era of web development
+
+ http://qooxdoo.org
+
+ Copyright:
+ 2004-2006 by 1&1 Internet AG, Germany, http://www.1and1.org
+
+ License:
+ LGPL 2.1: http://www.gnu.org/licenses/lgpl.html
+
+ Authors:
+ * Sebastian Werner (wpbasti)
+ * Andreas Ecker (ecker)
+
+************************************************************************ */
+
+/* ************************************************************************
+
+
+************************************************************************ */
+
+qx.OO.defineClass("qx.util.ColorUtil");
+
+qx.Class.rgb2hsb = function(vRed, vGreen, vBlue)
+{
+ var vHue, vSaturation, vBrightness;
+
+ vRed = parseFloat(vRed);
+ vGreen = parseFloat(vGreen);
+ vBlue = parseFloat(vBlue);
+
+ var cmax = (vRed > vGreen) ? vRed : vGreen;
+ if (vBlue > cmax) {
+ cmax = vBlue;
+ }
+
+ var cmin = (vRed < vGreen) ? vRed : vGreen;
+ if (vBlue < cmin) {
+ cmin = vBlue;
+ }
+
+ vBrightness = cmax / 255.0;
+
+ if (cmax != 0)
+ {
+ vSaturation = (cmax - cmin) / cmax;
+ }
+ else
+ {
+ vSaturation = 0;
+ }
+
+ if (vSaturation == 0)
+ {
+ vHue = 0;
+ }
+ else
+ {
+ var redc = (cmax - vRed) / (cmax - cmin);
+ var greenc = (cmax - vGreen) / (cmax - cmin);
+ var bluec = (cmax - vBlue) / (cmax - cmin);
+
+ if (vRed == cmax)
+ {
+ vHue = bluec - greenc;
+ }
+ else if (vGreen == cmax)
+ {
+ vHue = 2.0 + redc - bluec;
+ }
+ else
+ {
+ vHue = 4.0 + greenc - redc;
+ }
+
+ vHue = vHue / 6.0;
+ if (vHue < 0) vHue = vHue + 1.0;
+ }
+
+ return {
+ hue : Math.round(vHue * 360),
+ saturation : Math.round(vSaturation * 100),
+ brightness : Math.round(vBrightness * 100)
+ }
+}
+
+qx.Class.hsb2rgb = function(vHue, vSaturation, vBrightness)
+{
+ var i, f, p, q, t, vReturn;
+
+ vHue = parseFloat(vHue/360);
+ vSaturation = parseFloat(vSaturation/100);
+ vBrightness = parseFloat(vBrightness/100);
+
+ if(vHue >= 1.0) vHue %= 1.0;
+ if(vSaturation > 1.0) vSaturation = 1.0;
+ if(vBrightness > 1.0) vBrightness = 1.0;
+
+ var tov = Math.floor(255 * vBrightness);
+
+ var vReturn = {};
+
+ if(vSaturation == 0.0)
+ {
+ vReturn.red = vReturn.green = vReturn.blue = tov;
+ }
+ else
+ {
+ vHue *= 6.0;
+
+ i = Math.floor(vHue);
+
+ f = vHue - i;
+
+ p = Math.floor(tov * (1.0 - vSaturation));
+ q = Math.floor(tov * (1.0 - (vSaturation * f)));
+ t = Math.floor(tov * (1.0 - (vSaturation * (1.0 - f))));
+
+ switch(i)
+ {
+ case 0:
+ vReturn.red = tov;
+ vReturn.green = t;
+ vReturn.blue = p;
+ break;
+
+ case 1:
+ vReturn.red = q;
+ vReturn.green = tov;
+ vReturn.blue = p;
+ break;
+
+ case 2:
+ vReturn.red = p;
+ vReturn.green = tov;
+ vReturn.blue = t;
+ break;
+
+ case 3:
+ vReturn.red = p;
+ vReturn.green = q;
+ vReturn.blue = tov;
+ break;
+
+ case 4:
+ vReturn.red = t;
+ vReturn.green = p;
+ vReturn.blue = tov;
+ break;
+
+ case 5:
+ vReturn.red = tov;
+ vReturn.green = p;
+ vReturn.blue = q;
+ break;
+ }
+ }
+
+ return vReturn;
+}
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/Compare.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/Compare.js
new file mode 100644
index 0000000000..3de325d717
--- /dev/null
+++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/Compare.js
@@ -0,0 +1,86 @@
+/* ************************************************************************
+
+ qooxdoo - the new era of web development
+
+ http://qooxdoo.org
+
+ Copyright:
+ 2004-2006 by 1&1 Internet AG, Germany, http://www.1and1.org
+
+ License:
+ LGPL 2.1: http://www.gnu.org/licenses/lgpl.html
+
+ Authors:
+ * Sebastian Werner (wpbasti)
+ * Andreas Ecker (ecker)
+
+************************************************************************ */
+
+/* ************************************************************************
+
+
+************************************************************************ */
+
+qx.OO.defineClass("qx.util.Compare");
+
+qx.util.Compare.byString = function(a, b) {
+ return a==b ? 0 : a > b ? 1 : -1;
+}
+
+qx.util.Compare.byStringCaseInsensitive = function(a, b) {
+ return qx.util.Compare.byString(a.toLowerCase(), b.toLowerCase());
+}
+
+qx.util.Compare.byStringUmlautsShort = function(a, b) {
+ return qx.util.Compare.byString(qx.util.Normalization.umlautsShort(a), qx.util.Normalization.umlautsShort(b));
+}
+
+qx.util.Compare.byStringUmlautsShortCaseInsensitive = function(a, b) {
+ return qx.util.Compare.byString(qx.util.Normalization.umlautsShort(a).toLowerCase(), qx.util.Normalization.umlautsShort(b).toLowerCase());
+}
+
+qx.util.Compare.byStringUmlautsLong = function(a, b) {
+ return qx.util.Compare.byString(qx.util.Normalization.umlautsLong(a), qx.util.Normalization.umlautsLong(b));
+}
+
+qx.util.Compare.byStringUmlautsLongCaseInsensitive = function(a, b) {
+ return qx.util.Compare.byString(qx.util.Normalization.umlautsLong(a).toLowerCase(), qx.util.Normalization.umlautsLong(b).toLowerCase());
+}
+
+qx.util.Compare.byFloat = function(a, b) {
+ return a - b;
+}
+
+qx.util.Compare.byInteger = qx.util.Compare.byNumber = qx.util.Compare.byFloat;
+
+qx.util.Compare.byIntegerString = function(a, b) {
+ return parseInt(a) - parseInt(b);
+}
+
+qx.util.Compare.byFloatString = function(a, b) {
+ return parseFloat(a) - parseFloat(b);
+}
+
+qx.util.Compare.byNumberString = qx.util.Compare.byFloatString;
+
+qx.util.Compare.byIPv4 = function(a, b)
+{
+ var ipa = a.split(".", 4);
+ var ipb = b.split(".", 4);
+
+ for (var i=0; i<3; i++)
+ {
+ a = parseInt(ipa[i]);
+ b = parseInt(ipb[i]);
+
+ if (a != b) {
+ return a - b;
+ }
+ }
+
+ return parseInt(ipa[3]) - parseInt(ipb[3]);
+}
+
+qx.util.Compare.byZIndex = function(a, b) {
+ return a.getZIndex() - b.getZIndex();
+}
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/FormUtil.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/FormUtil.js
new file mode 100644
index 0000000000..2d4913008d
--- /dev/null
+++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/FormUtil.js
@@ -0,0 +1,109 @@
+/* ************************************************************************
+
+ qooxdoo - the new era of web development
+
+ http://qooxdoo.org
+
+ Copyright:
+ 2004-2006 by 1&1 Internet AG, Germany, http://www.1and1.org
+
+ License:
+ LGPL 2.1: http://www.gnu.org/licenses/lgpl.html
+
+ Authors:
+ * Sebastian Werner (wpbasti)
+ * Andreas Ecker (ecker)
+
+************************************************************************ */
+
+/* ************************************************************************
+
+#module(io_remote)
+
+************************************************************************ */
+
+qx.OO.defineClass("qx.util.FormUtil");
+
+qx.Class.ignoreInputTypes = [ "file", "submit", "image", "reset", "button" ];
+qx.Class.ignoreElementTypes = [ "fieldset" ];
+qx.Class.checkElementTypes = [ "radio", "checkbox" ];
+qx.Class.multiSelectType = "select-multiple";
+
+qx.Class.inputFilter = function(vNode)
+{
+ if (vNode.disabled) {
+ return false;
+ }
+
+ var vTag = (vNode.tagName || "").toLowerCase();
+
+ if (qx.lang.Array.contains(qx.util.FormUtil.ignoreElementTypes, vTag)) {
+ return false;
+ }
+
+ var vType = vNode.type.toLowerCase();
+
+ if (qx.lang.Array.contains(qx.util.FormUtil.ignoreInputTypes, vType)) {
+ return false;
+ }
+
+ if (!vNode.checked && qx.lang.Array.contains(qx.util.FormUtil.checkElementTypes, vType)) {
+ return false;
+ }
+
+ return true;
+}
+
+qx.Class.getFields = function(vForm) {
+ return Array.filter(vForm.elements, qx.util.FormUtil.inputFilter);
+}
+
+qx.Class.encodeField = function(vNode)
+{
+ var vName = vNode.name || "";
+ var vType = (vNode.type || "").toLowerCase();
+
+ if(vType === qx.util.FormUtil.multiSelectType)
+ {
+ var vValues = [];
+
+ for(var i=0; i<vNode.options.length; i++)
+ {
+ if(vNode.options[i].selected) {
+ vValues.push(vName + "=" + vNode.options[i].value);
+ }
+ }
+
+ return vValues.join("&");
+ }
+ else
+ {
+ return vName + "=" + vNode.value;
+ }
+}
+
+qx.Class.encodeForm = function(vForm)
+{
+ var vFields = qx.util.FormUtil.getFields(vForm);
+ var vAll = [];
+
+ for (var i=0, l=vFields.length; i<l; i++) {
+ vAll.push(qx.util.FormUtil.encodeField(vFields[i]));
+ }
+
+ return vAll.join("&");
+}
+
+qx.Class.bind = function(vForm, vMethod)
+{
+ qx.dom.EventRegistration.addEventListener(vForm, "submit", function(e)
+ {
+ e.returnValue = false;
+
+ if (typeof e.preventDefault === "function") {
+ e.preventDefault();
+ }
+
+ return vMethod(e);
+ });
+}
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/Normalization.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/Normalization.js
new file mode 100644
index 0000000000..1d94b5dcfc
--- /dev/null
+++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/Normalization.js
@@ -0,0 +1,56 @@
+/* ************************************************************************
+
+ qooxdoo - the new era of web development
+
+ http://qooxdoo.org
+
+ Copyright:
+ 2004-2006 by 1&1 Internet AG, Germany, http://www.1and1.org
+
+ License:
+ LGPL 2.1: http://www.gnu.org/licenses/lgpl.html
+
+ Authors:
+ * Sebastian Werner (wpbasti)
+ * Andreas Ecker (ecker)
+
+************************************************************************ */
+
+/* ************************************************************************
+
+
+************************************************************************ */
+
+qx.OO.defineClass("qx.util.Normalization");
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ HANDLING OF UMLAUTS
+---------------------------------------------------------------------------
+*/
+
+qx.util.Normalization._umlautsRegExp = /[\xE4\xF6\xFC\xDF\xC4\xD6\xDC]/g;
+
+qx.util.Normalization._umlautsShortData = { "\xC4": "A", "\xD6": "O", "\xDC": "U", "\xE4": "a", "\xF6": "o", "\xFC": "u", "\xDF": "s" }
+
+qx.util.Normalization._umlautsShort = function(vChar) {
+ return qx.util.Normalization._umlautsShortData[vChar];
+}
+
+qx.util.Normalization.umlautsShort = function(vString) {
+ return vString.replace(qx.util.Normalization._umlautsRegExp, qx.util.Normalization._umlautsShort);
+}
+
+qx.util.Normalization._umlautsLongData = { "\xC4": "Ae", "\xD6": "Oe", "\xDC": "Ue", "\xE4": "ae", "\xF6": "oe", "\xFC": "ue", "\xDF": "ss" }
+
+qx.util.Normalization._umlautsLong = function(vChar) {
+ return qx.util.Normalization._umlautsLongData[vChar];
+}
+
+qx.util.Normalization.umlautsLong = function(vString) {
+ return vString.replace(qx.util.Normalization._umlautsRegExp, qx.util.Normalization._umlautsLong);
+}
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/Return.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/Return.js
new file mode 100644
index 0000000000..2f5c7dd1e2
--- /dev/null
+++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/Return.js
@@ -0,0 +1,74 @@
+/* ************************************************************************
+
+ qooxdoo - the new era of web development
+
+ http://qooxdoo.org
+
+ Copyright:
+ 2004-2006 by 1&1 Internet AG, Germany, http://www.1and1.org
+
+ License:
+ LGPL 2.1: http://www.gnu.org/licenses/lgpl.html
+
+ Authors:
+ * Sebastian Werner (wpbasti)
+ * Andreas Ecker (ecker)
+
+************************************************************************ */
+
+/* ************************************************************************
+
+#module(core)
+
+************************************************************************ */
+
+qx.OO.defineClass("qx.util.Return");
+
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ SIMPLE RETURN METHODS
+---------------------------------------------------------------------------
+*/
+
+qx.util.Return.returnTrue = function() {
+ return true;
+};
+
+qx.util.Return.returnFalse = function() {
+ return false;
+};
+
+qx.util.Return.returnNull = function() {
+ return null;
+};
+
+qx.util.Return.returnThis = function() {
+ return this;
+};
+
+qx.util.Return.returnInstance = function()
+{
+ if (!this._instance)
+ {
+ this._instance = new this;
+
+ /*
+ if (this._instance.debug) {
+ this._instance.debug("Created...");
+ }*/
+ }
+
+ return this._instance;
+};
+
+qx.util.Return.returnZero = function() {
+ return 0;
+};
+
+qx.util.Return.returnNegativeIndex = function() {
+ return -1;
+};
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/Textile.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/Textile.js
new file mode 100644
index 0000000000..1bf42982c9
--- /dev/null
+++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/Textile.js
@@ -0,0 +1,178 @@
+/* ************************************************************************
+
+ qooxdoo - the new era of web development
+
+ http://qooxdoo.org
+
+ Copyright:
+ 2004-2006 by 1&1 Internet AG, Germany, http://www.1and1.org
+
+ License:
+ LGPL 2.1: http://www.gnu.org/licenses/lgpl.html
+
+ Authors:
+ * Sebastian Werner (wpbasti)
+ * Andreas Ecker (ecker)
+
+************************************************************************ */
+
+/* ************************************************************************
+
+
+************************************************************************ */
+
+/**
+ * Optimized version of SuperTextile
+ */
+qx.OO.defineClass("qx.util.Textile");
+
+/**
+ * ATTENTION: Deprecated module. Will be removed with qooxdoo 0.7.
+ *
+ * Textilizes a string
+ * http://www.creatimation.net/journal/textile-live-preview (offline)
+ *
+ * @param s {string} Text to be textilized.
+ * @return {string} The textilized text.
+ */
+qx.util.Textile.textilize = function(s)
+{
+ var r = s;
+
+ // quick tags first
+ var qtags = [
+ ["\\*", "strong"],
+ ["\\?\\?", "cite"],
+ ["\\+", "ins"],
+ ["~", "sub"],
+ ["\\^", "sup"],
+ ["@", "code"]
+ ];
+
+ var ttag, htag, re, line, lines, nr, changed, inlist, listtype;
+
+ for (var i=0;i<qtags.length;i++) {
+ ttag = qtags[i][0]; htag = qtags[i][1];
+ re = new RegExp(ttag+"\\b(.+?)\\b"+ttag,"g");
+ r = r.replace(re,"<"+htag+">"+"$1"+"</"+htag+">");
+ }
+
+ // underscores count as part of a word, so do them separately
+ re = new RegExp("\\b_(.+?)_\\b","g");
+ r = r.replace(re,"<em>$1</em>");
+
+ // jeff: so do dashes
+ re = new RegExp("[\s\n]-(.+?)-[\s\n]","g");
+ r = r.replace(re,"<del>$1</del>");
+
+ // links
+ re = new RegExp('"\\b(.+?)\\(\\b(.+?)\\b\\)":([^\\s]+)','g');
+ r = r.replace(re,'<a href="$3" title="$2">$1</a>');
+ re = new RegExp('"\\b(.+?)\\b":([^\\s]+)','g');
+ r = r.replace(re,'<a href="$2">$1</a>');
+
+ // images
+ re = new RegExp("!\\b(.+?)\\(\\b(.+?)\\b\\)!","g");
+ r = r.replace(re,'<img src="$1" alt="$2">');
+ re = new RegExp("!\\b(.+?)\\b!","g");
+ r = r.replace(re,'<img src="$1">');
+
+ // block level formatting
+
+ // Jeff's hack to show single line breaks as they should.
+ // insert breaks - but you get some....stupid ones
+ re = new RegExp("(.*)\n([^#\*\n].*)","g");
+ r = r.replace(re,"$1<br />$2");
+
+ // remove the stupid breaks.
+ re = new RegExp("\n<br />","g");
+ r = r.replace(re,"\n");
+
+ lines = r.split("\n");
+ nr = "";
+
+ for (var i=0;i<lines.length;i++)
+ {
+ line = lines[i].replace(/\s*$/,"");
+ changed = 0;
+
+ if (line.search(/^\s*bq\.\s+/) != -1)
+ {
+ line = line.replace(/^\s*bq\.\s+/,"\t<blockquote>")+"</blockquote>";
+ changed = 1;
+ }
+
+ // jeff adds h#.
+ if (line.search(/^\s*h[1-6]\.\s+/) != -1)
+ {
+ re = new RegExp("h([1-6])\.(.+)","g");
+ line = line.replace(re,"<h$1>$2</h$1>");
+ changed = 1;
+ }
+
+ if (line.search(/^\s*\*\s+/) != -1)
+ {
+ // for bullet list; make up an liu tag to be fixed later
+ line = line.replace(/^\s*\*\s+/,"\t<liu>") + "</liu>";
+ changed = 1;
+ }
+
+ if (line.search(/^\s*#\s+/) != -1)
+ {
+ // # for numeric list; make up an lio tag to be fixed later
+ line = line.replace(/^\s*#\s+/,"\t<lio>") + "</lio>";
+ changed = 1;
+ }
+
+ if (!changed && (line.replace(/\s/g,"").length > 0))
+ {
+ line = "<p>"+line+"</p>";
+ }
+
+ lines[i] = line + "\n";
+ }
+
+ // Second pass to do lists
+ inlist = 0;
+ listtype = "";
+
+ for (var i=0;i<lines.length;i++)
+ {
+ line = lines[i];
+
+ if (inlist && listtype == "ul" && !line.match(/^\t<liu/))
+ {
+ line = "</ul>\n" + line;
+ inlist = 0;
+ }
+
+ if (inlist && listtype == "ol" && !line.match(/^\t<lio/))
+ {
+ line = "</ol>\n" + line;
+ inlist = 0;
+ }
+
+ if (!inlist && line.match(/^\t<liu/))
+ {
+ line = "<ul>" + line;
+ inlist = 1;
+ listtype = "ul";
+ }
+
+ if (!inlist && line.match(/^\t<lio/))
+ {
+ line = "<ol>" + line;
+ inlist = 1;
+ listtype = "ol";
+ }
+
+ lines[i] = line;
+ }
+
+ r = lines.join("\n");
+
+ // jeff added : will correctly replace <li(o|u)> AND </li(o|u)>
+ r = r.replace(/li[o|u]>/g, "li>");
+
+ return r;
+} \ No newline at end of file
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/Validation.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/Validation.js
new file mode 100644
index 0000000000..1fadd1d686
--- /dev/null
+++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/Validation.js
@@ -0,0 +1,172 @@
+/* ************************************************************************
+
+ qooxdoo - the new era of web development
+
+ http://qooxdoo.org
+
+ Copyright:
+ 2004-2006 by 1&1 Internet AG, Germany, http://www.1and1.org
+
+ License:
+ LGPL 2.1: http://www.gnu.org/licenses/lgpl.html
+
+ Authors:
+ * Sebastian Werner (wpbasti)
+ * Andreas Ecker (ecker)
+
+************************************************************************ */
+
+/* ************************************************************************
+
+#module(core)
+
+************************************************************************ */
+
+qx.OO.defineClass("qx.util.Validation");
+
+/*
+ All methods use the strict comparison operators as all modern
+ browsers (needs support for JavaScript 1.3) seems to support this.
+
+ http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Operators:Comparison_Operators
+*/
+
+qx.util.Validation.isValid = function(v)
+{
+ switch(typeof v)
+ {
+ case "undefined":
+ return false;
+
+ case "object":
+ return v !== null;
+
+ case "string":
+ return v !== "";
+
+ case "number":
+ return !isNaN(v);
+
+ case "function":
+ case "boolean":
+ return true;
+ }
+
+ return false;
+}
+
+qx.util.Validation.isInvalid = function(v)
+{
+ switch(typeof v)
+ {
+ case "undefined":
+ return true;
+
+ case "object":
+ return v === null;
+
+ case "string":
+ return v === "";
+
+ case "number":
+ return isNaN(v);
+
+ case "function":
+ case "boolean":
+ return false;
+ }
+
+ return true;
+}
+
+qx.util.Validation.isValidNumber = function(v) {
+ return typeof v === "number" && !isNaN(v);
+}
+
+qx.util.Validation.isInvalidNumber = function(v) {
+ return typeof v !== "number" || isNaN(v);
+}
+
+qx.util.Validation.isValidString = function(v) {
+ return typeof v === "string" && v !== "";
+}
+
+qx.util.Validation.isInvalidString = function(v) {
+ return typeof v !== "string" || v === "";
+}
+
+qx.util.Validation.isValidArray = function(v) {
+ return typeof v === "object" && v !== null && v instanceof Array;
+}
+
+qx.util.Validation.isInvalidArray = function(v) {
+ return typeof v !== "object" || v === null || !(v instanceof Array);
+}
+
+qx.util.Validation.isValidObject = function(v) {
+ return typeof v === "object" && v !== null && !(v instanceof Array);
+}
+
+qx.util.Validation.isInvalidObject = function(v) {
+ return typeof v !== "object" || v === null || v instanceof Array;
+}
+
+qx.util.Validation.isValidNode = function(v) {
+ return typeof v === "object" && v !== null;
+}
+
+qx.util.Validation.isInvalidNode = function(v) {
+ return typeof v !== "object" || v === null;
+}
+
+qx.util.Validation.isValidElement = function(v) {
+ return typeof v === "object" && v !== null || v.nodeType !== 1;
+}
+
+qx.util.Validation.isInvalidElement = function(v) {
+ return typeof v !== "object" || v === null || v.nodeType !== 1;
+}
+
+qx.util.Validation.isValidFunction = function(v) {
+ return typeof v === "function";
+}
+
+qx.util.Validation.isInvalidFunction = function(v) {
+ return typeof v !== "function";
+}
+
+qx.util.Validation.isValidBoolean = function(v) {
+ return typeof v === "boolean";
+}
+
+qx.util.Validation.isInvalidBoolean = function(v) {
+ return typeof v !== "boolean";
+}
+
+qx.util.Validation.isValidStringOrNumber = function(v)
+{
+ switch(typeof v)
+ {
+ case "string":
+ return v !== "";
+
+ case "number":
+ return !isNaN(v);
+ }
+
+ return false;
+}
+
+qx.util.Validation.isInvalidStringOrNumber = function(v)
+{
+ switch(typeof v)
+ {
+ case "string":
+ return v === "";
+
+ case "number":
+ return isNaN(v);
+ }
+
+ return false;
+}
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/format/DateFormat.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/format/DateFormat.js
new file mode 100644
index 0000000000..7460ea4467
--- /dev/null
+++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/format/DateFormat.js
@@ -0,0 +1,614 @@
+/* ************************************************************************
+
+ qooxdoo - the new era of web development
+
+ http://qooxdoo.org
+
+ Copyright:
+ 2006 by STZ-IDA, Germany, http://www.stz-ida.de
+
+ License:
+ LGPL 2.1: http://www.gnu.org/licenses/lgpl.html
+
+ Authors:
+ * Til Schneider (til132)
+
+************************************************************************ */
+
+/* ************************************************************************
+
+
+************************************************************************ */
+
+/**
+ * A formatter and parser for dates
+ *
+ * @param format {string} The format to use. If null, the
+ * {@link #DEFAULT_DATE_TIME_FORMAT} is used.
+ */
+qx.OO.defineClass("qx.util.format.DateFormat", qx.util.format.Format,
+function(format) {
+ qx.util.format.Format.call(this);
+
+ this._format = (format != null) ? format : qx.util.format.DateFormat.DEFAULT_DATE_TIME_FORMAT;
+});
+
+
+/**
+ * Fills a number with leading zeros ("25" -> "0025").
+ *
+ * @param number {int} the number to fill.
+ * @param minSize {int} the minimum size the returned string should have.
+ * @return {string} the filled number as string.
+ */
+qx.Proto._fillNumber = function(number, minSize) {
+ var str = "" + number;
+ while (str.length < minSize) {
+ str = "0" + str;
+ }
+ return str;
+}
+
+
+/**
+ * Returns the day in year of a date.
+ *
+ * @param date {Date} the date.
+ * @return {int} the day in year.
+ */
+qx.Proto._getDayInYear = function(date) {
+ var helpDate = new Date(date.getTime());
+ var day = helpDate.getDate();
+ while (helpDate.getMonth() != 0) {
+ // Set the date to the last day of the previous month
+ helpDate.setDate(-1);
+ day += helpDate.getDate() + 1;
+ }
+ return day;
+}
+
+
+/**
+ * Returns the thursday in the same week as the date.
+ *
+ * @param date {Date} the date to get the thursday of.
+ * @return {Date} the thursday in the same week as the date.
+ */
+qx.Proto._thursdayOfSameWeek = function(date) {
+ return new Date(date.getTime() + (3 - ((date.getDay() + 6) % 7)) * 86400000);
+}
+
+
+/**
+ * Returns the week in year of a date.
+ *
+ * @param date {Date} the date to get the week in year of.
+ * @return {int} the week in year.
+ */
+qx.Proto._getWeekInYear = function(date) {
+ // This algorithm gets the correct calendar week after ISO 8601.
+ // This standard is used in almost all european countries.
+ // TODO: In the US week in year is calculated different!
+ // See http://www.merlyn.demon.co.uk/weekinfo.htm
+
+ // The following algorithm comes from http://www.salesianer.de/util/kalwoch.html
+
+ // Get the thursday of the week the date belongs to
+ var thursdayDate = this._thursdayOfSameWeek(date);
+ // Get the year the thursday (and therefor the week) belongs to
+ var weekYear = thursdayDate.getFullYear();
+ // Get the thursday of the week january 4th belongs to
+ // (which defines week 1 of a year)
+ var thursdayWeek1 = this._thursdayOfSameWeek(new Date(weekYear, 0, 4));
+ // Calculate the calendar week
+ return Math.floor(1.5 + (thursdayDate.getTime() - thursdayWeek1.getTime()) / 86400000 / 7)
+}
+
+
+/**
+ * Formats a date.
+ * <p>
+ * Uses the same syntax as
+ * <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/text/SimpleDateFormat.html" target="_blank">
+ * the SimpleDateFormat class in Java</a>.
+ *
+ * @param date {Date} The date to format.
+ * @return {string} the formatted date.
+ */
+qx.Proto.format = function(date) {
+ var DateFormat = qx.util.format.DateFormat;
+
+ var fullYear = date.getFullYear();
+ var month = date.getMonth();
+ var dayOfMonth = date.getDate();
+ var dayOfWeek = date.getDay();
+ var hours = date.getHours();
+ var minutes = date.getMinutes();
+ var seconds = date.getSeconds();
+ var ms = date.getMilliseconds();
+ var timezone = date.getTimezoneOffset() / 60;
+
+ // Create the output
+ this._initFormatTree();
+ var output = "";
+ for (var i = 0; i < this._formatTree.length; i++) {
+ var currAtom = this._formatTree[i];
+
+ if (currAtom.type == "literal") {
+ output += currAtom.text;
+ } else {
+ // This is a wildcard
+ var wildcardChar = currAtom.character;
+ var wildcardSize = currAtom.size;
+
+ // Get its replacement
+ var replacement = "?";
+ switch (wildcardChar) {
+ // TODO: G - Era designator (e.g. AD). Problem: Not covered by JScript Date class
+ // TODO: W - Week in month (e.g. 2)
+ // TODO: F - Day of week in month (e.g. 2). Problem: What is this?
+
+ case 'y': // Year
+ if (wildcardSize == 2) {
+ replacement = this._fillNumber(fullYear % 100, 2);
+ } else if (wildcardSize == 4) {
+ replacement = fullYear;
+ }
+ break;
+ case 'D': // Day in year (e.g. 189)
+ replacement = this._fillNumber(this._getDayInYear(date), wildcardSize); break;
+ case 'd': // Day in month
+ replacement = this._fillNumber(dayOfMonth, wildcardSize); break;
+ case 'w': // Week in year (e.g. 27)
+ replacement = this._fillNumber(this._getWeekInYear(date), wildcardSize); break;
+ case 'E': // Day in week
+ if (wildcardSize == 2) {
+ replacement = DateFormat.SHORT_DAY_OF_WEEK_NAMES[dayOfWeek];
+ } else if (wildcardSize == 3) {
+ replacement = DateFormat.MEDIUM_DAY_OF_WEEK_NAMES[dayOfWeek];
+ } else if (wildcardSize == 4) {
+ replacement = DateFormat.FULL_DAY_OF_WEEK_NAMES[dayOfWeek];
+ }
+ break;
+ case 'M': // Month
+ if (wildcardSize == 1 || wildcardSize == 2) {
+ replacement = this._fillNumber(month + 1, wildcardSize);
+ } else if (wildcardSize == 3) {
+ replacement = DateFormat.SHORT_MONTH_NAMES[month];
+ } else if (wildcardSize == 4) {
+ replacement = DateFormat.FULL_MONTH_NAMES[month];
+ }
+ break;
+ case 'a': // am/pm marker
+ // NOTE: 0:00 is am, 12:00 is pm
+ replacement = (hours < 12) ? DateFormat.AM_MARKER : DateFormat.PM_MARKER; break;
+ case 'H': // Hour in day (0-23)
+ replacement = this._fillNumber(hours, wildcardSize); break;
+ case 'k': // Hour in day (1-24)
+ replacement = this._fillNumber((hours == 0) ? 24 : hours, wildcardSize); break;
+ case 'K': // Hour in am/pm (0-11)
+ replacement = this._fillNumber(hours % 12, wildcardSize); break;
+ case 'h': // Hour in am/pm (1-12)
+ replacement = this._fillNumber(((hours % 12) == 0) ? 12 : (hours % 12), wildcardSize); break;
+ case 'm': // Minute in hour
+ replacement = this._fillNumber(minutes, wildcardSize); break;
+ case 's': // Second in minute
+ replacement = this._fillNumber(seconds, wildcardSize); break;
+ case 'S': // Millisecond
+ replacement = this._fillNumber(ms, wildcardSize); break;
+ case 'z': // Time zone
+ if (wildcardSize == 1) {
+ replacement = "GMT" + ((timezone < 0) ? "-" : "+") + this._fillNumber(timezone) + ":00";
+ } else if (wildcardSize == 2) {
+ replacement = DateFormat.MEDIUM_TIMEZONE_NAMES[timezone];
+ } else if (wildcardSize == 3) {
+ replacement = DateFormat.FULL_TIMEZONE_NAMES[timezone];
+ }
+ break;
+ case 'Z': // RFC 822 time zone
+ replacement = ((timezone < 0) ? "-" : "+") + this._fillNumber(timezone, 2) + "00";
+ }
+ output += replacement;
+ }
+ }
+
+ return output;
+}
+
+
+/**
+ * Parses a date.
+ * <p>
+ * Uses the same syntax as
+ * <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/text/SimpleDateFormat.html" target="_blank">
+ * the SimpleDateFormat class in Java</a>.
+ *
+ * @param dateStr {string} the date to parse.
+ * @return {Date} the parsed date.
+ * @throws If the format is not well formed or if the date string does not
+ * match to the format.
+ */
+qx.Proto.parse = function(dateStr) {
+ this._initParseFeed();
+
+ // Apply the regex
+ var hit = this._parseFeed.regex.exec(dateStr);
+ if (hit == null) {
+ throw new Error("Date string '" + dateStr + "' does not match the date format: " + this._format);
+ }
+
+ // Apply the rules
+ var dateValues = { year:1970, month:0, day:1, hour:0, ispm:false, min:0, sec:0, ms:0 }
+ var currGroup = 1;
+ for (var i = 0; i < this._parseFeed.usedRules.length; i++) {
+ var rule = this._parseFeed.usedRules[i];
+
+ var value = hit[currGroup];
+ if (rule.field != null) {
+ dateValues[rule.field] = parseInt(value, 10);
+ } else {
+ rule.manipulator(dateValues, value);
+ }
+
+ currGroup += (rule.groups == null) ? 1 : rule.groups;
+ }
+
+ var date = new Date(dateValues.year, dateValues.month, dateValues.day,
+ (dateValues.ispm) ? (dateValues.hour + 12) : dateValues.hour,
+ dateValues.min, dateValues.sec, dateValues.ms);
+ if (dateValues.month != date.getMonth() || dateValues.year != date.getFullYear()) {
+ // TODO: check if this is also necessary for the time components
+ throw new Error("Error parsing date '" + dateStr + "': the value for day or month is too large");
+ }
+
+ return date;
+}
+
+
+
+/**
+ * Helper method for {@link #format()} and {@link #parse()}.
+ * Parses the date format.
+ */
+qx.Proto._initFormatTree = function() {
+ if (this._formatTree != null) {
+ return;
+ }
+
+ this._formatTree = [];
+
+ var currWildcardChar;
+ var currWildcardSize;
+ var currLiteral = "";
+ var format = this._format;
+ for (var i = 0; i < format.length; i++) {
+ var currChar = format.charAt(i);
+
+ // Check whether we are currently in a wildcard
+ if (currWildcardChar != null) {
+ // Check whether the currChar belongs to that wildcard
+ if (currChar == currWildcardChar) {
+ // It does -> Raise the size
+ currWildcardSize++;
+ } else {
+ // It does not -> The current wildcard is done
+ this._formatTree.push({ type:"wildcard", character:currWildcardChar, size:currWildcardSize });
+ currWildcardChar = null;
+ }
+ }
+
+ if (currWildcardChar == null) {
+ // We are not (any more) in a wildcard -> Check what's starting here
+ if ((currChar >= 'a' && currChar <= 'z') || (currChar >= 'A' && currChar <= 'Z')) {
+ // This is a letter -> All letters are wildcards
+
+ // Add the literal
+ if (currLiteral.length > 0) {
+ this._formatTree.push({ type:"literal", text:currLiteral });
+ currLiteral = "";
+ }
+
+ // Start a new wildcard
+ currWildcardChar = currChar;
+ currWildcardSize = 1;
+ } else {
+ // This is a literal -> Add it to the current literal
+ currLiteral += currChar;
+ }
+ }
+ }
+
+ // Add the last wildcard or literal
+ if (currWildcardChar != null) {
+ this._formatTree.push({ type:"wildcard", character:currWildcardChar, size:currWildcardSize });
+ } else if (currLiteral.length > 0) {
+ this._formatTree.push({ type:"literal", text:currLiteral });
+ }
+}
+
+
+/**
+ * Initializes the parse feed.
+ * <p>
+ * The parse contains everything needed for parsing: The regular expression
+ * (in compiled and uncompiled form) and the used rules.
+ *
+ * @return {Map} the parse feed.
+ */
+qx.Proto._initParseFeed = function() {
+ if (this._parseFeed != null) {
+ // We already have the farse feed
+ return;
+ }
+
+ var DateFormat = qx.util.format.DateFormat;
+
+ // Initialize the rules
+ this._initParseRules();
+ this._initFormatTree();
+
+ // Get the used rules and construct the regex pattern
+ var usedRules = [];
+ var pattern = "^";
+ for (var atomIdx = 0; atomIdx < this._formatTree.length; atomIdx++) {
+ var currAtom = this._formatTree[atomIdx];
+
+ if (currAtom.type == "literal") {
+ pattern += qx.lang.String.escapeRegexpChars(currAtom.text);
+ } else {
+ // This is a wildcard
+ var wildcardChar = currAtom.character;
+ var wildcardSize = currAtom.size;
+
+ // Get the rule for this wildcard
+ var wildcardRule;
+ for (var ruleIdx = 0; ruleIdx < DateFormat._parseRules.length; ruleIdx++) {
+ var rule = DateFormat._parseRules[ruleIdx];
+ if (wildcardChar == rule.pattern.charAt(0) && wildcardSize == rule.pattern.length) {
+ // We found the right rule for the wildcard
+ wildcardRule = rule;
+ break;
+ }
+ }
+
+ // Check the rule
+ if (wildcardRule == null) {
+ // We have no rule for that wildcard -> Malformed date format
+ var wildcardStr = "";
+ for (var i = 0; i < wildcardSize; i++) {
+ wildcardStr += wildcardChar;
+ }
+ throw new Error("Malformed date format: " + format + ". Wildcard "
+ + wildcardStr + " is not supported");
+ } else {
+ // Add the rule to the pattern
+ usedRules.push(wildcardRule);
+ pattern += wildcardRule.regex;
+ }
+ }
+ }
+ pattern += "$";
+
+ // Create the regex
+ var regex;
+ try {
+ regex = new RegExp(pattern);
+ }
+ catch (exc) {
+ throw new Error("Malformed date format: " + format);
+ }
+
+ // Create the this._parseFeed
+ this._parseFeed = { regex:regex, "usedRules":usedRules, pattern:pattern }
+}
+
+
+/**
+ * Initializes the static parse rules.
+ */
+qx.Proto._initParseRules = function() {
+ var DateFormat = qx.util.format.DateFormat;
+
+ if (DateFormat._parseRules != null) {
+ // The parse rules are already initialized
+ return;
+ }
+
+ DateFormat._parseRules = [];
+
+ var yearManipulator = function(dateValues, value) {
+ value = parseInt(value, 10);
+ if (value < DateFormat.ASSUME_YEAR_2000_THRESHOLD) {
+ value += 2000;
+ } else if (value < 100) {
+ value += 1900;
+ }
+
+ dateValues.year = value;
+ }
+
+ var monthManipulator = function(dateValues, value) {
+ dateValues.month = parseInt(value, 10) - 1;
+ }
+
+ var ampmManipulator = function(dateValues, value) {
+ dateValues.ispm = (value == DateFormat.PM_MARKER);
+ }
+
+ var noZeroHourManipulator = function(dateValues, value) {
+ dateValues.hour = parseInt(value, 10) % 24;
+ }
+
+ var noZeroAmPmHourManipulator = function(dateValues, value) {
+ dateValues.hour = parseInt(value, 10) % 12;
+ }
+
+ // Unsupported: w (Week in year), W (Week in month), D (Day in year),
+ // F (Day of week in month), z (time zone) reason: no setter in Date class,
+ // Z (RFC 822 time zone) reason: no setter in Date class
+
+ DateFormat._parseRules.push({ pattern:"yyyy", regex:"(\\d\\d(\\d\\d)?)",
+ groups:2, manipulator:yearManipulator } );
+ DateFormat._parseRules.push({ pattern:"yy", regex:"(\\d\\d)", manipulator:yearManipulator } );
+ // TODO: "MMMM", "MMM" (Month names)
+ DateFormat._parseRules.push({ pattern:"MM", regex:"(\\d\\d?)", manipulator:monthManipulator });
+ DateFormat._parseRules.push({ pattern:"dd", regex:"(\\d\\d?)", field:"day" });
+ DateFormat._parseRules.push({ pattern:"d", regex:"(\\d\\d?)", field:"day" });
+ // TODO: "EEEE", "EEE", "EE" (Day in week names)
+ DateFormat._parseRules.push({ pattern:"a",
+ regex:"(" + DateFormat.AM_MARKER + "|" + DateFormat.PM_MARKER + ")",
+ manipulator:ampmManipulator });
+ DateFormat._parseRules.push({ pattern:"HH", regex:"(\\d\\d?)", field:"hour" });
+ DateFormat._parseRules.push({ pattern:"H", regex:"(\\d\\d?)", field:"hour" });
+ DateFormat._parseRules.push({ pattern:"kk", regex:"(\\d\\d?)", manipulator:noZeroHourManipulator });
+ DateFormat._parseRules.push({ pattern:"k", regex:"(\\d\\d?)", manipulator:noZeroHourManipulator });
+ DateFormat._parseRules.push({ pattern:"KK", regex:"(\\d\\d?)", field:"hour" });
+ DateFormat._parseRules.push({ pattern:"K", regex:"(\\d\\d?)", field:"hour" });
+ DateFormat._parseRules.push({ pattern:"hh", regex:"(\\d\\d?)", manipulator:noZeroAmPmHourManipulator });
+ DateFormat._parseRules.push({ pattern:"h", regex:"(\\d\\d?)", manipulator:noZeroAmPmHourManipulator });
+ DateFormat._parseRules.push({ pattern:"mm", regex:"(\\d\\d?)", field:"min" });
+ DateFormat._parseRules.push({ pattern:"m", regex:"(\\d\\d?)", field:"min" });
+ DateFormat._parseRules.push({ pattern:"ss", regex:"(\\d\\d?)", field:"sec" });
+ DateFormat._parseRules.push({ pattern:"s", regex:"(\\d\\d?)", field:"sec" });
+ DateFormat._parseRules.push({ pattern:"SSS", regex:"(\\d\\d?\\d?)", field:"ms" });
+ DateFormat._parseRules.push({ pattern:"SS", regex:"(\\d\\d?\\d?)", field:"ms" });
+ DateFormat._parseRules.push({ pattern:"S", regex:"(\\d\\d?\\d?)", field:"ms" });
+}
+
+
+/**
+ * Returns a <code>DateFomat</code> instance that uses the
+ * {@link #DEFAULT_DATE_TIME_FORMAT}.
+ *
+ * @return {string} the date/time instance.
+ */
+qx.Class.getDateTimeInstance = function() {
+ var DateFormat = qx.util.format.DateFormat;
+
+ if (DateFormat._dateTimeInstance == null) {
+ DateFormat._dateTimeInstance = new DateFormat();
+ }
+ return DateFormat._dateTimeInstance;
+}
+
+
+/**
+ * Returns a <code>DateFomat</code> instance that uses the
+ * {@link #DEFAULT_DATE_FORMAT}.
+ *
+ * @return {string} the date instance.
+ */
+qx.Class.getDateInstance = function() {
+ var DateFormat = qx.util.format.DateFormat;
+
+ if (DateFormat._dateInstance == null) {
+ DateFormat._dateInstance = new DateFormat(DateFormat.DEFAULT_DATE_FORMAT);
+ }
+ return DateFormat._dateInstance;
+}
+
+
+/**
+ * (int) The threshold until when a year should be assumed to belong to the
+ * 21st century (e.g. 12 -> 2012). Years over this threshold but below 100 will be
+ * assumed to belong to the 20th century (e.g. 88 -> 1988). Years over 100 will be
+ * used unchanged (e.g. 1792 -> 1792).
+ */
+qx.Class.ASSUME_YEAR_2000_THRESHOLD = 30;
+
+/** {string} The short date format. */
+qx.Class.SHORT_DATE_FORMAT = "MM/dd/yyyy";
+
+/** {string} The medium date format. */
+qx.Class.MEDIUM_DATE_FORMAT = "MMM dd, yyyy";
+
+/** {string} The long date format. */
+qx.Class.LONG_DATE_FORMAT = "MMMM dd, yyyy";
+
+/** {string} The full date format. */
+qx.Class.FULL_DATE_FORMAT = "EEEE, MMMM dd, yyyy";
+
+/** {string} The short time format. */
+qx.Class.SHORT_TIME_FORMAT = "HH:mm";
+
+/** {string} The medium time format. */
+qx.Class.MEDIUM_TIME_FORMAT = qx.util.format.DateFormat.SHORT_TIME_FORMAT;
+
+/** {string} The long time format. */
+qx.Class.LONG_TIME_FORMAT = "HH:mm:ss";
+
+/** {string} The full time format. */
+qx.Class.FULL_TIME_FORMAT = "HH:mm:ss zz";
+
+/** {string} The short date-time format. */
+qx.Class.SHORT_DATE_TIME_FORMAT
+ = qx.util.format.DateFormat.SHORT_DATE_FORMAT + " "
+ + qx.util.format.DateFormat.SHORT_TIME_FORMAT;
+
+/** {string} The medium date-time format. */
+qx.Class.MEDIUM_DATE_TIME_FORMAT
+ = qx.util.format.DateFormat.MEDIUM_DATE_FORMAT + " "
+ + qx.util.format.DateFormat.MEDIUM_TIME_FORMAT;
+
+/** {string} The long date-time format. */
+qx.Class.LONG_DATE_TIME_FORMAT
+ = qx.util.format.DateFormat.LONG_DATE_FORMAT + " "
+ + qx.util.format.DateFormat.LONG_TIME_FORMAT;
+
+/** {string} The full date-time format. */
+qx.Class.FULL_DATE_TIME_FORMAT
+ = qx.util.format.DateFormat.FULL_DATE_FORMAT + " "
+ + qx.util.format.DateFormat.FULL_TIME_FORMAT;
+
+
+/** {string} The date format used for logging. */
+qx.Class.LOGGING_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
+
+/** {string} The default date/time format. */
+qx.Class.DEFAULT_DATE_TIME_FORMAT = qx.util.format.DateFormat.LOGGING_DATE_TIME_FORMAT;
+
+/** {string} The default date format. */
+qx.Class.DEFAULT_DATE_FORMAT = qx.util.format.DateFormat.SHORT_DATE_FORMAT;
+
+/** {string} The am marker. */
+qx.Class.AM_MARKER = "am";
+
+/** {string} The pm marker. */
+qx.Class.PM_MARKER = "pm";
+
+/** {string[]} The full month names. */
+qx.Class.FULL_MONTH_NAMES = [
+ "January", "February", "March", "April", "May", "June",
+ "July", "August", "September", "October", "November", "December"
+];
+
+/** {string[]} The short month names. */
+qx.Class.SHORT_MONTH_NAMES = [
+ "Jan", "Feb", "Mar", "Apr", "Mai", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+];
+
+/** {string[]} The short (two letter) day of week names. */
+qx.Class.SHORT_DAY_OF_WEEK_NAMES = [
+ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"
+];
+
+/** {string[]} The medium (three letter) day of week names. */
+qx.Class.MEDIUM_DAY_OF_WEEK_NAMES = [
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+];
+
+/** {string[]} The full day of week names. */
+qx.Class.FULL_DAY_OF_WEEK_NAMES = [
+ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
+];
+
+/** {string[]} The medium (three letter) timezone names. */
+qx.Class.MEDIUM_TIMEZONE_NAMES = [
+ "GMT" // TODO: fill up
+];
+
+/** {string[]} The full timezone names. */
+qx.Class.FULL_TIMEZONE_NAMES = [
+ "Greenwich Mean Time" // TODO: fill up
+];
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/format/Format.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/format/Format.js
new file mode 100644
index 0000000000..463d2b3595
--- /dev/null
+++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/format/Format.js
@@ -0,0 +1,51 @@
+/* ************************************************************************
+
+ qooxdoo - the new era of web development
+
+ http://qooxdoo.org
+
+ Copyright:
+ 2006 by STZ-IDA, Germany, http://www.stz-ida.de
+
+ License:
+ LGPL 2.1: http://www.gnu.org/licenses/lgpl.html
+
+ Authors:
+ * Til Schneider (til132)
+
+************************************************************************ */
+
+/* ************************************************************************
+
+
+************************************************************************ */
+
+/**
+ * Superclass for formatters and parsers.
+ */
+qx.OO.defineClass("qx.util.format.Format", qx.core.Object,
+function() {
+ qx.core.Object.call(this);
+});
+
+
+/**
+ * Formats an object.
+ *
+ * @param obj {var} The object to format.
+ * @return {string} the formatted object.
+ */
+qx.Proto.format = function(obj) {
+ throw new Error("format is abstract");
+}
+
+
+/**
+ * Parses an object.
+ *
+ * @param str {string} the string to parse.
+ * @return {var} the parsed object.
+ */
+qx.Proto.parse = function(str) {
+ throw new Error("parse is abstract");
+}
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/format/NumberFormat.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/format/NumberFormat.js
new file mode 100644
index 0000000000..2b3f2c954a
--- /dev/null
+++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/format/NumberFormat.js
@@ -0,0 +1,216 @@
+/* ************************************************************************
+
+ qooxdoo - the new era of web development
+
+ http://qooxdoo.org
+
+ Copyright:
+ 2006 by STZ-IDA, Germany, http://www.stz-ida.de
+
+ License:
+ LGPL 2.1: http://www.gnu.org/licenses/lgpl.html
+
+ Authors:
+ * Til Schneider (til132)
+
+************************************************************************ */
+
+/* ************************************************************************
+
+
+************************************************************************ */
+
+/**
+ * A formatter and parser for numbers.
+ */
+qx.OO.defineClass("qx.util.format.NumberFormat", qx.util.format.Format,
+function() {
+ qx.util.format.Format.call(this);
+});
+
+
+/**
+ * The minimum number of integer digits (digits before the decimal separator).
+ * Missing digits will be filled up with 0 ("19" -> "0019").
+ */
+qx.OO.addProperty({ name:"minimumIntegerDigits", type:"number", defaultValue:0, allowNull:false });
+
+/**
+ * The maximum number of integer digits (superfluos digits will be cut off
+ * ("1923" -> "23").
+ */
+qx.OO.addProperty({ name:"maximumIntegerDigits", type:"number", defaultValue:null });
+
+/**
+ * The minimum number of fraction digits (digits after the decimal separator).
+ * Missing digits will be filled up with 0 ("1.5" -> "1.500")
+ */
+qx.OO.addProperty({ name:"minimumFractionDigits", type:"number", defaultValue:0, allowNull:false });
+
+/**
+ * The maximum number of fraction digits (digits after the decimal separator).
+ * Superflous digits will cause rounding ("1.8277" -> "1.83")
+ */
+qx.OO.addProperty({ name:"maximumFractionDigits", type:"number", defaultValue:null });
+
+/** Whether thousand groupings should be used {e.g. "1,432,234.65"}. */
+qx.OO.addProperty({ name:"groupingUsed", type:"boolean", defaultValue:true, allowNull:false });
+
+/** The prefix to put before the number {"EUR " -> "EUR 12.31"}. */
+qx.OO.addProperty({ name:"prefix", type:"string", defaultValue:"", allowNull:false });
+
+/** Sets the postfix to put after the number {" %" -> "56.13 %"}. */
+qx.OO.addProperty({ name:"postfix", type:"string", defaultValue:"", allowNull:false });
+
+
+/**
+ * Formats a number.
+ *
+ * @param num {number} the number to format.
+ * @return {string} the formatted number as a string.
+ */
+qx.Proto.format = function(num) {
+ var NumberFormat = qx.util.format.NumberFormat;
+
+ var negative = (num < 0);
+ if (negative) {
+ num = -num;
+ }
+ if (this.getMaximumFractionDigits() != null) {
+ // Do the rounding
+ var mover = Math.pow(10, this.getMaximumFractionDigits());
+ num = Math.round(num * mover) / mover;
+ }
+
+ if (num != 0) { // Math.log(0) = -Infinity
+ var integerDigits = Math.max(parseInt(Math.log(num) / Math.LN10) + 1, 1);
+ } else {
+ integerDigits = 1;
+ }
+
+ var numStr = "" + num;
+
+ // Prepare the integer part
+ var integerStr = numStr.substring(0, integerDigits);
+ while (integerStr.length < this.getMinimumIntegerDigits()) {
+ integerStr = "0" + integerStr;
+ }
+ if (this.getMaximumIntegerDigits() != null && integerStr.length > this.getMaximumIntegerDigits()) {
+ // NOTE: We cut off even though we did rounding before, because there
+ // may be rounding errors ("12.24000000000001" -> "12.24")
+ integerStr = integerStr.substring(integerStr.length - this.getMaximumIntegerDigits());
+ }
+
+ // Prepare the fraction part
+ var fractionStr = numStr.substring(integerDigits + 1);
+ while (fractionStr.length < this.getMinimumFractionDigits()) {
+ fractionStr += "0";
+ }
+ if (this.getMaximumFractionDigits() != -1 && fractionStr.length > this.getMaximumFractionDigits()) {
+ // We have already rounded -> Just cut off the rest
+ fractionStr = fractionStr.substring(0, this.getMaximumFractionDigits());
+ }
+
+ // Add the thousand groupings
+ if (this.getGroupingUsed()) {
+ var origIntegerStr = integerStr;
+ integerStr = "";
+ var groupPos;
+ for (groupPos = origIntegerStr.length; groupPos > 3; groupPos -= 3) {
+ integerStr = NumberFormat.GROUPING_SEPARATOR
+ + origIntegerStr.substring(groupPos - 3, groupPos) + integerStr;
+ }
+ integerStr = origIntegerStr.substring(0, groupPos) + integerStr;
+ }
+
+ // Workaround: prefix and postfix are null even their defaultValue is "" and
+ // allowNull is set to false?!?
+ var prefix = this.getPrefix() ? this.getPrefix() : "";
+ var postfix = this.getPostfix() ? this.getPostfix() : "";
+
+ // Assemble the number
+ var str = prefix + (negative ? "-" : "") + integerStr;
+ if (fractionStr.length > 0) {
+ str += NumberFormat.DECIMAL_SEPARATOR + fractionStr;
+ }
+ str += postfix;
+
+ return str;
+}
+
+
+/**
+ * Parses a number.
+ *
+ * @param str {string} the string to parse.
+ *
+ * @return {double} the number.
+ */
+qx.Proto.parse = function(str) {
+ var NumberFormat = qx.util.format.NumberFormat;
+
+ // use the escaped separators for regexp
+ var groupSepEsc = qx.lang.String.escapeRegexpChars(NumberFormat.GROUPING_SEPARATOR);
+ var decimalSepEsc = qx.lang.String.escapeRegexpChars(NumberFormat.DECIMAL_SEPARATOR);
+
+ var regex = new RegExp(qx.lang.String.escapeRegexpChars(this.getPrefix())
+ + '(-)?([0-9' + groupSepEsc + ']+)'
+ + '(' + decimalSepEsc + '\\d+)?'
+ + qx.lang.String.escapeRegexpChars(this.getPostfix()));
+
+ var hit = regex.exec(str);
+ if (hit == null) {
+ throw new Error("Number string '" + str + "' does not match the number format");
+ }
+
+ var negative = (hit[1] == "-");
+ var integerStr = hit[2];
+ var fractionStr = hit[3];
+
+ // Remove the thousand groupings
+ integerStr = integerStr.replace(new RegExp(groupSepEsc), "");
+
+ var asStr = (negative ? "-" : "") + integerStr;
+ if (fractionStr != null && fractionStr.length != 0) {
+ // Remove the leading decimal separator from the fractions string
+ fractionStr = fractionStr.replace(new RegExp(decimalSepEsc),"");
+ asStr += "." + fractionStr;
+ }
+ return parseFloat(asStr);
+}
+
+
+/**
+ * Returns the default number format.
+ *
+ * @return {NumberFormat} the default number format.
+ */
+qx.Class.getInstance = function() {
+ var NumberFormat = qx.util.format.NumberFormat;
+ if (NumberFormat._instance == null) {
+ NumberFormat._instance = new NumberFormat();
+ }
+ return NumberFormat._instance;
+}
+
+
+/**
+ * Returns an integer number format.
+ *
+ * @return {NumberFormat} an integer number format.
+ */
+qx.Class.getIntegerInstance = function() {
+ var NumberFormat = qx.util.format.NumberFormat;
+ if (NumberFormat._integerInstance == null) {
+ NumberFormat._integerInstance = new NumberFormat();
+ NumberFormat._integerInstance.setMaximumFractionDigits(0);
+ }
+ return NumberFormat._integerInstance;
+}
+
+
+/** {string} The decimal separator. */
+qx.Class.DECIMAL_SEPARATOR = ".";
+
+/** {string} The thousand grouping separator. */
+qx.Class.GROUPING_SEPARATOR = ",";
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/FiniteStateMachine.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/FiniteStateMachine.js
new file mode 100644
index 0000000000..e1a1605c83
--- /dev/null
+++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/FiniteStateMachine.js
@@ -0,0 +1,1189 @@
+/* ************************************************************************
+
+ qooxdoo - the new era of web development
+
+ http://qooxdoo.org
+
+ Copyright:
+ 2006 by Derrell Lipman
+
+ License:
+ LGPL 2.1: http://www.gnu.org/licenses/lgpl.html
+
+ Authors:
+ * Derrell Lipman (derrell)
+
+************************************************************************ */
+
+/* ************************************************************************
+
+#module(util_fsm)
+
+************************************************************************ */
+
+/**
+ * A finite state machine.
+ *
+ * See {@see qx.util.finitestatemacine.State} for details on creating States,
+ * and {@see qx.util.finitestatemacine.Transitions} for details on creating
+ * transitions between states.
+ *
+ * *EXPERIMENTAL*
+ * The interface to the finite state machine, states, and transitions is
+ * experimental. It may change in non-backward-compatible ways as more
+ * experience is gained in its use.
+ *
+ * @param machineName {string} The name of this finite state machine
+ *
+ */
+qx.OO.defineClass("qx.util.fsm.FiniteStateMachine", qx.core.Target,
+function(machineName)
+{
+ // Call our superclass' constructor
+ qx.core.Target.call(this);
+
+ // Save the machine name
+ this.setName(machineName);
+
+ // Initialize the states object
+ this._states = { };
+
+ // Initialize the saved-states stack
+ this._savedStates = [ ];
+
+ // Initialize the pending event queue
+ this._eventQueue = [ ];
+
+ // Initialize the blocked events queue
+ this._blockedEvents = [ ];
+
+ // Create the friendlyToObject" object. Each object has as its property
+ // name, the friendly name of the object; and as its property value, the
+ // object itself.
+ this._friendlyToObject = { };
+
+ // Create the "friendlyToHash" object. Each object has as its property
+ // name, the friendly name of the object; and as its property value, the
+ // hash code of the object.
+ this._friendlyToHash = { };
+
+ // Create the "hashToFriendly" object. Each object has as its property
+ // name, the hash code of the object; and as its property value, the
+ // friendly name of the object.
+ this._hashToFriendly = { };
+
+ // Friendly names can be added to groups, for easy manipulation of enabling
+ // and disabling groups of widgets. Track which friendly names are in which
+ // group.
+ this._groupToFriendly = { };
+
+ // We also need to be able to map back from friendly name to the groups it
+ // is in.
+ this._friendlyToGroups = { };
+});
+
+
+/*
+---------------------------------------------------------------------------
+ PROPERTIES
+---------------------------------------------------------------------------
+*/
+
+/**
+ * The name of this finite state machine (for debug messages)
+ */
+qx.OO.addProperty(
+ {
+ name : "name",
+ type : "string"
+ });
+
+/**
+ * The current state of the finite state machine.
+ */
+qx.OO.addProperty(
+ {
+ name : "state",
+ type : "string"
+ });
+
+/**
+ * The previous state of the finite state machine, i.e. the state from which
+ * we most recently transitioned. Note that this could be the same as the
+ * current state if a successful transition brought us back to the same
+ * state.
+ */
+qx.OO.addProperty(
+ {
+ name : "previousState",
+ type : "string"
+ });
+
+/**
+ * The state to which we will be transitioning. This property is valid only
+ * during a Transition's ontransition function and a State's onexit function.
+ * At all other times, it is null.
+ */
+qx.OO.addProperty(
+ {
+ name : "nextState",
+ type : "string"
+ });
+
+
+/**
+ * The maximum number of states which may pushed onto the state-stack. It is
+ * generally a poor idea to have very many states saved on a stack. Following
+ * program logic becomes very difficult, and the code can be highly
+ * unmaintainable. The default should be more than adequate. You've been
+ * warned.
+ */
+qx.OO.addProperty(
+ {
+ name : "maxSavedStates",
+ type : "number",
+ defaultValue : 5
+ });
+
+/*
+---------------------------------------------------------------------------
+ MODIFIER
+---------------------------------------------------------------------------
+*/
+
+
+/*
+---------------------------------------------------------------------------
+ UTILITIES
+---------------------------------------------------------------------------
+*/
+
+
+/**
+ * Add a state to the finite state machine.
+ *
+ * @param state {qx.util.fsm.State}
+ * An object of class qx.util.fsm.State representing a state
+ * which is to be a part of this finite state machine.
+ */
+qx.Proto.addState = function(state)
+{
+ // Ensure that we got valid state info
+ if (! state instanceof qx.util.fsm.State)
+ {
+ throw new Error("Invalid state: not an instance of " +
+ "qx.util.fsm.State");
+ }
+
+ // Retrieve the name of this state
+ var stateName = state.getName();
+
+ // Ensure that the state name doesn't already exist
+ if (stateName in this._states)
+ {
+ throw new Error("State " + state + " already exists");
+ }
+
+ // Add the new state object to the finite state machine
+ this._states[stateName] = state;
+};
+
+
+/**
+ * Add an object (typically a widget) that is to be accessed during state
+ * transitions, to the finite state machine.
+ *
+ * @param friendlyName {string}
+ * The friendly name to used for access to the object being added.
+ *
+ * @param obj {Object}
+ * The object to associate with the specified friendly name
+ *
+ * @param groupNames {Array}
+ * An optional list of group names of which this object is a member.
+ */
+qx.Proto.addObject = function(friendlyName, obj, groupNames)
+{
+ var hash = obj.toHashCode();
+ this._friendlyToHash[friendlyName] = hash;
+ this._hashToFriendly[hash] = friendlyName;
+ this._friendlyToObject[friendlyName] = obj;
+
+ // If no groupNames are specified, we're done.
+ if (! groupNames)
+ {
+ return;
+ }
+
+ // Allow either a single group name or an array of group names. If the
+ // former, we convert it to the latter to make the subsequent code simpler.
+ if (typeof(groupNames) == "string")
+ {
+ groupNames = [ groupNames ];
+ }
+
+ // For each group that this friendly name is to be a member of...
+ for (var i = 0; i < groupNames.length; i++)
+ {
+ var groupName = groupNames[i];
+
+ // If the group name doesn't yet exist...
+ if (! this._groupToFriendly[groupName])
+ {
+ // ... then create it.
+ this._groupToFriendly[groupName] = { };
+ }
+
+ // Add the friendly name to the list of names in this group
+ this._groupToFriendly[groupName][friendlyName] = true;
+
+ // If the friendly name group mapping doesn't yet exist...
+ if (! this._friendlyToGroups[friendlyName])
+ {
+ // ... then create it.
+ this._friendlyToGroups[friendlyName] = [ ];
+ }
+
+ // Append this group name to the list of groups this friendly name is in
+ this._friendlyToGroups[friendlyName] =
+ this._friendlyToGroups[friendlyName].concat(groupNames);
+ }
+};
+
+
+/**
+ * Remove an object which had previously been added by {@see #addObject}.
+ *
+ * @param friendlyName {string}
+ * The friendly name associated with an object, specifying which object is
+ * to be removed.
+ */
+qx.Proto.removeObject = function(friendlyName)
+{
+ var hash = this._friendlyToHash[friendlyName];
+
+ // Delete references to any groupos this friendly name was in
+ if (this._friendlyToGroups[friendlyName])
+ {
+ for (groupName in this._friendlyToGroups[friendlyName])
+ {
+ delete this._groupToFriendly[groupName];
+ }
+
+ delete this._friendlyToGroups[friendlyName];
+ }
+
+ // Delete the friendly name
+ delete this._hashToFriendly[hash];
+ delete this._friendlyToHash[friendlyName];
+ delete this._friendlyToObject[friendlyName];
+};
+
+
+/**
+ * Retrieve an object previously saved via {@see #addObject}, using its
+ * Friendly Name.
+ *
+ * @param friendlyName {string}
+ * The friendly name of the object to be retrieved.
+ *
+ * @return {Object}
+ * The object which has the specified friendly name, or undefined if no
+ * object has been associated with that name.
+ */
+qx.Proto.getObject = function(friendlyName)
+{
+ return this._friendlyToObject[friendlyName];
+};
+
+
+/**
+ * Get the friendly name of an object.
+ *
+ * @param obj {Object} The object for which the friendly name is desired
+ *
+ * @return {string}
+ * If the object has been previously registered via {@see #addObject}, then
+ * a reference to the object is returned; otherwise, null.
+ */
+qx.Proto.getFriendlyName = function(obj)
+{
+ var hash = obj.toHashCode();
+ return hash ? this.getObject(this._hashToFriendly[hash]) : null;
+};
+
+
+/**
+ * Retrieve the list of objects which have registered, via {@see addObject} as
+ * being members of the specified group.
+ *
+ * @param groupName {string}
+ * The name of the group for which the member list is desired.
+ *
+ * @return {Array}
+ * An array containing the friendly names of any objects which are members
+ * of the specified group. The resultant array may be empty.
+ */
+qx.Proto.getGroupObjects = function(groupName)
+{
+ var a = [ ];
+
+ for (var name in this._groupToFriendly[groupName])
+ {
+ a.push(name);
+ }
+
+ return a;
+};
+
+/**
+ * Start (or restart, after it has terminated) the finite state machine from
+ * the starting state. The starting state is defined as the first state added
+ * to the finite state machine.
+ */
+qx.Proto.start = function()
+{
+ var stateName;
+
+ // Set the start state to be the first state which was added to the machine
+ for (stateName in this._states)
+ {
+ this.setState(stateName);
+ this.setPreviousState(null);
+ this.setNextState(null);
+ break;
+ }
+
+ if (! stateName)
+ {
+ throw new Error("Machine started with no available states");
+ }
+
+ var debugFunctions =
+ (qx.Settings.getValueOfClass("qx.util.fsm.FiniteStateMachine",
+ "debugFlags") &
+ qx.util.fsm.FiniteStateMachine.DebugFlags.FUNCTION_DETAIL);
+
+ // Run the actionsBeforeOnentry actions for the initial state
+ if (debugFunctions)
+ {
+ this.debug(this.getName() + "#" + stateName + "#actionsBeforeOnentry");
+ }
+ this._states[stateName].getAutoActionsBeforeOnentry()(this);
+
+ // Run the entry function for the new state, if one is specified
+ if (debugFunctions)
+ {
+ this.debug(this.getName() + "#" + stateName + "#entry");
+ }
+ this._states[stateName].getOnentry()(this, null);
+
+ // Run the actionsAfterOnentry actions for the initial state
+ if (debugFunctions)
+ {
+ this.debug(this.getName() + "#" + stateName + "#actionsAfterOnentry");
+ }
+ this._states[stateName].getAutoActionsAfterOnentry()(this);
+
+};
+
+
+/**
+ * Save the current state on the saved-state stack. A future transition can
+ * then provide, as its nextState value, the class constant:
+ *
+ * qx.util.fsm.FiniteStateMachine.StateChange.POP_STATE_STACK
+ *
+ * which will cause the next state to be whatever is at the top of the
+ * saved-state stack, and remove that top element from the saved-state stack.
+ */
+qx.Proto.pushState = function()
+{
+ // See if there's room on the state stack for a new state
+ if (this.getMaxSavedStates() >= this._savedStates.length)
+ {
+ // Nope. Programmer error.
+ throw new Error("Saved-state stack is full");
+ }
+
+ // Push the current state onto the saved-state stack
+ this._savedStates.push(this.getState());
+};
+
+
+/**
+ * Add the specified event to a list of events to be passed to the next state
+ * following state transition.
+ *
+ * @param event {qx.event.type.Event}
+ * The event to add to the event queue for processing after state change.
+ */
+qx.Proto.postponeEvent = function(event)
+{
+ // Add this event to the blocked event queue, so it will be passed to the
+ // next state upon transition.
+ this._blockedEvents.unshift(event);
+};
+
+
+/**
+ * Event listener for all event types in the finite state machine
+ *
+ * @param event {qx.event.type.Event}
+ * The event that was dispatched.
+ */
+qx.Proto.eventListener = function(event)
+{
+ // Events are enqueued upon receipt. Some events are then processed
+ // immediately; other events get processed later. We need to allow the
+ // event dispatcher to free the source event upon our return, so we'll clone
+ // it and enqueue our clone. The source event can then be disposed upon our
+ // return.
+ var e = { };
+ for (var prop in event)
+ {
+ e[prop] = event[prop];
+ }
+
+ // Add the event to the event queue
+ this._eventQueue.unshift(e);
+
+ if (qx.Settings.getValueOfClass("qx.util.fsm.FiniteStateMachine",
+ "debugFlags") &
+ qx.util.fsm.FiniteStateMachine.DebugFlags.EVENTS)
+ {
+ this.debug(this.getName() + ": Queued event: " + e.getType());
+ }
+
+ // Process events
+ this._processEvents();
+};
+
+
+/**
+ * Process all of the events on the event queue.
+ */
+qx.Proto._processEvents = function()
+{
+ // eventListener() can potentially be called while we're processing events
+ if (this._eventProcessingInProgress)
+ {
+ // We were processing already, so don't process concurrently.
+ return;
+ }
+
+ // Track that we're processing events
+ this._eventProcessingInProgress = true;
+
+ // Process each of the events on the event queue
+ while (this._eventQueue.length > 0)
+ {
+ // Pull the next event from the pending event queue
+ var event = this._eventQueue.pop();
+
+ // Run the finite state machine with this event
+ this._run(event);
+
+ // We can now dispose the event
+ event.dispose();
+ }
+
+ // We're no longer processing events
+ this._eventProcessingInProgress = false;
+};
+
+/**
+ * Run the finite state machine to process a single event.
+ *
+ * @param event {qx.event.type.Event}
+ * An event that has been dispatched. The event may be handled (if the
+ * current state handles this event type), queued (if the current state
+ * blocks this event type), or discarded (if the current state neither
+ * handles nor blocks this event type).
+ */
+qx.Proto._run = function(event)
+{
+ // For use in generated functions...
+ var fsm = this;
+
+ // State name variables
+ var thisState;
+ var nextState;
+ var prevState;
+
+ // The current State object
+ var currentState;
+
+ // The transitions available in the current State
+ var transitions;
+
+ // Events handled by the current State
+ var e;
+
+ // The action to take place upon receipt of a particular event
+ var action;
+
+ // Get the debug flags
+ var debugFlags =
+ (qx.Settings.getValueOfClass("qx.util.fsm.FiniteStateMachine",
+ "debugFlags"));
+
+ // Allow slightly faster access to determine if debug is enableda
+ var debugEvents =
+ debugFlags & qx.util.fsm.FiniteStateMachine.DebugFlags.EVENTS;
+ var debugTransitions =
+ debugFlags & qx.util.fsm.FiniteStateMachine.DebugFlags.TRANSITIONS;
+ var debugFunctions =
+ debugFlags & qx.util.fsm.FiniteStateMachine.DebugFlags.FUNCTION_DETAIL;
+ var debugObjectNotFound =
+ debugFlags & qx.util.fsm.FiniteStateMachine.DebugFlags.OBJECT_NOT_FOUND;
+
+ if (debugEvents)
+ {
+ this.debug(this.getName() + ": Process event: " + event.getType());
+ }
+
+ // Get the current state name
+ thisState = this.getState();
+
+ // Get the current State object
+ currentState = this._states[thisState];
+
+ // Get a list of the transitions available from this state
+ transitions = currentState.transitions;
+
+ // Determine how to handle this event
+ e = currentState.getEvents()[event.getType()];
+
+ // See if we actually found this event type
+ if (! e)
+ {
+ if (this.debugEvents)
+ {
+ this.debug(this.getName() + ": Event '" + event.getType() + "'" +
+ " not handled. Ignoring.");
+ }
+ return;
+ }
+
+
+ // We might have found a constant (PREDICATE or BLOCKED) or an object with
+ // each property name being the friendly name of a saved object, and the
+ // property value being one of the constants (PREDICATE or BLOCKED).
+ if (typeof(e) == "object")
+ {
+ // Individual objects are listed. Ensure target is a saved object
+ var friendly = this.getFriendlyName(event.getTarget());
+ if (! friendly)
+ {
+ // Nope, it doesn't seem so. Just discard it.
+ if (debugObjectNotFound)
+ {
+ this.debug(this.getName() + ": Could not find friendly name for '" +
+ event.getType() + "' on '" + event.getTarget() + "'");
+ }
+ return;
+ }
+
+ action = e[friendly];
+ }
+ else
+ {
+ action = e;
+ }
+
+ switch(action)
+ {
+ case qx.util.fsm.FiniteStateMachine.EventHandling.PREDICATE:
+ // Process this event. One of the transitions should handle it.
+ break;
+
+ case qx.util.fsm.FiniteStateMachine.EventHandling.BLOCKED:
+ // This event is blocked. Enqueue it for later, and get outta here.
+ this._blockedEvents.unshift(event);
+ return;
+
+ default:
+ // See if we've been given an explicit transition name
+ if (typeof(action) == "string")
+ {
+ // Yup! Ensure that it exists
+ if (transitions[action])
+ {
+ // Yup. Create a transitions object containing only this transition.
+ var trans = transitions[action];
+ transitions = { };
+ transitions[action] = trans;
+ }
+ else
+ {
+ throw new Error("Explicit transition " + action + " does not exist");
+ }
+
+ break;
+ }
+ }
+
+ // We handle the event. Try each transition in turn until we find one that
+ // is acceptable.
+ for (var t in transitions)
+ {
+ var trans = transitions[t];
+
+ // Does the predicate allow use of this transition?
+ switch(trans.getPredicate()(this, event))
+ {
+ case true:
+ // Transition is allowed. Proceed.
+ break;
+
+ case false:
+ // Transition is not allowed. Try next transition.
+ continue;
+
+ case null:
+ // Transition indicates not to try further transitions
+ return;
+
+ default:
+ throw new Error("Transition " + thisState + ":" + t +
+ " returned a value other than true, false, or null.");
+ return;
+ }
+
+ // We think we can transition to the next state. Set next state.
+ nextState = trans.getNextState();
+ if (typeof(nextState) == "string")
+ {
+ // We found a literal state name. Ensure it exists.
+ if (! nextState in this._states)
+ {
+ throw new Error("Attempt to transition to nonexistent state " +
+ nextState);
+ }
+
+ // It exists. Track it being the next state.
+ this.setNextState(nextState);
+ }
+ else
+ {
+ // If it's not a string, nextState must be a StateChange constant
+ switch(nextState)
+ {
+ case qx.util.fsm.FiniteStateMachine.StateChange.CURRENT_STATE:
+ // They want to remain in the same state.
+ nextState = thisState;
+ this.setNextState(nextState)
+ break;
+
+ case qx.util.fsm.FiniteStateMachine.StateChange.POP_STATE_STACK:
+ // Switch to the state at the top of the state stack.
+ if (this._stateStack.length == 0)
+ {
+ throw new Error("Attempt to transition to POP_STATE_STACK " +
+ "while state stack is empty.");
+ }
+
+ // Pop the state stack to retrieve the state to transition to
+ nextState = this._stateStack.pop();
+ this.setNextState(nextState);
+ break;
+
+ default:
+ throw new Error("Internal error: invalid nextState");
+ break;
+ }
+ }
+
+ // Run the actionsBeforeOntransition actions for this transition
+ if (debugFunctions)
+ {
+ this.debug(this.getName() + "#" + thisState + "#" + t +
+ "#autoActionsBeforeOntransition");
+ }
+ trans.getAutoActionsBeforeOntransition()(this);
+
+ // Run the 'ontransition' function
+ if (debugFunctions)
+ {
+ this.debug(this.getName() + "#" + thisState + "#" + t + "#ontransition");
+ }
+ trans.getOntransition()(this, event);
+
+ // Run the autoActionsAfterOntransition actions for this transition
+ if (debugFunctions)
+ {
+ this.debug(this.getName() + "#" + thisState + "#" + t +
+ "#autoActionsAfterOntransition");
+ }
+ trans.getAutoActionsAfterOntransition()(this);
+
+ // Run the autoActionsBeforeOnexit actions for the old state
+ if (debugFunctions)
+ {
+ this.debug(this.getName() + "#" + thisState +
+ "#autoActionsBeforeOnexit");
+ }
+ currentState.getAutoActionsBeforeOnexit()(this);
+
+ // Run the exit function for the old state
+ if (debugFunctions)
+ {
+ this.debug(this.getName() + "#" + thisState + "#exit");
+ }
+ currentState.getOnexit()(this, event);
+
+ // Run the autoActionsAfterOnexit actions for the old state
+ if (debugFunctions)
+ {
+ this.debug(this.getName() + "#" + thisState + "#autoActionsAfterOnexit");
+ }
+ currentState.getAutoActionsAfterOnentry()(this);
+
+ // Reset currentState to the new state object
+ currentState = this._states[this.getNextState()];
+
+ // set previousState and state, and clear nextState, for transition
+ this.setPreviousState(thisState);
+ this.setState(this.getNextState());
+ this.setNextState(null);
+ prevState = thisState;
+ thisState = nextState;
+ nextState = undefined;
+
+ // Run the autoActionsBeforeOnentry actions for the new state
+ if (debugFunctions)
+ {
+ this.debug(this.getName() + "#" + thisState +
+ "#autoActionsBeforeOnentry");
+ }
+ currentState.getAutoActionsBeforeOnentry()(this);
+
+ // Run the entry function for the new state, if one is specified
+ if (debugFunctions)
+ {
+ this.debug(this.getName() + "#" + thisState + "#entry");
+ }
+ currentState.getOnentry()(this, event);
+
+ // Run the autoActionsAfterOnentry actions for the new state
+ if (debugFunctions)
+ {
+ this.debug(this.getName() + "#" + thisState +
+ "#autoActionsAfterOnentry");
+ }
+ currentState.getAutoActionsAfterOnentry()(this);
+
+ // Add the blocked events to the pending event queue
+ if (this._blockedEvents.length > 0)
+ {
+ this._eventQueue.unshift(this._blockedEvents);
+ }
+
+ // The blocked event list is now empty
+ this._blockedEvents = [ ];
+
+ // Ensure that all actions have been flushed
+ qx.ui.core.Widget.flushGlobalQueues();
+
+ if (debugTransitions)
+ {
+ this.debug(this.getName() + "#" + prevState + " => " +
+ this.getName() + "#" + thisState);
+ }
+
+ // See ya!
+ return;
+ }
+
+ if (debugTransitions)
+ {
+ this.debug(this.getName() + "#" + thisState +
+ ": event '" + event.getType() + "'" +
+ ": no transition found. No state change.");
+ }
+};
+
+
+
+/*
+---------------------------------------------------------------------------
+ EVENT LISTENERS
+---------------------------------------------------------------------------
+*/
+
+
+
+/*
+---------------------------------------------------------------------------
+ CLASS CONSTANTS
+---------------------------------------------------------------------------
+*/
+
+/**
+ * Constants which may be values of the nextState member in the transitionInfo
+ * parameter of the Transition constructor.
+ */
+qx.Class.StateChange =
+{
+ /** When used as a nextState value, means remain in current state */
+ CURRENT_STATE : 1,
+
+ /** When used as a nextState value, means go to most-recently pushed state */
+ POP_STATE_STACK : 2,
+
+ /** When used as a nextState value, means terminate this state machine */
+ TERMINATE : 3
+};
+
+
+/**
+ * Constants for use in the events member of the transitionInfo parameter of
+ * the Transition constructor.
+ */
+qx.Class.EventHandling =
+{
+ /**
+ * This event is handled by this state, but the predicate of a transition
+ * will determine whether to use that transition.
+ */
+ PREDICATE : 1,
+
+ /** Enqueue this event for possible use by the next state */
+ BLOCKED : 2
+};
+
+/**
+ * Debug bitmask values. Set the debug flags from the application by or-ing
+ * together bits, akin to this:
+ *
+ * qx.Settings.setCustomOfClass(
+ * "qx.util.fsm.FiniteStateMachine",
+ * "debugFlags",
+ * (qx.util.fsm.FiniteStateMachine.DebugFlags.EVENTS |
+ * qx.util.fsm.FiniteStateMachine.DebugFlags.TRANSITIONS |
+ * qx.util.fsm.FiniteStateMachine.DebugFlags.FUNCTION_DETAIL |
+ * qx.util.fsm.FiniteStateMachine.DebugFlags.OBJECT_NOT_FOUND));
+ */
+qx.Class.DebugFlags =
+{
+ /** Show events */
+ EVENTS : 1,
+
+ /** Show transitions */
+ TRANSITIONS : 2,
+
+ /** Show individual function invocations during transitions */
+ FUNCTION_DETAIL : 4,
+
+ /** When object friendly names are referenced but not found, show message */
+ OBJECT_NOT_FOUND : 8
+};
+
+
+/*
+---------------------------------------------------------------------------
+ CLASS DEFAULT SETTINGS
+---------------------------------------------------------------------------
+*/
+
+/**
+ * Debug flags: bitmap of DebugFlags (see Class Constants).
+ */
+qx.Settings.setDefault(
+ "debugFlags",
+ (qx.util.fsm.FiniteStateMachine.DebugFlags.EVENTS |
+ qx.util.fsm.FiniteStateMachine.DebugFlags.TRANSITIONS |
+ qx.util.fsm.FiniteStateMachine.DebugFlags.OBJECT_NOT_FOUND));
+
+
+/*
+---------------------------------------------------------------------------
+ CLASS FUNCTIONS
+---------------------------------------------------------------------------
+*/
+
+/**
+ * Common function used by {qx.util.fsm.State} and
+ * {qx.util.fsm.Transition} for checking the value provided for
+ * auto actions.
+ *
+ * Auto-action property values passed to us look akin to:
+ *
+ * <pre>
+ * {
+ * // The name of a function.
+ * "setEnabled" :
+ * [
+ * {
+ * // The parameter value(s), thus "setEnabled(true);"
+ * "parameters" : [ true ],
+ *
+ * // The function would be called on each object:
+ * // this.getObject("obj1").setEnabled(true);
+ * // this.getObject("obj2").setEnabled(true);
+ * "objects" : [ "obj1", "obj2" ]
+ *
+ * // And similarly for each object in each specified group.
+ * "groups" : [ "group1", "group2" ],
+ * }
+ * ];
+ *
+ * "setColor" :
+ * [
+ * {
+ * "parameters" : [ "blue" ]
+ * "groups" : [ "group3", "group4" ],
+ * "objects" : [ "obj3", "obj4" ]
+ * }
+ * ];
+ * };
+ * </pre>
+ *
+ * @param actionType {string}
+ * The name of the action being validated (for debug messages)
+ *
+ * @param propValue {Object}
+ * The property value which is being validated
+ *
+ * @param propData
+ * Not used
+ */
+qx.Class._commonCheckAutoActions = function(actionType, propValue, propData)
+{
+ // Validate that we received an object property value
+ if (typeof(propValue) != "object")
+ {
+ throw new Error("Invalid " + actionType + " value: " + typeof(propValue));
+ }
+
+ // We'll create a function to do the requested actions. Initialize the
+ // string into which we'll generate the common fragment added to the
+ // function for each object.
+ var funcFragment;
+
+ // Here, we'll keep the function body. Initialize a try block.
+ var func =
+ "try" +
+ "{";
+
+ var param;
+ var objectAndGroupList;
+
+ // Retrieve the function request, e.g.
+ // "enabled" :
+ for (var f in propValue)
+ {
+ // Get the function request value object, e.g.
+ // "setEnabled" :
+ // [
+ // {
+ // "parameters" : [ true ],
+ // "objects" : [ "obj1", "obj2" ]
+ // "groups" : [ "group1", "group2" ],
+ // }
+ // ];
+ var functionRequest = propValue[f];
+
+ // The function request value should be an object
+ if (! functionRequest instanceof Array)
+ {
+ throw new Error("Invalid function request type: " +
+ "expected array, found " + typeof(functionRequest));
+ }
+
+ // For each function request...
+ for (var i = 0; i < functionRequest.length; i++)
+ {
+ // Retreive the object and group list object
+ objectAndGroupList = functionRequest[i];
+
+ // The object and group list should be an object, e.g.
+ // {
+ // "parameters" : [ true ],
+ // "objects" : [ "obj1", "obj2" ]
+ // "groups" : [ "group1", "group2" ],
+ // }
+ if (typeof(objectAndGroupList) != "object")
+ {
+ throw new Error("Invalid function request parameter type: " +
+ "expected object, found " +
+ typeof(functionRequest[param]));
+ }
+
+ // Retrieve the parameter list
+ params = objectAndGroupList["parameters"];
+
+ // If it didn't exist, ...
+ if (! params)
+ {
+ // ... use an empty array.
+ params = [ ];
+ }
+ else
+ {
+ // otherwise, ensure we got an array
+ if (! params instanceof Array)
+ {
+ throw new Error("Invalid function parameters: " +
+ "expected array, found " + typeof(params));
+ }
+ }
+
+ // Create the function to call on each object. The object on which the
+ // function is called will be prepended later.
+ funcFragment = f + "(";
+
+ // For each parameter...
+ for (var j = 0; j < params.length; j++)
+ {
+ // If this isn't the first parameter, add a separator
+ if (j != 0)
+ {
+ funcFragment += ",";
+ }
+
+ if (typeof(params[j]) == "function")
+ {
+ // If the parameter is a function, arrange for it to be called
+ // at run time.
+ funcFragment += "(" + params[j] + ")(fsm)";
+ }
+ else if (typeof(params[j]) == "string")
+ {
+ // If the parameter is a string, quote it.
+ funcFragment += '"' + params[j] + '"';
+ }
+ else
+ {
+ // Otherwise, just add the parameter's literal value
+ funcFragment += params[j];
+ }
+ }
+
+ // Complete the function call
+ funcFragment += ")";
+
+ // Get the "objects" list, e.g.
+ // "objects" : [ "obj1", "obj2" ]
+ var a = objectAndGroupList["objects"];
+
+ // Was there an "objects" list?
+ if (! a)
+ {
+ // Nope. Simplify code by creating an empty array.
+ a = [ ];
+ }
+ else if (! a instanceof Array)
+ {
+ throw new Error("Invalid 'objects' list: expected array, got " +
+ typeof(a));
+ }
+
+ for (var j = 0; j < a.length; j++)
+ {
+ // Ensure we got a string
+ if (typeof(a[j]) != "string")
+ {
+ throw new Error("Invalid friendly name in 'objects' list: " + a[j]);
+ }
+
+ func += " fsm.getObject('" + a[j] + "')." + funcFragment + ";";
+ }
+
+ // Get the "groups" list, e.g.
+ // "groups" : [ "group1, "group2" ]
+ var g = objectAndGroupList["groups"];
+
+ // Was a "groups" list found?
+ if (g)
+ {
+ // Yup. Ensure it's an array.
+ if (! g instanceof Array)
+ {
+ throw new Error("Invalid 'groups' list: expected array, got " +
+ typeof(g));
+ }
+
+ for (var groupName in g)
+ {
+ // Arrange to call the function on each object in each group
+ func +=
+ " var groupObjects = " +
+ " fsm.getGroupObjects('" + g[groupName] + "');" +
+ " for (var i = 0; i < groupObjects.length; i++)" +
+ " {" +
+ " var objName = groupObjects[i];" +
+ " fsm.getObject(objName)." + funcFragment + ";" +
+ " }";
+ }
+ }
+ }
+ }
+
+ // Terminate the try block for function invocations
+ func +=
+ "}" +
+ "catch(e)" +
+ "{" +
+ " fsm.debug(e);" +
+ "}";
+
+// o = new qx.core.Object();
+// o.debug("Dynamically created " + actionType + "(fsm) { " + func + " }");
+
+ // We've now built the entire body of a function that implements calls to
+ // each of the requested automatic actions. Create and return the function,
+ // which will become the property value.
+ return new Function("fsm", func);
+};
+
+
+
+/*
+---------------------------------------------------------------------------
+ DISPOSER
+---------------------------------------------------------------------------
+*/
+
+qx.Proto.dispose = function()
+{
+ var e;
+ var s;
+
+ if (this.getDisposed()) {
+ return true;
+ }
+
+ while (this._savedStates.length > 0)
+ {
+ s = this._savedStates.pop();
+ s = null;
+ }
+ this._savedStates = null;
+
+ while (this._eventQueue.length > 0)
+ {
+ e = this._eventQueue.pop();
+ e.dispose();
+ e = null;
+ }
+ this._eventQueue = null;
+
+ while (this._blockedEvents.length > 0)
+ {
+ e = this._blockedEvents.pop();
+ e.dispose();
+ e = null;
+ }
+
+ for (var s in this._states)
+ {
+ this._states[s].dispose();
+ this._states[s] = null;
+ delete this._states[s];
+ }
+ this._states = null;
+
+ return qx.core.Target.prototype.dispose.call(this);
+}
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/State.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/State.js
new file mode 100644
index 0000000000..a61d27ff24
--- /dev/null
+++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/State.js
@@ -0,0 +1,613 @@
+/* ************************************************************************
+
+ qooxdoo - the new era of web development
+
+ http://qooxdoo.org
+
+ Copyright:
+ 2006 by Derrell Lipman
+
+ License:
+ LGPL 2.1: http://www.gnu.org/licenses/lgpl.html
+
+ Authors:
+ * Derrell Lipman (derrell)
+
+************************************************************************ */
+
+/* ************************************************************************
+
+#module(util_fsm)
+#require(qx.util.fsm.FiniteStateMachine)
+
+************************************************************************ */
+
+/**
+ * Create a new state which may be added to a finite state machine.
+ *
+ * *EXPERIMENTAL*
+ * The interface to the finite state machine, states, and transitions is
+ * experimental. It may change in non-backward-compatible ways as more
+ * experience is gained in its use.
+ *
+ * @param
+ * stateName -
+ * The name of this state. This is the name which may be referenced in
+ * objects of class qx.util.fsm.Transition, when passing of
+ * the the transition's predicate means transition to this state.
+ *
+ * @param
+ * stateInfo -
+ * An object containing any of the following properties:
+ *
+ * onentry -
+ * A function which is called upon entry to the state. Its signature is
+ * function(fsm, event) and it is saved in the onentry property of the
+ * state object. (This function is called after the Transition's action
+ * function and after the previous state's onexit function.)
+ *
+ * In the onentry function:
+ *
+ * fsm -
+ * The finite state machine object to which this state is attached.
+ *
+ * event -
+ * The event that caused the finite state machine to run
+ *
+ * onexit -
+ * A function which is called upon exit from the state. Its signature
+ * is function(fsm, event) and it is saved in the onexit property of the
+ * state object. (This function is called after the Transition's action
+ * function and before the next state's onentry function.)
+ *
+ * In the onexit function:
+ *
+ * fsm -
+ * The finite state machine object to which this state is attached.
+ *
+ * event -
+ * The event that caused the finite state machine to run
+ *
+ * autoActionsBeforeOnentry -
+ * autoActionsAfterOnentry -
+ * auutoActionsBeforeOnexit -
+ * autoActionsAfterOnexit -
+ * Automatic actions which take place at the time specified by the
+ * property name. In all cases, the action takes place immediately
+ * before or after the specified function.
+ *
+ * The property value for each of these properties is an object which
+ * describes some number of functions to invoke on a set of specified
+ * objects (typically widgets).
+ *
+ * An example, using autoActionsBeforeOnentry, might look like this:
+ *
+ * "autoActionsBeforeOnentry" :
+ * {
+ * // The name of a function.
+ * "enabled" :
+ * [
+ * {
+ * // The parameter value, thus "setEnabled(true);"
+ * "parameters" : [ true ],
+ *
+ * // The function would be called on each object:
+ * // this.getObject("obj1").setEnabled(true);
+ * // this.getObject("obj2").setEnabled(true);
+ * "objects" : [ "obj1", "obj2" ],
+ *
+ * // And similarly for each object in each specified group.
+ * "groups" : [ "group1", "group2" ]
+ * }
+ * ],
+ *
+ * // The name of another function.
+ * "visible" :
+ * [
+ * {
+ * // The parameter value, thus "setEnabled(true);"
+ * "parameters" : [ false ],
+ *
+ * // The function would be called on each object and group, as
+ * // described above.
+ * "objects" : [ "obj3", "obj4" ],
+ * "groups" : [ "group3", "group4" ]
+ * }
+ * ]
+ * };
+ *
+ *
+ * events (required) -
+ * A description to the finite state machine of how to handle a
+ * particular event, optionally associated with a specific target object
+ * on which the event was dispatched. This should be an object
+ * containing one property for each event which is either handled or
+ * blocked. The property name should be the event name. The property
+ * value should be one of:
+ *
+ * (a) qx.util.fsm.FiniteStateMachine.EventHandling.PREDICATE
+ *
+ * (b) qx.util.fsm.FiniteStateMachine.EventHandling.BLOCKED
+ *
+ * (c) a string containing the name of an explicit Transition to use
+ *
+ * (d) an object where each property name is the Friendly Name of an
+ * object (meaning that this rule applies if both the event and
+ * the event's target object's Friendly Name match), and its
+ * property value is one of (a), (b) or (c), above.
+ *
+ * This object is saved in the events property of the state object.
+ *
+ * Additional properties may be provided in stateInfo. They will not be
+ * used by the finite state machine, but will be available via
+ * this.getUserData("<propertyName>") during the state's onentry and
+ * onexit functions.
+ */
+qx.OO.defineClass("qx.util.fsm.State", qx.core.Object,
+function(stateName, stateInfo)
+{
+ // Call our superclass' constructor
+ qx.core.Object.call(this, true);
+
+ // Save the state name
+ this.setName(stateName);
+
+ // Ensure they passed in an object
+ if (typeof(stateInfo) != "object")
+ {
+ throw new Error("State info must be an object");
+ }
+
+ // Save data from the stateInfo object
+ for (var field in stateInfo)
+ {
+ // If we find one of our properties, call its setter.
+ switch(field)
+ {
+ case "onentry":
+ this.setOnentry(stateInfo[field]);
+ break;
+
+ case "onexit":
+ this.setOnexit(stateInfo[field]);
+ break;
+
+ case "autoActionsBeforeOnentry":
+ this.setAutoActionsBeforeOnentry(stateInfo[field]);
+ break;
+
+ case "autoActionsAfterOnentry":
+ this.setAutoActionsAfterOnentry(stateInfo[field]);
+ break;
+
+ case "autoActionsBeforeOnexit":
+ this.setAutoActionsBeforeOnentry(stateInfo[field]);
+ break;
+
+ case "autoActionsBeforeOnexit":
+ this.setAutoActionsBeforeOnentry(stateInfo[field]);
+ break;
+
+ case "events":
+ this.setEvents(stateInfo[field]);
+ break;
+
+ default:
+ // Anything else is user-provided data for their own use. Save it.
+ this.setUserData(field, stateInfo[field]);
+
+ // Log it in case it was a typo and they intended a built-in field
+ this.debug("State " + stateName + ": " +
+ "Adding user-provided field to state: " + field);
+
+ break;
+ }
+ }
+
+
+ // Check for required but missing properties
+ if (! this.getEvents())
+ {
+ throw new Error("The events object must be provided in new state info");
+ }
+
+
+ // Initialize the transition list
+ this.transitions = { };
+});
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ PROPERTIES
+---------------------------------------------------------------------------
+*/
+
+/**
+ * The name of this state. This name may be used as a Transition's nextState
+ * value, or an explicit next state in the 'events' handling list in a State.
+ */
+qx.OO.addProperty(
+ {
+ name : "name",
+ type : "string"
+ });
+
+/**
+ * The onentry function for this state. This is documented in the
+ * constructor, and is typically provided through the constructor's stateInfo
+ * object, but it is also possible (but highly NOT recommended) to change this
+ * dynamically.
+ */
+qx.OO.addProperty(
+ {
+ name : "onentry",
+ defaultValue : function(fsm, event) { }
+ });
+
+/**
+ * The onexit function for this state. This is documented in the constructor,
+ * and is typically provided through the constructor's stateInfo object, but
+ * it is also possible (but highly NOT recommended) to change this
+ * dynamically.
+ */
+qx.OO.addProperty(
+ {
+ name : "onexit",
+ defaultValue : function(fsm, event) { }
+ });
+
+/**
+ * Automatic actions to take prior to calling the state's onentry function.
+ *
+ * The value passed to setAutoActionsBeforeOnentry() should like something
+ * akin to:
+ *
+ * "autoActionsBeforeOnentry" :
+ * {
+ * // The name of a function. This would become "setEnabled("
+ * "enabled" :
+ * [
+ * {
+ * // The parameter value, thus "setEnabled(true);"
+ * "parameters" : [ true ],
+ *
+ * // The function would be called on each object:
+ * // this.getObject("obj1").setEnabled(true);
+ * // this.getObject("obj2").setEnabled(true);
+ * "objects" : [ "obj1", "obj2" ]
+ *
+ * // And similarly for each object in each specified group.
+ * "groups" : [ "group1", "group2" ],
+ * }
+ * ];
+ * };
+ */
+qx.OO.addProperty(
+ {
+ name : "autoActionsBeforeOnentry",
+ defaultValue : function(fsm, event) { }
+ });
+
+/**
+ * Automatic actions to take after return from the state's onentry function.
+ *
+ * The value passed to setAutoActionsAfterOnentry() should like something akin
+ * to:
+ *
+ * "autoActionsAfterOnentry" :
+ * {
+ * // The name of a function. This would become "setEnabled("
+ * "enabled" :
+ * [
+ * {
+ * // The parameter value, thus "setEnabled(true);"
+ * "parameters" : [ true ],
+ *
+ * // The function would be called on each object:
+ * // this.getObject("obj1").setEnabled(true);
+ * // this.getObject("obj2").setEnabled(true);
+ * "objects" : [ "obj1", "obj2" ]
+ *
+ * // And similarly for each object in each specified group.
+ * "groups" : [ "group1", "group2" ],
+ * }
+ * ];
+ * };
+ */
+qx.OO.addProperty(
+ {
+ name : "autoActionsAfterOnentry",
+ defaultValue : function(fsm, event) { }
+ });
+
+/**
+ * Automatic actions to take prior to calling the state's onexit function.
+ *
+ * The value passed to setAutoActionsBeforeOnexit() should like something akin
+ * to:
+ *
+ * "autoActionsBeforeOnexit" :
+ * {
+ * // The name of a function. This would become "setEnabled("
+ * "enabled" :
+ * [
+ * {
+ * // The parameter value, thus "setEnabled(true);"
+ * "parameters" : [ true ],
+ *
+ * // The function would be called on each object:
+ * // this.getObject("obj1").setEnabled(true);
+ * // this.getObject("obj2").setEnabled(true);
+ * "objects" : [ "obj1", "obj2" ]
+ *
+ * // And similarly for each object in each specified group.
+ * "groups" : [ "group1", "group2" ],
+ * }
+ * ];
+ * };
+ */
+qx.OO.addProperty(
+ {
+ name : "autoActionsBeforeOnexit",
+ defaultValue : function(fsm, event) { }
+ });
+
+
+/**
+ * Automatic actions to take after returning from the state's onexit function.
+ *
+ * The value passed to setAutoActionsAfterOnexit() should like something akin
+ * to:
+ *
+ * "autoActionsBeforeOnexit" :
+ * {
+ * // The name of a function. This would become "setEnabled("
+ * "enabled" :
+ * [
+ * {
+ * // The parameter value, thus "setEnabled(true);"
+ * "parameters" : [ true ],
+ *
+ * // The function would be called on each object:
+ * // this.getObject("obj1").setEnabled(true);
+ * // this.getObject("obj2").setEnabled(true);
+ * "objects" : [ "obj1", "obj2" ]
+ *
+ * // And similarly for each object in each specified group.
+ * "groups" : [ "group1", "group2" ],
+ * }
+ * ];
+ * };
+ */
+qx.OO.addProperty(
+ {
+ name : "autoActionsAfterOnexit",
+ defaultValue : function(fsm, event) { }
+ });
+
+
+/**
+ * The object representing handled and blocked events for this state. This is
+ * documented in the constructor, and is typically provided through the
+ * constructor's stateInfo object, but it is also possible (but highly NOT
+ * recommended) to change this dynamically.
+ */
+qx.OO.addProperty(
+ {
+ name : "events"
+ });
+
+
+
+/*
+---------------------------------------------------------------------------
+ MODIFIER
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._checkName = function(propValue, propData)
+{
+ // Ensure that we got a valid state name
+ if (typeof(propValue) != "string" || propValue.length < 1)
+ {
+ throw new Error("Invalid state name");
+ }
+
+ return propValue;
+};
+
+qx.Proto._checkOnentry = function(propValue, propData)
+{
+ // Validate the onentry function
+ switch(typeof(propValue))
+ {
+ case "undefined":
+ // None provided. Convert it to a null function
+ return function(fsm, event) {};
+
+ case "function":
+ // We're cool. No changes required
+ return propValue;
+
+ default:
+ throw new Error("Invalid onentry type: " + typeof(propValue));
+ return null;
+ }
+};
+
+qx.Proto._checkOnexit = function(propValue, propData)
+{
+ // Validate the onexit function
+ switch(typeof(propValue))
+ {
+ case "undefined":
+ // None provided. Convert it to a null function
+ return function(fsm, event) {};
+
+ case "function":
+ // We're cool. No changes required
+ return propValue;
+
+ default:
+ throw new Error("Invalid onexit type: " + typeof(propValue));
+ return null;
+ }
+};
+
+qx.Proto._checkEvents = function(propValue, propData)
+{
+ // Validate that events is an object
+ if (typeof(propValue) != "object")
+ {
+ throw new Error("events must be an object");
+ }
+
+ // Confirm that each property is a valid value
+ // The property value should be one of:
+ //
+ // (a) qx.util.fsm.FiniteStateMachine.EventHandling.PREDICATE
+ //
+ // (b) qx.util.fsm.FiniteStateMachine.EventHandling.BLOCKED
+ //
+ // (c) a string containing the name of an explicit Transition to use
+ //
+ // (d) an object where each property name is the Friendly Name of an
+ // object (meaning that this rule applies if both the event and
+ // the event's target object's Friendly Name match), and its
+ // property value is one of (a), (b) or (c), above.
+ for (var e in propValue)
+ {
+ var action = propValue[e];
+ if (typeof(action) == "number" &&
+ action != qx.util.fsm.FiniteStateMachine.EventHandling.PREDICATE &&
+ action != qx.util.fsm.FiniteStateMachine.EventHandling.BLOCKED)
+ {
+ throw new Error("Invalid numeric value in events object: " +
+ e + ": " + action);
+ }
+ else if (typeof(action) == "object")
+ {
+ for (action_e in action)
+ {
+ if (typeof(action[action_e]) == "number" &&
+ action != qx.util.fsm.FiniteStateMachine.EventHandling.PREDICATE &&
+ action != qx.util.fsm.FiniteStateMachine.EventHandling.BLOCKED)
+ {
+ throw new Error("Invalid numeric value in events object " +
+ "(" + e + "): " +
+ action_e + ": " + action[action_e]);
+ }
+ else if (typeof(action[action_e]) != "string")
+ {
+ throw new Error("Invalid value in events object " +
+ "(" + e + "): " +
+ action_e + ": " + action[action_e]);
+ }
+ }
+ }
+ else if (typeof(action) != "string")
+ {
+ throw new Error("Invalid value in events object: " +
+ e + ": " + propValue[e]);
+ }
+ }
+
+ // We're cool. No changes required.
+ return propValue;
+};
+
+qx.Proto._checkAutoActionsBeforeOnentry = function(propValue, propData)
+{
+ return qx.util.fsm.FiniteStateMachine._commonCheckAutoActions(
+ "autoActionsBeforeOnentry",
+ propValue,
+ propData);
+};
+
+qx.Proto._checkAutoActionsAfterOnentry = function(propValue, propData)
+{
+ return qx.util.fsm.FiniteStateMachine._commonCheckAutoActions(
+ "autoActionsAfterOnentry",
+ propValue,
+ propData);
+};
+
+qx.Proto._checkAutoActionsBeforeOnexit = function(propValue, propData)
+{
+ return qx.util.fsm.FiniteStateMachine._commonCheckAutoActions(
+ "autoActionsBeforeOnexit",
+ propValue,
+ propData);
+};
+
+qx.Proto._checkAutoActionsAfterOnexit = function(propValue, propData)
+{
+ return qx.util.fsm.FiniteStateMachine._commonCheckAutoActions(
+ "autoActionsAfterOnexit",
+ propValue,
+ propData);
+};
+
+
+/*
+---------------------------------------------------------------------------
+ UTILITIES
+---------------------------------------------------------------------------
+*/
+
+/**
+ * Add a transition to a state
+ *
+ * @param trans {qx.util.fsm.Transition}
+ * An object of class qx.util.fsm.Transition representing a
+ * transition which is to be a part of this state.
+ */
+qx.Proto.addTransition = function(trans)
+{
+ // Ensure that we got valid transition info
+ if (! trans instanceof qx.util.fsm.Transition)
+ {
+ throw new Error("Invalid transition: not an instance of " +
+ "qx.util.fsm.Transition");
+ }
+
+ // Add the new transition object to the state
+ this.transitions[trans.getName()] = trans;
+};
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ EVENT LISTENERS
+---------------------------------------------------------------------------
+*/
+
+
+
+/*
+---------------------------------------------------------------------------
+ CLASS CONSTANTS
+---------------------------------------------------------------------------
+*/
+
+
+
+/*
+---------------------------------------------------------------------------
+ DISPOSER
+---------------------------------------------------------------------------
+*/
+
+qx.Proto.dispose = function()
+{
+ if (this.getDisposed()) {
+ return true;
+ }
+
+ return qx.core.Object.prototype.dispose.call(this);
+}
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/Transition.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/Transition.js
new file mode 100644
index 0000000000..3d13324999
--- /dev/null
+++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/Transition.js
@@ -0,0 +1,383 @@
+/* ************************************************************************
+
+ qooxdoo - the new era of web development
+
+ http://qooxdoo.org
+
+ Copyright:
+ 2006 by Derrell Lipman
+
+ License:
+ LGPL 2.1: http://www.gnu.org/licenses/lgpl.html
+
+ Authors:
+ * Derrell Lipman (derrell)
+
+************************************************************************ */
+
+/* ************************************************************************
+
+#module(util_fsm)
+#require(qx.util.fsm.FiniteStateMachine)
+
+************************************************************************ */
+
+/**
+ * Create a new possible transition from one state to another.
+ *
+ * *EXPERIMENTAL*
+ * The interface to the finite state machine, states, and transitions is
+ * experimental. It may change in non-backward-compatible ways as more
+ * experience is gained in its use.
+ *
+ * @param transitionName {string}
+ * The name of this transition, used in debug messages.
+ *
+ * @param transitionInfo {Object}
+ * An object optionally containing any of the following properties:
+ *
+ * predicate -
+ * A function which is called to determine whether this transition is
+ * acceptable. An acceptable transition will cause the transition's
+ * "ontransition" function to be run, the current state's "onexit"
+ * function to be run, and the new state's "onentry" function to be run.
+ *
+ * The predicate function's signature is function(fsm, event) and it is
+ * saved in the predicate property of the transition object. In the
+ * predicate function:
+ *
+ * fsm -
+ * The finite state machine object to which this state is attached.
+ *
+ * event -
+ * The event that caused a run of the finite state machine
+ *
+ * The predicate function should return one of the following three
+ * values:
+ *
+ * - true means the transition is acceptable
+ *
+ * - false means the transition is not acceptable, and the next
+ * transition (if one exists) should be tried to determine if it is
+ * acceptable
+ *
+ * - null means that the transition determined that no further
+ * transitions should be tried. This might be used when the
+ * transition ascertained that the event is for a target that is not
+ * available in the current state, and the event has called
+ * fsm.queueEvent() to have the event delivered upon state
+ * transition.
+ *
+ * It is possible to create a default predicate -- one that will cause a
+ * transition to be acceptable always -- by either not providing a
+ * predicate property, or by explicitely either setting the predicate
+ * property to 'true' or setting it to a function that unconditionally
+ * returns 'true'. This default transition should, of course, always be
+ * the last transition added to a state, since no transition added after
+ * it will ever be tried.
+ *
+ * nextState -
+ * The state to which we transition, if the predicate returns true
+ * (meaning the transition is acceptable). The value of nextState may
+ * be:
+ *
+ * - a string, the state name of the state to transition to
+ *
+ * - One of the constants:
+ * - qx.util.fsm.FiniteStateMachine.StateChange.CURRENT_STATE:
+ * Remain in whatever is the current state
+ * - qx.util.fsm.FiniteStateMachine.StateChange.PREVIOUS_STATE:
+ * Transition to the state at the top of the saved-state stack,
+ * and remove the top element from the saved-state stack.
+ * Elements are added to the saved-state stack using
+ * fsm.pushState(). It is an error if no state exists on the
+ * saved-state stack.
+ * - qx.util.fsm.FiniteStateMachine.StateChange.TERMINATE:
+ * TBD
+ *
+ * autoActionsBeforeOntransition -
+ * autoActionsAfterOntransition -
+ * Automatic actions which take place at the time specified by the
+ * property name. In all cases, the action takes place immediately
+ * before or after the specified function.
+ *
+ * The property value for each of these properties is an object which
+ * describes some number of functions to invoke on a set of specified
+ * objects (typically widgets).
+ *
+ * See {@see qx.util.fsm.State} for an example of autoActions.
+ *
+ * ontransition -
+ * A function which is called if the predicate function for this
+ * transition returns true. Its signature is function(fsm, event) and
+ * it is saved in the ontransition property of the transition object.
+ * In the ontransition function:
+ *
+ * fsm -
+ * The finite state machine object to which this state is attached.
+ *
+ * event -
+ * The event that caused a run of the finite state machine
+ *
+ * Additional properties may be provided in transInfo. They will not be
+ * used by the finite state machine, but will be available via
+ * this.getUserData("<propertyName>") during the transition's predicate
+ * and ontransition functions.
+ */
+qx.OO.defineClass("qx.util.fsm.Transition", qx.core.Object,
+function(transitionName, transitionInfo)
+{
+ // Call our superclass' constructor
+ qx.core.Object.call(this, true);
+
+ // Save the state name
+ this.setName(transitionName);
+
+ // Save data from the transitionInfo object
+ for (var field in transitionInfo)
+ {
+ // If we find one of our properties, call its setter.
+ switch(field)
+ {
+ case "predicate":
+ this.setPredicate(transitionInfo[field]);
+ break;
+
+ case "nextState":
+ this.setNextState(transitionInfo[field]);
+ break;
+
+ case "autoActionsBeforeOntransition":
+ this.setAutoActionsBeforeOntransition(transitionInfo[field]);
+ break;
+
+ case "autoActionsAfterOntransition":
+ this.setAutoActionsAfterOntransition(transitionInfo[field]);
+ break;
+
+ case "ontransition":
+ this.setOntransition(transitionInfo[field]);
+ break;
+
+ default:
+ // Anything else is user-provided data for their own use. Save it.
+ this.setUserData(field, transitionInfo[field]);
+
+ // Log it in case it was a typo and they intended a built-in field
+ this.debug("Transition " + transitionName + ": " +
+ "Adding user-provided field to transition: " + field);
+
+ break;
+ }
+ }
+});
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ PROPERTIES
+---------------------------------------------------------------------------
+*/
+
+/**
+ * The name of this transition
+ */
+qx.OO.addProperty(
+ {
+ name : "name",
+ type : "string"
+ });
+
+/**
+ * The predicate function for this transition. This is documented in the
+ * constructor, and is typically provided through the constructor's
+ * transitionInfo object, but it is also possible (but highly NOT recommended)
+ * to change this dynamically.
+ */
+qx.OO.addProperty(
+ {
+ name : "predicate",
+ defaultValue : function(fsm, event) { return true; }
+ });
+
+/**
+ * The state to transition to, if the predicate determines that this
+ * transition is acceptable. This is documented in the constructor, and is
+ * typically provided through the constructor's transitionInfo object, but it
+ * is also possible (but highly NOT recommended) to change this dynamically.
+ */
+qx.OO.addProperty(
+ {
+ name : "nextState",
+ defaultValue : qx.util.fsm.FiniteStateMachine.StateChange.CURRENT_STATE
+ });
+
+/**
+ * Automatic actions to take prior to calling the transition's ontransition
+ * function. This is documented in the constructor, and is typically provided
+ * through the constructor's transitionInfo object, but it is also possible
+ * (but highly NOT recommended) to change this dynamically.
+ */
+qx.OO.addProperty(
+ {
+ name : "autoActionsBeforeOntransition",
+ defaultValue : function(fsm, event) { }
+ });
+
+/**
+ * Automatic actions to take immediately after calling the transition's
+ * ontransition function. This is documented in the constructor, and is
+ * typically provided through the constructor's transitionInfo object, but it
+ * is also possible (but highly NOT recommended) to change this dynamically.
+ */
+qx.OO.addProperty(
+ {
+ name : "autoActionsAfterOntransition",
+ defaultValue : function(fsm, event) { }
+ });
+
+
+/**
+ * The function run when the transition is accepted. This is documented in
+ * the constructor, and is typically provided through the constructor's
+ * transitionInfo object, but it is also possible (but highly NOT recommended)
+ * to change this dynamically.
+ */
+qx.OO.addProperty(
+ {
+ name : "ontransition",
+ defaultValue : function(fsm, event) { }
+ });
+
+
+
+
+/*
+---------------------------------------------------------------------------
+ MODIFIER
+---------------------------------------------------------------------------
+*/
+
+qx.Proto._checkName = function(propValue, propData)
+{
+ // Ensure that we got a valid state name
+ if (typeof(propValue) != "string" || propValue.length < 1)
+ {
+ throw new Error("Invalid transition name");
+ }
+
+ return propValue;
+};
+
+qx.Proto._checkPredicate = function(propValue, propData)
+{
+ // Validate the predicate. Convert all valid types to function.
+ switch(typeof(propValue))
+ {
+ case "undefined":
+ // No predicate means predicate passes
+ return function(fsm, event) { return true; };
+
+ case "boolean":
+ // Convert boolean predicate to a function which returns that value
+ return function(fsm, event) { return propValue; };
+
+ case "function":
+ // Use user-provided function.
+ return propValue;
+
+ default:
+ throw new Error("Invalid transition predicate type: " +
+ typeof(propValue));
+ break;
+ }
+};
+
+qx.Proto._checkNextState = function(propValue, propData)
+{
+ // Validate nextState. It must be a string or a number.
+ switch(typeof(propValue))
+ {
+ case "string":
+ return propValue;
+
+ case "number":
+ // Ensure that it's one of the possible state-change constants
+ switch(propValue)
+ {
+ case qx.util.fsm.FiniteStateMachine.StateChange.CURRENT_STATE:
+ case qx.util.fsm.FiniteStateMachine.StateChange.PREVIOUS_STATE:
+ return propValue;
+
+ default:
+ throw new Error("Invalid transition nextState value: " +
+ propValue +
+ ": nextState must be an explicit state name, " +
+ "or one of the Fsm.StateChange constants");
+ }
+ break;
+
+ default:
+ throw new Error("Invalid transition nextState type: " + typeof(propValue));
+ break;
+ }
+};
+
+qx.Proto._checkOntransition = function(propValue, propData)
+{
+ // Validate the ontransition function. Convert undefined to function.
+ switch(typeof(propValue) )
+ {
+ case "undefined":
+ // No provided function just means do nothing. Use a null function.
+ return function(fsm, event) { };
+
+ case "function":
+ // Use user-provided function.
+ return propValue;
+
+ default:
+ throw new Error("Invalid ontransition type: " + typeof(propValue));
+ break;
+ }
+};
+
+/*
+---------------------------------------------------------------------------
+ UTILITIES
+---------------------------------------------------------------------------
+*/
+
+
+/*
+---------------------------------------------------------------------------
+ EVENT LISTENERS
+---------------------------------------------------------------------------
+*/
+
+
+
+/*
+---------------------------------------------------------------------------
+ CLASS CONSTANTS
+---------------------------------------------------------------------------
+*/
+
+
+
+/*
+---------------------------------------------------------------------------
+ DISPOSER
+---------------------------------------------------------------------------
+*/
+
+qx.Proto.dispose = function()
+{
+ if (this.getDisposed()) {
+ return true;
+ }
+
+ return qx.core.Object.prototype.dispose.call(this);
+}
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/example.txt b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/example.txt
new file mode 100644
index 0000000000..bb92f70083
--- /dev/null
+++ b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/util/fsm/example.txt
@@ -0,0 +1,210 @@
+var fsm;
+var state;
+var trans;
+
+// Create a new finite state machine called "Test Machine"
+fsm = new qx.util.finitestatemachine.Fsm("Test machine");
+
+// State S1
+state = new qx.util.finitestatemachine.State(
+ // State name
+ "S1",
+
+ // Object with state information
+ {
+ // Function called on entry to this state
+ "onentry" :
+ function(fsm, event)
+ {
+ alert("Previous state: " + fsm.getPreviousState());
+ };
+
+ // Function called on exit from this state
+ "onexit" :
+ function(fsm, event)
+ {
+ alert("Next state: " + fsm.getNextState());
+ };
+
+ // Automatic actions to take place before a (possibly) new state's onentry
+ // function is called.
+ "autoActionsBeforeOnentry" :
+ {
+ // The name of a function.
+ "setEnabled" :
+ [
+ {
+ // The parameter value(s), thus "setEnabled(true);"
+ "parameters" : [ true ],
+
+ // The function would be called on each object:
+ // this.getObject("obj1").setEnabled(true);
+ // this.getObject("obj2").setEnabled(true);
+ "objects" : [ "obj1", "obj2" ]
+
+ // And similarly for each object in each specified group.
+ "groups" : [ "group1", "group2" ],
+ }
+ ];
+
+ "setColor" :
+ [
+ {
+ "parameters" : [ "blue" ]
+ "groups" : [ "group3", "group4" ],
+ "objects" : [ "obj3", "obj4" ]
+ }
+ ];
+ };
+
+ // also available, in same format as actionsBeforeOnentry:
+ // "actionsAfterOnentry",
+ // "actionsBeforeOnexit"
+ // "actionsAfterOnexit"
+
+ // Events handled by this state, or queued for processing by a future state
+ "events" :
+ {
+ // The event type "compete" is handled by one of the transitions in this
+ // state. The transitions will be searched in order of their addition
+ // to the state, until the predicate for a transition returns true (or
+ // no predicate is specified for the transition, which is an implicit
+ // "true") That transition will be used.
+ "complete" : qx.util.finitestatemachine.Fsm.EventHandling.PREDICATE,
+
+ // The event type "interval" has two objects specified by their
+ // "friendly name". The action when an event of type "interval" occurs
+ // depends on which object was the target of the event.
+ "interval" :
+ {
+ // If the target of the event was the object to which we have given
+ // the friendly name "flash" then use a transition specified by name
+ "flash" : "S1_S3_interval_flash",
+
+ // If the target of the event was the object to which we have given
+ // the friendly name "timeout", then enqueue this event for possible
+ // processing by a future state.
+ "timeout" : qx.util.finitestatemachine.Fsm.EventHandling.BLOCKED
+ },
+
+ // The event type "execute", too, has two objects specified by their
+ // "friendly name".
+ "execute" :
+ {
+ // If the target of the event was the object to which we have given
+ // the friend name "ok", search the transitions in order looking for
+ // one where the predicate is true
+ "ok" : qx.util.finitestatemachine.Fsm.EventHandling.PREDICATE
+
+ // If the target of the event was the object to which we have given
+ // the friendly name "restart", then enqueue this event for possible
+ // processing by a future state.
+ "restart" : qx.util.finitestatemachine.Fsm.EventHandling.BLOCKED
+ }
+
+ // all events other than those which are handled or blocked are ignored.
+ };
+ });
+
+// Add State S1 to the finite state machine.
+fsm.addState(state);
+
+// Transition from S1 to S2 due to event 1
+trans = new qx.util.finitestatemachine.Transition(
+ // Transition name
+ "S1_S2_ev1",
+
+ // Object with transition information
+ {
+ // return TRUE to pass
+ "predicate" :
+ function(fsm, event)
+ {
+ var type = event.getType();
+ if (type == "somethingWeCareAbout")
+ {
+ return true;
+ }
+ else if (type == "somethingToHandleInAnotherState")
+ {
+ // reattempt event delivery following state transition
+ fsm.postponeEvent(event);
+
+ // do no further transition attempts for this event for now
+ return null;
+ }
+ else
+ {
+ return false;
+ }
+ },
+
+ // if event matches and predicate passes, pop the state stack and go to
+ // the state which was found at the top of the stack. States are added to
+ // the state stack by calling fsm.pushState() during a state's onexit
+ // function or by a transition's action function.
+ "nextState" : qx.util.finintestatemachine.Fsm.StateChange.POP_STATE_STACK,
+
+ // action taken during transisition
+ "action" :
+ function(fsm, event)
+ {
+ // save current state so a future transition can get back to
+ // this saved state
+ fsm.pushState();
+ }
+ });
+state.addTransition(trans);
+
+// Default transition (any event): remain in current state
+trans = new qx.util.finitestatemachine.Transition(
+ "S1_S1_default",
+ {
+ // true or undefined : always pass
+ "predicate" :
+ function(fsm, event)
+ {
+ // This predicate does not pass, and we return null to tell the finite
+ // state machine that no additional transitions in the transition list
+ // should be tested. (Note that the next transition is the one
+ // explicitly called for by the "interval" event on the object with
+ // friendly name "flash". We do not want a predicate search to find
+ // it.
+ return null;
+ },
+
+ // return to current state
+ "nextState" : qx.util.finitestatemacine.CURRENT_STATE,
+ });
+state.addTransition(trans);
+
+// Transition from S1 to S2 due to event 2. Since the previous transition
+// returned null in its predicate function, the only way to get to this
+// transition is when it is called out explicitly in the state's event list.
+// This one was specified for the "interval" event on the object with friendly
+// name "flash".
+trans = new qx.util.finitestatememachine.Transition(
+ "S1_S3_interval_flash",
+ {
+ // No predicate or a value of 'true' means that the predicate passes as if
+ // a predicate function returned true.
+ "predicate" : true,
+
+ // if event matches, go to this state
+ "nextState" : "S2",
+
+ // action taken during transisition
+ "action" :
+ function(fsm, event)
+ {
+ alert(this.getName() + "action function");
+ }
+ });
+state.addTransition(trans);
+
+// We would, of course, need to add state S2 since it is specified in a
+// nextState property. That is left as an exercise for the reader.
+
+
+// Initialize and start the machine running
+fsm.start();