summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoonas Lehtinen <joonas.lehtinen@itmill.com>2006-10-12 02:42:33 +0000
committerJoonas Lehtinen <joonas.lehtinen@itmill.com>2006-10-12 02:42:33 +0000
commit041fb2f50011d8a88114197e1af9d9b087811731 (patch)
treef897f874e4c0fb0d63104e6b578cf26e9f2bbc48
parentec177eb8b9b90cc07ba93d5954addbcf696d87ee (diff)
downloadvaadin-framework-041fb2f50011d8a88114197e1af9d9b087811731.tar.gz
vaadin-framework-041fb2f50011d8a88114197e1af9d9b087811731.zip
svn changeset:11/svn branch:toolkit
-rw-r--r--WebContent/META-INF/MANIFEST.MF3
-rw-r--r--WebContent/WEB-INF/web.xml102
-rw-r--r--WebContent/ajax-features.html51
-rw-r--r--WebContent/client/client.js1677
-rw-r--r--WebContent/client/debug.css57
-rw-r--r--WebContent/client/img/off.gifbin0 -> 69 bytes
-rw-r--r--WebContent/client/img/on.gifbin0 -> 70 bytes
-rw-r--r--WebContent/themes/default/calendar-default.css236
-rw-r--r--WebContent/themes/default/img/bg1.gifbin0 -> 416 bytes
-rw-r--r--WebContent/themes/default/img/bg3.jpgbin0 -> 1629 bytes
-rw-r--r--WebContent/themes/default/img/button/btn-bg.gifbin0 -> 866 bytes
-rw-r--r--WebContent/themes/default/img/button/btn-left.gifbin0 -> 1341 bytes
-rw-r--r--WebContent/themes/default/img/button/btn-left.pngbin0 -> 3722 bytes
-rw-r--r--WebContent/themes/default/img/button/btn-right.gifbin0 -> 1342 bytes
-rw-r--r--WebContent/themes/default/img/button/btn-right.pngbin0 -> 3774 bytes
-rw-r--r--WebContent/themes/default/img/debug.gifbin0 -> 288 bytes
-rw-r--r--WebContent/themes/default/img/icon/attention.gifbin0 -> 1641 bytes
-rw-r--r--WebContent/themes/default/img/icon/attention.pngbin0 -> 2613 bytes
-rw-r--r--WebContent/themes/default/img/icon/error-mini.gifbin0 -> 82 bytes
-rw-r--r--WebContent/themes/default/img/icon/error.gifbin0 -> 1538 bytes
-rw-r--r--WebContent/themes/default/img/icon/info-mini.gifbin0 -> 509 bytes
-rw-r--r--WebContent/themes/default/img/icon/info.gifbin0 -> 1641 bytes
-rw-r--r--WebContent/themes/default/img/panel/bottom-left.gifbin0 -> 724 bytes
-rw-r--r--WebContent/themes/default/img/panel/bottom-right.gifbin0 -> 237 bytes
-rw-r--r--WebContent/themes/default/img/panel/bottom.gifbin0 -> 52 bytes
-rw-r--r--WebContent/themes/default/img/panel/middle-light.gifbin0 -> 280 bytes
-rw-r--r--WebContent/themes/default/img/panel/middle.gifbin0 -> 62 bytes
-rw-r--r--WebContent/themes/default/img/panel/top-left-light.gifbin0 -> 1780 bytes
-rw-r--r--WebContent/themes/default/img/panel/top-left.gifbin0 -> 1114 bytes
-rw-r--r--WebContent/themes/default/img/panel/top-right-light.gifbin0 -> 452 bytes
-rw-r--r--WebContent/themes/default/img/panel/top-right.gifbin0 -> 291 bytes
-rw-r--r--WebContent/themes/default/img/panel/top.gifbin0 -> 70 bytes
-rw-r--r--WebContent/themes/default/img/table/asc.gifbin0 -> 70 bytes
-rw-r--r--WebContent/themes/default/img/table/bottom-left.gifbin0 -> 987 bytes
-rw-r--r--WebContent/themes/default/img/table/bottom-right.gifbin0 -> 818 bytes
-rw-r--r--WebContent/themes/default/img/table/caption-bg.gifbin0 -> 151 bytes
-rw-r--r--WebContent/themes/default/img/table/caption-left.gifbin0 -> 653 bytes
-rw-r--r--WebContent/themes/default/img/table/caption-right.gifbin0 -> 651 bytes
-rw-r--r--WebContent/themes/default/img/table/col-header-bg.gifbin0 -> 100 bytes
-rw-r--r--WebContent/themes/default/img/table/colsel.gifbin0 -> 70 bytes
-rw-r--r--WebContent/themes/default/img/table/desc.gifbin0 -> 69 bytes
-rw-r--r--WebContent/themes/default/img/table/handle.gifbin0 -> 43 bytes
-rw-r--r--WebContent/themes/default/img/table/off.gifbin0 -> 69 bytes
-rw-r--r--WebContent/themes/default/img/table/on.gifbin0 -> 70 bytes
-rw-r--r--WebContent/themes/default/img/table/test.gifbin0 -> 10828 bytes
-rw-r--r--WebContent/themes/default/img/table/top-left.gifbin0 -> 224 bytes
-rw-r--r--WebContent/themes/default/img/table/top-right.gifbin0 -> 66 bytes
-rw-r--r--WebContent/themes/default/img/tree/empty.gifbin0 -> 55 bytes
-rw-r--r--WebContent/themes/default/img/tree/off.gifbin0 -> 69 bytes
-rw-r--r--WebContent/themes/default/img/tree/on.gifbin0 -> 70 bytes
-rw-r--r--WebContent/themes/default/img/w2x2.gifbin0 -> 35 bytes
-rw-r--r--WebContent/themes/default/jscalendar/calendar-blue.css232
-rw-r--r--WebContent/themes/default/jscalendar/calendar-blue2.css236
-rw-r--r--WebContent/themes/default/jscalendar/calendar-brown.css225
-rw-r--r--WebContent/themes/default/jscalendar/calendar-green.css229
-rw-r--r--WebContent/themes/default/jscalendar/calendar-setup.js200
-rw-r--r--WebContent/themes/default/jscalendar/calendar-setup_stripped.js21
-rw-r--r--WebContent/themes/default/jscalendar/calendar-system.css251
-rw-r--r--WebContent/themes/default/jscalendar/calendar-tas.css239
-rw-r--r--WebContent/themes/default/jscalendar/calendar-win2k-1.css271
-rw-r--r--WebContent/themes/default/jscalendar/calendar-win2k-2.css271
-rw-r--r--WebContent/themes/default/jscalendar/calendar-win2k-cold-1.css265
-rw-r--r--WebContent/themes/default/jscalendar/calendar-win2k-cold-2.css271
-rw-r--r--WebContent/themes/default/jscalendar/calendar.js1806
-rw-r--r--WebContent/themes/default/jscalendar/calendar_stripped.js14
-rw-r--r--WebContent/themes/default/jscalendar/dayinfo.html109
-rw-r--r--WebContent/themes/default/jscalendar/img.gifbin0 -> 223 bytes
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-af.js39
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-al.js101
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-bg.js124
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-big5-utf8.js123
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-big5.js123
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-br.js108
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-ca.js123
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-cs-utf8.js65
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-cs-win.js65
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-da.js123
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-de.js124
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-du.js45
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-el.js89
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-en.js127
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-es.js129
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-fi.js109
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-fr.js125
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-he-utf8.js123
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-hr-utf8.js49
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-hr.jsbin0 -> 3088 bytes
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-hu.js124
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-it.js124
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-jp.js45
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-ko-utf8.js120
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-ko.js120
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-lt-utf8.js114
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-lt.js114
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-lv.js123
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-nl.js73
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-no.js114
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-pl-utf8.js93
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-pl.js56
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-pt.js123
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-ro.js66
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-ru.js123
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-ru_win_.js123
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-si.js94
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-sk.js99
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-sp.js110
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-sv.js113
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-tr.js58
-rw-r--r--WebContent/themes/default/jscalendar/lang/calendar-zh.js119
-rw-r--r--WebContent/themes/default/jscalendar/lang/cn_utf8.js123
-rw-r--r--WebContent/themes/default/theme.css803
-rw-r--r--WebContent/themes/default/theme.js4119
-rw-r--r--WebContent/themes/example/example_styles.css0
-rw-r--r--WebContent/themes/example/example_theme.js80
-rw-r--r--WebContent/themes/playground/components.html227
-rw-r--r--WebContent/themes/playground/default.css238
-rw-r--r--WebContent/themes/playground/img/bg1.gifbin0 -> 416 bytes
-rw-r--r--WebContent/themes/playground/img/bg2.gifbin0 -> 215 bytes
-rw-r--r--WebContent/themes/playground/img/bg3.jpgbin0 -> 1629 bytes
-rw-r--r--WebContent/themes/playground/img/tree/off.gifbin0 -> 69 bytes
-rw-r--r--WebContent/themes/playground/img/tree/on.gifbin0 -> 70 bytes
-rw-r--r--WebContent/themes/playground/table-prototypes/aquaHeaderIcon.gifbin0 -> 582 bytes
-rw-r--r--WebContent/themes/playground/table-prototypes/table-proto-firefox.html88
-rw-r--r--WebContent/themes/playground/table-prototypes/table-proto-ie.html40
-rw-r--r--WebContent/themes/playground/table-prototypes/table-proto-safari.html69
125 files changed, 16715 insertions, 0 deletions
diff --git a/WebContent/META-INF/MANIFEST.MF b/WebContent/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..5e9495128c
--- /dev/null
+++ b/WebContent/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path:
+
diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml
new file mode 100644
index 0000000000..4ea9a0754e
--- /dev/null
+++ b/WebContent/WEB-INF/web.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+ <display-name>
+ itmill-toolkit</display-name>
+
+
+ <servlet>
+ <servlet-name>web</servlet-name>
+ <servlet-class>org.millstone.webadapter.WebAdapterServlet</servlet-class>
+ <init-param>
+ <param-name>application</param-name>
+ <param-value>com.itmill.ajaxadapter.test.TestApplication</param-value>
+ </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name>ajax</servlet-name>
+ <servlet-class>com.itmill.millstone.ajaxadapter.AjaxAdapterServlet</servlet-class>
+ <init-param>
+ <param-name>application</param-name>
+ <param-value>com.itmill.ajaxadapter.test.TestApplication</param-value>
+ </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name>web-features</servlet-name>
+ <servlet-class>org.millstone.webadapter.WebAdapterServlet</servlet-class>
+ <init-param>
+ <param-name>application</param-name>
+ <param-value>com.itmill.ajaxadapter.test.features.FeaturesApplication</param-value>
+ </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name>ajax-features</servlet-name>
+ <servlet-class>com.itmill.millstone.ajaxadapter.AjaxAdapterServlet</servlet-class>
+ <init-param>
+ <param-name>application</param-name>
+ <param-value>com.itmill.ajaxadapter.test.features.FeaturesApplication</param-value>
+ </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name>demo-table</servlet-name>
+ <servlet-class>org.millstone.webadapter.WebAdapterServlet</servlet-class>
+ <init-param>
+ <param-name>application</param-name>
+ <param-value>com.itmill.millstone.ajaxadapter.demo.table.TableDemoApplication</param-value>
+ </init-param>
+ </servlet>
+
+ <servlet>
+ <servlet-name>ajaxdemo-table</servlet-name>
+ <servlet-class>com.itmill.millstone.ajaxadapter.AjaxAdapterServlet</servlet-class>
+ <init-param>
+ <param-name>application</param-name>
+ <param-value>com.itmill.millstone.ajaxadapter.demo.table.TableDemoApplication</param-value>
+ </init-param>
+ </servlet>
+
+ <!-- Namespace mappings for servlets -->
+
+ <servlet-mapping>
+ <servlet-name>web</servlet-name>
+ <url-pattern>/web/*</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>ajax</servlet-name>
+ <url-pattern>/ajax/*</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>web-features</servlet-name>
+ <url-pattern>/web-features/*</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>ajax-features</servlet-name>
+ <url-pattern>/ajax-features/*</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>demo-table</servlet-name>
+ <url-pattern>/table/*</url-pattern>
+ </servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>ajaxdemo-table</servlet-name>
+ <url-pattern>/ajax-table/*</url-pattern>
+ </servlet-mapping>
+
+
+ <welcome-file-list>
+ <welcome-file>index.html</welcome-file>
+ <welcome-file>index.htm</welcome-file>
+ <welcome-file>index.jsp</welcome-file>
+ <welcome-file>default.html</welcome-file>
+ <welcome-file>default.htm</welcome-file>
+ <welcome-file>default.jsp</welcome-file>
+ </welcome-file-list>
+</web-app>
diff --git a/WebContent/ajax-features.html b/WebContent/ajax-features.html
new file mode 100644
index 0000000000..31cd467bfa
--- /dev/null
+++ b/WebContent/ajax-features.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+ <head>
+ <title>Millstone Ajax Client </title>
+
+ <!-- These are the "DefaultTheme" related CSS and JS files -->
+ <script src="client/client.js" type="text/javascript"></script>
+ <script type="text/javascript" src="themes/default/theme.js"></script>
+ <script type="text/javascript" src="themes/default/jscalendar/calendar.js"></script>
+ <script type="text/javascript" src="themes/default/jscalendar/lang/calendar-en.js"></script>
+ <script type="text/javascript" src="themes/default/jscalendar/calendar-setup.js"></script>
+ <link rel="stylesheet" media="screen, projection" href="themes/default/calendar-default.css" type="text/css" />
+ <link rel="stylesheet" media="screen, projection" href="themes/default/theme.css" type="text/css" />
+
+ <!-- These are the "ExampleTheme" related CSS and JS files -->
+ <script type="text/javascript" src="themes/example/example_theme.js"></script>
+ <link rel="stylesheet" media="screen, projection" href="themes/example/example_styles.css" type="text/css" />
+
+ </head>
+
+ <body>
+ <DIV id="ajax-wait" class="outset" style="top:4px;right:4px;cursor:wait;z-index:10000;background:white;display:none;position:absolute;">
+ <DIV class="border pad">Loading...</DIV>
+ </DIV>
+ <div class="window" id="ajax-window" style=""></div>
+ <script language="JavaScript">
+ var baseUrl = document.location.href.split("ajax-features.html")[0];
+
+ // Create ajax-client for the application
+ var client = new MillstoneAjaxClient(
+ document.getElementById('ajax-window'),
+ baseUrl + "ajax-features/",
+ baseUrl + "client/",
+ document.getElementById('ajax-wait'));
+ client.debugEnabled = (document.location.href.indexOf("debug")>0);
+
+ // Create the default theme and register the theme to the ajax-client
+ var defaultTheme = new DefaultTheme(baseUrl + "themes/default/");
+ defaultTheme.registerTo(client);
+
+ var exampleTheme = new ExampleTheme(baseUrl + "themes/example/",defaultTheme);
+ exampleTheme.registerTo(client);
+
+ // Start the client
+ client.start();
+
+ </script>
+ </body>
+ </html>
+ \ No newline at end of file
diff --git a/WebContent/client/client.js b/WebContent/client/client.js
new file mode 100644
index 0000000000..0c2266ffd9
--- /dev/null
+++ b/WebContent/client/client.js
@@ -0,0 +1,1677 @@
+
+/** Creates new Millstone ajax client.
+ * @param windowElementNode Reference to element that will contain the
+ * application window.
+ * @param servletUrl Base URL to server-side ajax adapter.
+ * @param clientRoot Base URL to client-side ajax adapter resources.
+ * @constructor
+ *
+ * @author Oy IT Mill Ltd / Sami Ekblad
+ */
+function MillstoneAjaxClient(windowElementNode, servletUrl, clientRoot, waitElement) {
+
+ // Store parameters
+ this.mainWindowElement = windowElementNode;
+ if (this.mainWindowElement == null) {
+ alert("Invalid window element. Ajax client not properly initialized.");
+ }
+ this.millstoneMainWindow = window;
+
+ this.ajaxAdapterServletUrl = servletUrl;
+ if (this.ajaxAdapterServletUrl == null) {
+ alert("Invalid servlet URL. Ajax client not properly initialized.");
+ }
+
+ // Wait element is shown during the ajax requests
+ this.waitElement = waitElement;
+
+ // Root of the client scripts
+ if (clientRoot == null)
+ this.clientRoot = "";
+ else (clientRoot.length > 0)
+ this.clientRoot = clientRoot + (clientRoot.match('/$') ? "" : "/" );
+
+ // Debugging is disabled by default
+ this.debugEnabled = false;
+
+ // Initialize variableChangeQueue
+ this.variableStates = new Object();
+
+ // Create empty renderers list
+ this.renderers = new Object();
+
+ // Create windows list
+ this.documents = new Object();
+ this.windows = new Object();
+
+ // Remove all eventListeners on window.unload
+ with (this) {
+ addEventListener(window,"unload", function () {
+ var removed = removeAllEventListeners(document);
+ if (window.eventMap) {
+ for (var t in window.eventMap) {
+ var i = window.eventMap[t].length;
+ while (i--) {
+ client.removeEventListener(window,t,window.eventMap[t][i]);
+ removed++;
+ }
+ }
+ window.eventMap = null;
+ }
+
+ // FIXME remove
+ //alert("Removed " + removed + " event listeners.");
+ warn("Removed " + removed + " event listeners.");
+ //warn("Removed " + removeAllEventListeners(window) + " event listeners.");
+ // TODO close all windows
+ warn("Removed " + unregisterAllLayoutFunctions()+ " layout functions.");
+
+ window.png = null;
+ });
+ var client = this;
+ var func = function() {
+ client.resizeTimeout=null;
+ client.processAllLayoutFunctions()
+ };
+
+ addEventListener(window,"resize", function () {
+ if (client.resizeTimeout) clearTimeout(client.resizeTimeout);
+ client.resizeTimeout = setTimeout(func,500);
+ });
+
+ }
+
+ window.png = function(img) {
+ var ua = navigator.userAgent.toLowerCase();
+ if (ua.indexOf("windows")<0) return;
+ var msie = ua.indexOf("msie");
+ if (msie < 0) return;
+ var v = parseInt(ua.substring(msie+5,msie+6));
+ if (!v || v < 5 || v > 6) return;
+
+ var src = img.src;
+ var w = img.width;
+ var h = img.height;
+
+ if (src && src.indexOf("pixel.gif")>0) return;
+
+ img.onload = null;
+ img.src = clientRoot + "pixel.gif";
+ img.style.height = h+"px";
+ img.style.width = w+"px";
+ img.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+src+"', sizingMethod='crop');";
+ }
+
+}
+
+/** Start the ajax client.
+ * Creates debug window and sends the initial request to server.
+ *
+ * @author Oy IT Mill Ltd / Sami Ekblad
+ */
+MillstoneAjaxClient.prototype.start = function() {
+
+ if (this.debugEnabled) {
+ this.debug("Starting Ajax client");
+ }
+
+ // Send initial request
+ this.processVariableChanges(true);
+}
+
+
+
+/** Creates new debug window.
+ *
+ * @return New debug window instance.
+ * @type Window
+ * @private
+ *
+ * @author Oy IT Mill Ltd / Sami Ekblad
+ */
+MillstoneAjaxClient.prototype.createDebugWindow = function() {
+
+ var dw = window.open("","MillstoneAjaxDebugWindow","width=500,height=700,scrollbars=1,menubar=0,status=0,titlebar=0,toolbar=0,resizable=1");
+ if (dw != null) {
+ with (dw.document) {
+
+ if (dw.document.body != null) {
+ dw.document.body.innerHTML = "";
+ }
+
+ write("<html><head>");
+ write("<title>Millstone Ajax Adapter Debug</title>");
+ write("<link rel=\"stylesheet\" href=\""+this.clientRoot+"debug.css\" type=\"text/css\" >");
+ write("</head>");
+ write("<body><h2>Debug</h2>");
+ write("</body></html>\n");
+ }
+ } else {
+ return null;
+ }
+ return dw;
+}
+
+
+MillstoneAjaxClient.prototype.warn = function (message, folded, extraStyle, html) {
+
+ // Check if we are in debug mode
+ if (!this.debugEnabled) { return; }
+
+ this.debug(message, folded, "warn "+(extraStyle?extraStyle:""), html);
+}
+/** Write debug message to debug window.
+ *
+ * @param message The message to be written
+ * @param folded True if the message should be foldable and folded to default,
+ * false or missing otherwise.
+ *
+ * @author Oy IT Mill Ltd / Sami Ekblad
+ *
+ */
+MillstoneAjaxClient.prototype.debug = function (message, folded, extraStyle, html) {
+
+ // Check if we are in debug mode
+ if (!this.debugEnabled) { return; }
+
+ // Ensure we have a debug window
+ if (this.debugwindow == null) {
+ this.debugwindow = this.createDebugWindow();
+ }
+
+ // If window is closed disable debug
+ if (this.debugwindow.closed) {
+ alert("Debug window closed. Disabling debug.\n Press reload to re-enable debug window.");
+ this.debugEnabled = false;
+ return;
+ }
+
+ // Apply the extra style given
+ if (extraStyle != null) {
+ extraStyle = " "+extraStyle;
+ } else {
+ extraStyle = "";
+ }
+
+ // Use folded or normal view
+ if (folded) {
+ this.debugwindow.document.write("<div onclick=\"if (this.className == 'folded"+extraStyle+"') this.className = 'unfolded"+extraStyle+"'; else this.className = 'folded"+extraStyle+"';\" class='folded"+extraStyle+"'>");
+ } else {
+ this.debugwindow.document.write("<div class='normal"+extraStyle+"'>");
+ }
+
+ // Print out as html or as preformatted
+ if (html) {
+ this.debugwindow.document.write(message);
+ } else {
+ this.debugwindow.document.write("<xmp>"+message+"</xmp>");
+ }
+ this.debugwindow.document.write("</div>");
+
+ // Scroll to end
+ this.debugwindow.document.write("<script>window.scrollTo(0,document.body.scrollHeight);</script>");
+}
+
+/** Write object properties to debug window.
+ *
+ * @param obj The object that is debugged.
+ * @param level The recursion level that the properties are inspected.
+ *
+ * @author Oy IT Mill Ltd / Sami Ekblad
+ *
+ */
+MillstoneAjaxClient.prototype.debugObject = function (obj,level) {
+ this.debug(this.printObject(obj,level),true,null,true);
+}
+
+/** Write error message to debug window.
+ *
+ * @param message The message to be written
+ * @param causeException Exception that caused this error.
+ *
+ * @author Oy IT Mill Ltd / Sami Ekblad
+ *
+ */
+MillstoneAjaxClient.prototype.error = function (message, causeException) {
+
+ // Check if we are in debug mode
+ if (!this.debugEnabled) { return; }
+
+ if (causeException != null) {
+ // If filename and line number is avaiable, append to output.
+ if (causeException.fileName != null) {
+ message += "\n\n FILE= '"
+ + causeException.fileName +"'"
+ + (causeException.lineNumber != null ?
+ " LINE="+causeException.lineNumber:
+ "");
+ }
+
+ // If stack trace is available, append it to output.
+ if (causeException.stack != null) {
+ message += "\n\n" + causeException.stack;
+ }
+
+ // Dump all exception properties
+ message += "\n\nException properties:\n";
+ for (var prop in causeException) {
+ if (prop != "stack") {
+ message += " " + prop + "=" +causeException[prop] + "\n";
+ }
+ }
+ }
+ this.debug(message,causeException != null, "error");
+
+}
+
+/** Creates new XMLHttpRequest object.
+ *
+ * NOTE: The return type of this function is platform dependent.
+ *
+ * @return New XMLHttpRequest or XMLHTTP (ActiveXObject) instance
+ * @type XMLHttpRequest | ActiveXObject
+ *
+ * @author Oy IT Mill Ltd / Sami Ekblad
+ */
+MillstoneAjaxClient.prototype.getXMLHttpRequest = function () {
+
+ var req = false;
+
+ if(window.XMLHttpRequest) {
+
+ // Native XMLHttpRequest object
+ try {
+ req = new XMLHttpRequest();
+ } catch(e) {
+ req = false;
+ }
+
+ } else if(window.ActiveXObject) {
+
+ // IE/Windows ActiveX version
+ try {
+ req = new ActiveXObject("Msxml2.XMLHTTP");
+ } catch(e) {
+ try {
+ req = new ActiveXObject("Microsoft.XMLHTTP");
+ } catch(e) {
+ req = false;
+ }
+ }
+ }
+ return req;
+}
+
+/** Loads a document using XMLHttpRequest object and returns it as text.
+ *
+ * @param url The URL of document.
+ * @skipCache If true, does not use cached documents (or cache this result).
+ *
+ * @author Oy IT Mill Ltd / Sami Ekblad
+ *
+ */
+MillstoneAjaxClient.prototype.loadDocument = function (url,skipCache) {
+
+ if (!skipCache) {
+ if (!this.loadcache) this.loadcache = new Object();
+ var cached = this.loadcache["_"+url];
+ if (cached != null) {
+ this.debug(url + " loaded from cache.");
+ return cached;
+ }
+ }
+
+ var x = this.getXMLHttpRequest();
+ x.open("GET",url, false);
+ x.send(null);
+ var response = x.responseText;
+ if (x.status != 200) {
+ this.error("Could not load (status 200) " + url);
+ return null;
+ }
+ delete x;
+
+ if (!skipCache) {
+ this.loadcache["_"+url] = response;
+ }
+
+ if (response) {
+ this.debug(url + " loaded.");
+ } else {
+ this.debug("Could not load " + url);
+ }
+ return response;
+}
+
+
+/** Registers new renderer function to ajax client.
+ *
+ * @param theme Theme instance where the renderer belongs to.
+ * @param tag UIDL Tag-name that this renderer supports.
+ * @param componentStyle The style attribute of component that this renderer supports.
+ * @param renderFunction Function that is performs the rendering of the UIDL.
+ * @return Newly created renderer object instance.
+ * @type Object
+ *
+ * @author Oy IT Mill Ltd / Sami Ekblad
+ *
+ */
+MillstoneAjaxClient.prototype.registerRenderer = function (theme, tag, componentStyle, renderFunction) {
+
+ if (renderFunction == null) {
+ alert("Theme error: Invalid renderer function registered for '"+tag+(componentStyle == null ? "" : "." + componentStyle)+"'");
+ }
+
+ // Find previous (parent) renderer
+ var parentRenderer = this.findRenderer(tag,componentStyle);
+
+ // Create new renderer information object
+ var renderer = new Object;
+ renderer.match = tag + (componentStyle == null ? "" : "__" + componentStyle);
+ renderer.doc = document;
+ renderer.client = this;
+ renderer.theme = theme;
+ renderer.tag = tag;
+ renderer.componentStyle = componentStyle;
+ renderer.renderFunction = renderFunction;
+ renderer.parentRenderer = parentRenderer;
+
+ // This replaces the previous (parent) renderer
+ this.renderers[renderer.match] = renderer;
+
+ // We return the created renderer object
+ this.debug("Registered renderer for "+tag +(componentStyle == null ? "" : " (" + componentStyle+")")+"");
+ return renderer;
+
+}
+
+
+/** Unregisters all renderers in client.
+ *
+ * @author Oy IT Mill Ltd / Sami Ekblad
+ *
+ */
+MillstoneAjaxClient.prototype.unregisterAllRenderers = function () {
+
+ // We just create new, empty rederer map.
+ this.renderers = new Object();
+
+}
+
+/** Create new response listener for the HTTPRequest object.
+ * This creates new function reference that is used to
+ * process the server response in httpRequest.onreadystatechange.
+ *
+ * @param client Reference to this client instance.
+ *
+ * @author Oy IT Mill Ltd / Sami Ekblad
+ *
+ */
+MillstoneAjaxClient.prototype.createRequestChangeListener = function(client, req) {
+
+ return (function() {
+ if (req.readyState != 4 || req.status == null) {
+ return;
+ }
+
+ // Check status code
+ if (req.status != 200) {
+ alert("Server request failed: ("+req.status+", "+req.statusText+")");
+ req.onreadystatechange = new Function();
+ delete req;
+ return;
+ }
+
+ // Get updates
+ var updates = req.responseXML;
+ if (updates == null) {
+ alert("Server did not return anything: ");
+ req.onreadystatechange = new Function();
+ delete req;
+ return;
+ }
+
+ // Debug request load time
+ if (client.debugEnabled) {
+ var loadedTime = (new Date()).getTime();
+ client.debug("UIDL loaded in " + (loadedTime-client.requestStartTime) + "ms");
+ client.debug("UIDL Changes: \n"+req.responseText,true);
+ }
+
+ // Clean up
+ client.variableStates = new Object();
+ req.onreadystatechange = new Function();
+ delete req;
+
+ // Process the updates
+ try {
+ if (updates.normalize) updates.normalize();
+ } catch (e) {
+ if (client.debugEnabled) {
+ client.debug("normalize() FAILED");
+ }
+ }
+ client.processUpdates(updates);
+ client.requestStartTime = -1;
+
+ });
+
+}
+
+/** Send pending variable changes to server.
+ *
+ * This function sends all pending (non-immediate) variable changes to the
+ * server and registers callback to render process the server response.
+ *
+ * @paran repaintAll True if full window UIDL should be requested from server.
+ *
+ * @author Oy IT Mill Ltd / Sami Ekblad
+ *
+ */
+MillstoneAjaxClient.prototype.processVariableChanges = function (repaintAll) {
+
+ if (this.waitElement) {
+ this.waitElement.style.display = "inline";
+ }
+
+ // Request start time
+ this.requestStartTime = (new Date()).getTime();
+
+ // Build variable change query string
+ var changes = "";
+ for (var i in this.variableStates) {
+ changes += i + "=" + this.variableStates[i] + "&";
+ }
+
+ // Build up request URL
+ var url = this.ajaxAdapterServletUrl + (repaintAll ? "?repaintAll=1" : "?") + "&requestid=" +this.requestStartTime;
+
+ // Run the HTTP request
+ this.debug("Send variable changes: " + url);
+ var activeRequest = this.getXMLHttpRequest();
+ // Create callback for request state changes
+ var changeListener = this.createRequestChangeListener(this,activeRequest);
+ activeRequest.onreadystatechange = changeListener;
+ activeRequest.open("POST",url, true);
+ activeRequest.setRequestHeader('Content-Type',
+ 'application/x-www-form-urlencoded')
+ activeRequest.send(changes);
+
+}
+
+/** Get first child element in given parent.
+ *
+ * @param parent The parent element
+ *
+ * @author Oy IT Mill Ltd / Sami Ekblad
+ *
+ */
+MillstoneAjaxClient.prototype.getFirstChildElement = function (parent) {
+ /*
+ if (parent == null || parent.childNodes == null) {
+ return null;
+ }
+ for (var j=0; j<parent.childNodes.length; j++) {
+ var n = parent.childNodes.item(j);
+ if (n.nodeType == Node.ELEMENT_NODE) {
+ return n;
+ }
+ }
+ */
+ try {
+ var child = parent.firstChild;
+ while (child) {
+ if (child.nodeType == Node.ELEMENT_NODE) {
+ return child;
+ }
+ child = child.nextSibling;
+ }
+ } catch (e) {
+ }
+
+ return null;
+
+
+}
+
+
+/** Initializes new window.
+ * Creates a document element and initializes it to
+ * to contain a window component.
+ *
+ * @param win The window to be initialized.
+ * @param name Millstone name of the window to be initialized.
+ * @return reference to div in document that should contain the window.
+ * @author Oy IT Mill Ltd / Sami Ekblad
+ *
+ */
+MillstoneAjaxClient.prototype.initializeNewWindow = function (win,uidl,theme) {
+
+ if (win == null) {
+ return null;
+ }
+
+ // Special handling for framewindows
+ var framewindow = uidl.nodeName == "framewindow";
+ var name = uidl.getAttribute("name");
+ var caption = uidl.getAttribute("caption")||"";
+
+ if (this.debugEnabled) {
+ this.debug("Initializing new "+(framewindow?"frame-":"")+"window '"+name+"' (PID="+uidl.getAttribute("id")+")");
+ }
+
+ // Create HTML content
+ var html="";
+ if (framewindow) {
+ html = this.createFramesetHtml(uidl,theme)
+ } else {
+ html = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><HTML><HEAD id=\"html-head\"><TITLE>"+caption+"</TITLE></HEAD>"+"<BODY STYLE=\" overflow: hidden; border: none; margin: 0px; padding: 0px;\"><div id=\"millstone-window\" class=\"window\"></div><\/BODY><\/HTML>";
+ }
+ win.document.open();
+ win.document.write(html);
+ win.document.close();
+ win.document.ownerWindow = win;
+ win.document.renderUIDL = function(uidl,currentNode) {
+ this.client.renderUIDL(uidl,currentNode);
+ }
+ win.document.client = this;
+ with (this) {
+ addEventListener(win,"unload", function () {
+ try {
+ // TODO detect external url instead?
+ removeAllEventListeners(win.document);
+ removeAllEventListeners(win);
+ unregisterAllLayoutFunctions(win.document);
+ } catch (e) {
+ // IGNORED FIXME
+ }
+ });
+ var client = this;
+ addEventListener(win,"resize", function () {
+ try {
+ // TODO detect external url instead?
+ setTimeout(function() {client.processAllLayoutFunctions()},1);
+ } catch (e) {
+ // IGNORED FIXME
+ }
+ });
+
+ }
+ // Add stylesheets
+ if (!framewindow) {
+ for (var si in this.mainDocument.styleSheets) {
+ var ss = this.mainDocument.styleSheets[si];
+ var nss = win.document.createElement('link');
+ nss.rel = 'stylesheet';
+ nss.type = 'text/css';
+ nss.media = ss.media;
+ nss.href = ss.href;
+ win.document.getElementById('html-head').appendChild(nss);
+ }
+ }
+
+ // Register it to client
+ this.registerWindow(name, win, win.document);
+
+ // Add unregister callback
+ var client = this;
+ win.onunload = function() {
+ client.unregisterWindow(name);
+ win.onunload = null;
+ }
+
+ // Ensure the name
+ win.millstoneWindowName = name;
+
+ // Assign the current node into that window
+ var winElement = win.document.getElementById("millstone-window");
+ if (framewindow) {
+ winElement = win.document.getElementById(uidl.getAttribute("id"));
+ }
+ if (winElement == null && this.debugEnabled) {
+ this.debug("NOTE: Window element not found!");
+ }
+ win.document.millstoneWindowElement = winElement;
+
+
+ if (!win.png) {
+ var clientRoot = this.clientRoot;
+ // PNG loading support in IE
+ win.png = function(img) {
+ var ua = navigator.userAgent.toLowerCase();
+ if (ua.indexOf("windows")<0) return;
+ var msie = ua.indexOf("msie");
+ if (msie < 0) return;
+ var v = parseInt(ua.substring(msie+5,msie+6));
+ if (!v || v < 5 || v > 6) return;
+
+ var src = img.src;
+ var w = img.width;
+ var h = img.height;
+
+ if (src && src.indexOf(clientRoot+"pixel.gif")>0) return;
+
+ img.onload = null;
+ img.src = clientRoot + "pixel.gif";
+ img.style.height = h+"px";
+ img.style.width = w+"px";
+ img.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+src+"', sizingMethod='crop');";
+ }
+ }
+
+ // Return the content element
+ return winElement;
+}
+
+/** Recursively create frameset html for FrameWindow initialization.
+ *
+ * @param win The window to be initialized.
+ * @param name Millstone name of the window to be initialized.
+ * @return reference to div in document that should contain the window.
+ * @author Oy IT Mill Ltd / Sami Ekblad
+ *
+ */
+MillstoneAjaxClient.prototype.createFramesetHtml = function(uidl,theme) {
+
+ if (uidl == null) {
+ return "";
+ }
+ var cols = uidl.getAttribute("cols");
+ var rows = uidl.getAttribute("rows");
+ var caption = uidl.getAttribute("caption")||"";
+
+ // Open frameset
+ var html = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><html><head><title>"+caption+"</title></head><frameset ";
+ if (cols) {
+ html += "cols=\""+cols+"\"";
+ } else if (rows) {
+ html += "rows=\""+rows+"\"";
+ }
+ html += " id=\""+uidl.getAttribute("id")+"\"";
+ html += " >";
+
+ // Sub-frames / -framesets
+ for (var i=0; i<uidl.childNodes.length; i++) {
+ var n = uidl.childNodes.item(i);
+ if (n.nodeType == Node.ELEMENT_NODE) {
+ if (n.nodeName == "frameset") {
+ html += this.createFramesetHtml(n);
+ } else if (n.nodeName == "frame") {
+ var name =n.getAttribute("name");
+ var src = n.getAttribute("src");
+ html += "<frame id=\""+name+"\" name=\""+name+"\"";
+
+ if (src && src.indexOf("theme://")==0) {
+ src = (theme?theme.root:"themes/") + src.substring(8);
+ html += " src=\""+src+"\" ";
+ }
+
+ html += "/>";
+ }
+ }
+ }
+
+ // Close frameset
+ html += "</frameset></html>";
+ return html;
+}
+
+/** Unregisters and closes a window.
+
+ * @param windowName Name of the window
+ *
+ * @author Oy IT Mill Ltd / Sami Ekblad
+ *
+ */
+MillstoneAjaxClient.prototype.unregisterWindow = function (windowName) {
+ if (this.debugEnabled) {
+ this.debug("Unregistering window '"+windowName+"'");
+ }
+
+ var doc = this.documents[windowName];
+ var win = this.windows[windowName];
+
+ if (doc) {
+ this.documents[windowName] = null;
+ try {
+ //if (win.location) win.location.href = "about:blank";
+ this.windows[windowName] = null;
+ win.close();
+ doc.ownerWindow = null;
+ } catch (e) {
+ if (this.debugEnabled) {
+ this.error("Exception when closing window '"+windowName+"'. Continuing...",e);
+ }
+ }
+ } else if (this.debugEnabled) {
+ this.debug("Failed to unregister '"+windowName+"'. Window not found.");
+ }
+}
+
+/** Registers new window .
+ * This enabled to client update the components by id in this window.
+
+ * @param windowName Name of the window
+ * @param doc The document element of window.
+ *
+ * @author Oy IT Mill Ltd / Sami Ekblad
+ *
+ */
+MillstoneAjaxClient.prototype.registerWindow = function (windowName,win,doc) {
+ if (win != null && doc != null && windowName != null) {
+ doc.millstoneWindowName = windowName;
+ this.documents[windowName] = doc;
+ this.windows[windowName] = win;
+ if (this.debugEnabled) {
+ this.debug("Registered new window '"+windowName+"'");
+ }
+ }
+}
+
+/** Find a paintable by id.
+ * Searcher all windows for given id and returns the element
+ * or null if not found.
+
+ * @param paintableId Id to look for.
+ *
+ * @author Oy IT Mill Ltd / Sami Ekblad
+ *
+ */
+MillstoneAjaxClient.prototype.findPaintableById = function (paintableId) {
+
+ if (this.documents == null) {
+ return null;
+ }
+ for (var name in this.documents) {
+ var d = this.documents[name];
+ var win = this.windows[name];
+
+ try {
+ if (win && win.location && this.millstoneMainWindow.location.href != win.location.href) {
+ // referencing external url, we cannot access, but no problem:
+ // it can't contain the paitable either.
+ if (this.debugEnabled) {
+ this.debug("Window: '"+name+"' referencing external URL and can NOT contain Paintable '"+paintableId+"'");
+ }
+ continue;
+ }
+ } catch (e) {
+ this.debug("Exception while examining window.location, assuming ext url.");
+ continue;
+ }
+
+ try {
+ if (d != null && win && !win.closed) {
+ var el = d.getElementById(paintableId);
+ if (el != null) {
+ if (this.debugEnabled) {
+ var isMain = el.ownerDocument == this.mainDocument? "main":" child";
+ this.debug("Paintable '"+paintableId+"' found in "+isMain+"-window: '"+d.millstoneWindowName+"'");
+ }
+ return el;
+ } else {
+ if (this.debugEnabled) {
+ this.debug("Window: '"+d.millstoneWindowName+"' does NOT contain Paintable '"+paintableId+"'");
+ }
+ }
+ }
+ } catch (e) {
+ if (this.debugEnabled) {
+ this.error("Exception when accessing window '"+name+"'. Closing and continuing...",e);
+ }
+ this.unregisterWindow(name);
+ }
+ }
+ if (this.debugEnabled) {
+ this.debug("Paintable '"+paintableId+"' NOT found in ANY of current windows.");
+ }
+ return null;
+}
+
+/** Process UIDL updates from server.
+ *
+ * Renders user interface changes. The registered renderers
+ * are then used to render the changes to correct location.
+ *
+ * @param updates Updates UIDL updates from server.
+ *
+ * @author Oy IT Mill Ltd / Sami Ekblad
+ *
+ */
+MillstoneAjaxClient.prototype.processUpdates = function (updates) {
+var T = new Date().getTime();
+
+ if (this.debugEnabled) {
+ this.debug("Processing updates.");
+ }
+
+ try {
+ // Iterate through the received changes
+ var changes = updates.getElementsByTagName("change");
+ var cLen = changes.length;
+ for (var i=0; i<cLen; i++) {
+
+ // Render start time
+ var renderStartTime = (new Date()).getTime();
+ var change = changes.item(i);
+ var paintableId = change.getAttribute("pid");
+ var windowName = change.getAttribute("windowname");
+ var invisible = (change.getAttribute("visible") == "false");
+ var changeContent = this.getFirstChildElement(change);
+ invisible = invisible || (changeContent && changeContent.getAttribute("invisible") == "true");
+ var paintableName = (changeContent!= null?changeContent.nodeName:"(unknown)");
+
+ if (this.debugEnabled) {
+ this.debug(" ");
+ this.debug("Change "+i+" Id='"+paintableId+"' Paintable='"+paintableName+"'");
+ }
+
+ // Get the containing element from all current windows
+ var currentNode = this.findPaintableById(paintableId);
+
+ // Use window element by default for windows
+ if (currentNode == null && changeContent != null) {
+
+ if (changeContent.nodeName == "window" || changeContent.nodeName == "framewindow") {
+ var winName = changeContent.getAttribute("name");
+
+ if (this.mainDocument == null) {
+ // Initialize the main document/window
+ currentNode = this.mainWindowElement;
+ currentNode.ownerDocument.ownerWindow = window;
+ this.registerWindow(winName, window, currentNode.ownerDocument);
+ this.mainDocument = currentNode.ownerDocument;
+ this.mainDocument.isMainDocument = "true";
+ } else {
+ // Open a new window if no document was found
+ var limit = new Date().getTime() + (1000*3);
+ var win = window.open("about:blank",winName);
+ while (new Date().getTime() < limit) {
+ try {
+ var url = win.location.href;
+ break;
+ } catch (e) {
+ // IE slow sometimes, buzy-loop for permission ( TODO better solution? )
+ this.debug("Permission denied for window "+winName+", retrying.");
+ }
+ }
+ try {
+ var url = win.location.href;
+ } catch (e) {
+ alert("Could not open window.");
+ win = window.open("about:blank",winName);
+ }
+
+ currentNode = this.initializeNewWindow(win,changeContent);
+ }
+ }
+ }
+
+ if (currentNode != null) {
+
+ if (invisible) {
+ //alert("invisible");
+ // Special hiding procesedure for windows
+ if (windowName != null) {
+ this.unregisterWindow(windowName);
+ } else {
+ // Hide invisble components
+ currentNode.style.display = "none";
+ }
+
+ } else {
+ // Make sure we are visible
+ if (currentNode.style) currentNode.style.display = "";
+ }
+
+
+ // Process all uidl nodes inside a change
+ var uidl = change.firstChild;
+ while (uidl) {
+ //var clen = change.childNodes.length;
+ //for (var j=0; j<clen; j++) {
+
+ //var uidl = change.childNodes.item(j);
+ if (uidl.nodeType == Node.ELEMENT_NODE) {
+
+ // Replace the contents of the current representation
+ // Create empty div for rendering
+
+ /* Render method 2 code
+ var newNode = this.createPaintableElement(uidl);
+
+ // Swap the old one with new one
+ if (currentNode.parentNode != null) {
+ var parent = currentNode.parentNode;
+ parent.replaceChild(newNode,currentNode);
+ newNode.id = paintableId;
+ // TODO working:
+ var removed = this.removeAllEventListeners(currentNode);
+
+
+ // Render to target div
+ this.renderUIDL(uidl,newNode,null,currentNode);
+ delete currentNode;
+ }
+ */
+
+
+ if (!currentNode) {
+ currentNode = this.createPaintableElement(uidl);
+ }
+ this.warn("Removed " + this.removeAllEventListeners(currentNode) + " event listeners.");
+ this.warn("Removed " + this.unregisterAllLayoutFunctions(currentNode) + " layout functions.");
+ if (currentNode.ownerDocument.renderUIDL) {
+ currentNode.ownerDocument.renderUIDL(uidl,currentNode);
+ } else {
+ this.renderUIDL(uidl,currentNode);
+ }
+ }
+ uidl = uidl.nextSibling;
+ }
+ } else {
+ this.error("Change " + i +" node not found. Id='"+ paintableId+ "'. Paintable='"+ paintableName+"'");
+ }
+
+ if (this.debugEnabled) {
+ var renderEndTime = (new Date()).getTime();
+ this.debug("Change " + i + " Id='"+ paintableId+ "'. Paintable='"+ paintableName +"' rendered in " + (renderEndTime-renderStartTime) + "ms");
+ }
+ }
+ } catch (e) {
+ // Print out the exception
+ if (this.debugEnabled) {
+ this.error("Could not process changes: "+e.message,e);
+ } else {
+ alert("Failed to process all changes. \n Please enable debug logging to get detailed error description");
+ }
+ }
+
+ this.processAllLayoutFunctions();
+
+ var endTime = (new Date()).getTime();
+ if (this.debugEnabled && this.requestStartTime > 0 ) {
+ this.debug("Total time for update " + (endTime-this.requestStartTime) + "ms");
+ }
+ if (this.waitElement) {
+ this.waitElement.style.display = "none";
+ }
+
+// FIXME REMOVE
+//alert("EventListeners:" + document.eventListenerCount +"\nTotal ms: " + (new Date().getTime() -T));
+}
+
+/** Render the given UIDL to target.
+ *
+ * If no renderer is specified the the internal renderer registry is
+ * looked up for matching renderer.
+ *
+ * @param uidl The UIDL node that is rendered.
+ * @param target The targer element where the result should be appended.
+ * @param renderer The specific renderer instance that should be used (optional)
+ * @return This function returns whatever the utilized renderer returns.
+ *
+ * @author Oy IT Mill Ltd / Sami Ekblad
+ *
+ */
+MillstoneAjaxClient.prototype.renderUIDL = function (uidl, target, renderer) {
+
+ // Sanity check
+ if (uidl == null || uidl.nodeType != Node.ELEMENT_NODE) return;
+
+ // Render the UIDL using the given renderer
+ if (renderer != null) {
+
+ // Invoke renderer and return whatever it returns.
+
+ // Function argument pass-through:
+ // Create arguments array and add all callers extra parameters
+ // to the end of arguments.
+ var args = new Array();
+ args[args.length] = renderer;
+ args[args.length] = uidl;
+ args[args.length] = target;
+ for(var i=3; i<arguments.length; i++) {
+ args[args.length] = arguments[i];
+ }
+ if (this.debugEnabled) {
+ this.debug("Theme '"+ renderer.theme.themeName + "' rendering '"+ uidl.nodeName + "' into '"+target.nodeName+"' (id="+target.id+")");
+ }
+ try {
+ var res = renderer.renderFunction.apply(this,args);
+ return res;
+ } catch (e) {
+ // Print out the exception
+ this.error("Could not render "+ uidl.nodeName +" using '"+ renderer.theme.themeName + "': "+e.message,e);
+ }
+
+
+ } else {
+
+ // Lookup for renderer
+ var style = uidl.getAttribute("style");
+ var tag = uidl.nodeName;
+ var renderer = this.findRenderer(tag,style);
+
+ // Render the UIDL using the found renderer
+ if (renderer != null) {
+
+ // Function argument pass-through:
+ // Create arguments array and add all callers extra parameters
+ // to the end of arguments.
+ var args = new Array();
+ args[args.length] = uidl;
+ args[args.length] = target;
+ args[args.length] = renderer;
+ for(var i=3; i<arguments.length; i++) {
+ args[args.length] = arguments[i];
+ }
+ return this.renderUIDL.apply(this,args);
+ }
+ }
+
+ // If no renderer is specified, render the UIDL as-is.
+ return this.renderHTML(uidl, target);
+}
+
+/** Search the internal renderer registry for matching renderer.
+ *
+ * The matching process first looks up for exact tag and componentStyle
+ * match, but if no renderer is found it uses only the tag name matching.
+ * If still no renderer is found returns null.
+ *
+ * @param tag UIDL tag name.
+ * @param componentStyle The style attribute of the component (optional)
+ * @return A matching renderer instance
+ * @type Object
+ *
+ * @author Oy IT Mill Ltd / Sami Ekblad
+ *
+ */
+MillstoneAjaxClient.prototype.findRenderer = function (tag, componentStyle) {
+ var renderer = null;
+ var rendererId = tag + (componentStyle == null ? "" : "__" + componentStyle);
+
+ // Try to find with specific style
+ if (componentStyle != null) {
+ renderer = this.renderers[rendererId];
+ }
+
+ // Try to find a renderer only using tag
+ if (renderer == null) {
+ renderer = this.renderers[tag];
+ }
+
+ return renderer;
+}
+
+
+/** Renders given XML as redable HTML.
+ *
+ * @param xml The XML node to be rendered as readable HTML.
+ * @param target The node where the result should be appended as child.
+ * @return The rendered element
+ * @type Node
+ *
+ * @author Oy IT Mill Ltd / Sami Ekblad
+ *
+ */
+MillstoneAjaxClient.prototype.renderHTML = function (xml, target) {
+
+ var n = this.createElement("div",target);
+ target.appendChild(n);
+ n.setAttribute("style", "padding-left:10px;background-color:white;z-index:9999;position:relative;");
+ var tn = this.createTextNode("<" + xml.nodeName, target);
+ n.appendChild(tn);
+ if (xml.attributes.length > 0)
+ for(var i=0; i<xml.attributes.length; i++) {
+ var a = xml.attributes.item(i);
+ n.appendChild(this.createTextNode(" " + a.name + "=\"" + a.value+"\"",target));
+ }
+ n.appendChild(this.createTextNode(">",target));
+ if (xml.hasChildNodes())
+ for (var i=0; i<xml.childNodes.length; i++) {
+ var c = xml.childNodes.item(i);
+ if (c.nodeType == Node.ELEMENT_NODE) {
+ this.renderHTML(c,n);
+ } else if (c.nodeType == Node.TEXT_NODE && c.data != null) {
+ n.appendChild(this.createTextNode(c.data, target));
+ }
+ }
+ n.appendChild(this.createTextNode("</"+xml.nodeName+">",target));
+ return n;
+}
+/** Returns given XML as text.
+ *
+ * @param xml The XML node to be rendered as HTML.
+ * @return The XML as text
+ * @type String
+ *
+ * @author Oy IT Mill Ltd / Sami Ekblad
+ *
+ */
+MillstoneAjaxClient.prototype.getXMLtext = function(xml) {
+ var n = "";
+ n += "<" + xml.nodeName;
+ if (xml.attributes.length > 0)
+ for(var i=0; i<xml.attributes.length; i++) {
+ var a = xml.attributes.item(i);
+ n += " " + a.name + "=\"" + a.value+"\"";
+ }
+ n += ">";
+ if (xml.hasChildNodes())
+ for (var i=0; i<xml.childNodes.length; i++) {
+ var c = xml.childNodes.item(i);
+ if (c.nodeType == Node.ELEMENT_NODE) {
+ n += this.getXMLtext(c);
+ } else if (c.nodeType == Node.TEXT_NODE && c.data != null) {
+ n += c.data;
+ }
+ }
+ n += "</"+xml.nodeName+">";
+ return n;
+}
+
+/** Send a change variable event to server.
+ *
+ * Changes a variable value and if 'immediate' is true invokes the
+ * processVariableChanges function.
+ *
+ * @param name The name of the variable to change.
+ * @param value New value of the variable.
+ * @immediate True if the variable change should immediately propagate to server.
+ *
+ * @author Oy IT Mill Ltd / Sami Ekblad
+ *
+ */
+MillstoneAjaxClient.prototype.changeVariable = function (name, value, immediate) {
+ this.debug("variableChange('" + name + "', '" + value + "', " + immediate + ");");
+
+ this.variableStates[name] = escape(value);
+
+ if (immediate)
+ this.processVariableChanges(false);
+}
+
+/** Create new containing element for a paintable (component).
+ *
+ * This function creates new containing element for a single
+ * paintable object, typically component.
+ *
+ * @param uidl The UIDL node of the paintable.
+ * @param target The target node where the new containing element should be
+ * appended to as child.
+ * @return The newly created element node.
+ * @type Node
+ *
+ * @author Oy IT Mill Ltd / Sami Ekblad
+ *
+ */
+MillstoneAjaxClient.prototype.createPaintableElement = function (uidl, target) {
+
+ // Create DIV as container to right document.
+ var div = this.createElement("div", target);
+
+ // Append to parent, if 'target' parameter specified
+ if (target != null) {
+ target.appendChild(div);
+ }
+
+ // Add ID attribute
+ var pid = uidl.getAttribute("id");
+ if (target != null && pid != null) {
+ div.setAttribute("id",pid);
+ }
+
+ // Set visibility
+ var invisible = uidl.getAttribute("invisible");
+ if (target != null && invisible == "true") {
+ div.style.display = "none";
+ } else {
+ div.style.display = "";
+ }
+
+ // Return reference to newly created div
+ return div;
+}
+
+
+/** Assigns given CSS class to element.
+ * Cross-browser function for assigning CSS class attribute to
+ * an element.
+ * @param element The element where the class should be applied.
+ * @param className The CSS class name to apply.
+ * @return element.
+ * @type Node
+ *
+ * @author Oy IT Mill Ltd / Sami Ekblad
+ *
+ */
+MillstoneAjaxClient.prototype.setElementClassName = function(element,className) {
+ if (element == null) { return; }
+ element.style.className = className;
+
+}
+
+/**
+ * Add event listener function to an element.
+ *
+ * @param element The element
+ * @param type Type of event to listen for [click|mouseover|mouseout|...]
+ * @param func The function to call. Called with single parameter: event.
+ *
+ * @return the listener function added
+ */
+MillstoneAjaxClient.prototype.addEventListener = function(element,type,func) {
+ if (element.addEventListener) {
+ element.addEventListener(type, func, false);
+
+ } else if (element.attachEvent) {
+ element.attachEvent("on" + type, func);
+
+ } else {
+ element['on'+type] = func;
+ }
+
+ // TODO add only to paintable?
+
+ if (!element.eventMap) element.eventMap = new Object();
+ if (!element.eventMap[type]) element.eventMap[type] = new Array();
+ element.eventMap[type][element.eventMap[type].length] = func;
+
+ // FIXME remove
+ if (!document.eventListenerCount) document.eventListenerCount = 0;
+ document.eventListenerCount++;
+
+ return func;
+}
+/**
+ * Remove event listener function from a element. The parameters should match addEventListener()
+ *
+ * @param element The element
+ * @param type Type of event to listen for [click|mouseover|mouseout|...]
+ * @param func The listener function to remove.
+ *
+ */
+MillstoneAjaxClient.prototype.removeEventListener = function(element,type,func) {
+ if (element.removeEventListener) {
+ element.removeEventListener(type, func, false);
+
+ } else if (element.detachEvent) {
+ element.detachEvent("on" + type, func);
+
+ } else {
+ element['on'+type] = null;
+ }
+ if (element.eventMap && element.eventMap[type]) {
+ for (var f in element.eventMap[type]) {
+ if (element.eventMap[type][f]==func) {
+ element.eventMap[type][f] = null;
+ break;
+ }
+ }
+ }
+ document.eventListenerCount--;
+}
+
+/**
+ * Remove all event listener functions from a element.
+ *
+ * @param element The element
+ * @param type Type of event to listen for [click|mouseover|mouseout|...]
+ * @param func The listener function to remove.
+ *
+ */
+ MillstoneAjaxClient.prototype.removeAllEventListeners = function(element) {
+ var removed = 0;
+ if (element.eventMap) {
+ for (var t in element.eventMap) {
+ var i = element.eventMap[t].length;
+ while (i--) {
+ this.removeEventListener(element,t,element.eventMap[t][i]);
+ removed++;
+ }
+ }
+
+ element.eventMap = null;
+ }
+ // TODO eventMAp -> paintable & only get DIV:s
+ var childs = element.getElementsByTagName("*");
+ if (childs) {
+ var i = childs.length;
+ while (i--) {
+ element = childs[i];
+ if (element.eventMap) {
+ for (var t in element.eventMap) {
+ var j = element.eventMap[t].length;
+ while (j--) {
+ this.removeEventListener(element,t,element.eventMap[t][j]);
+ removed++;
+ }
+ }
+
+ element.eventMap = null;
+ }
+ }
+ }
+
+ return removed;
+}
+
+MillstoneAjaxClient.prototype.registerLayoutFunction = function (paintableElement,func) {
+ if (!paintableElement || !func) {
+ this.error("Invalid layout function registration; paintableElement:"+paintableElement+" func:"+func);
+ return;
+ }
+
+ var pid = paintableElement.id;
+ if (!pid) {
+ this.error("Register layout function; paintableElement pid not found!" + paintableElement);
+ return;
+ }
+
+ if (!this.layoutFunctionsOrder) {
+ this.layoutFunctionsOrder = new Object();
+ this.layoutFunctions = new Array();
+ }
+
+ var idx = this.layoutFunctionsOrder[pid];
+ if (typeof(idx) == "undefined") idx = this.layoutFunctions.length;
+
+ this.layoutFunctionsOrder[pid] = idx;
+ this.layoutFunctions[idx] = func;
+
+ this.debug("Registered layout function for ("+paintableElement.nodeName+") pid " + pid + " as number " + idx);
+}
+MillstoneAjaxClient.prototype.unregisterLayoutFunction = function (paintableElement) {
+ if (!paintableElement) {
+ this.error("unregisterLayoutFunction(): NULL paintableElement!");
+ return false;
+ }
+
+ if (!this.layoutFunctionsOrder) {
+ // no functions at all
+ return false;
+ }
+
+ var pid = paintableElement.id;
+ if (!pid) {
+ this.error("unregisterLayoutFunction(): paintableElement pid not found!" + paintableElement);
+ return false;
+ }
+
+ var idx = this.layoutFunctionsOrder[pid];
+ if (typeof(idx) == "undefined") {
+ // no registered function
+ return false;
+ }
+
+ this.layoutFunctions[idx] = null;
+ delete this.layoutFunctionsOrder[pid];
+
+ this.debug("Unregistered layout function " + pid);
+
+ return true;
+}
+MillstoneAjaxClient.prototype.unregisterAllLayoutFunctions = function (paintableElement) {
+ var removed = 0;
+ if (!paintableElement) {
+ removed = (this.layoutFunctions?this.layoutFunctions.length:0);
+ this.layoutFunctions = null;
+ this.layoutFunctionsOrder = null;
+ this.debug("Unregistered ALL layout functions!");
+ return removed;
+ }
+
+
+
+ if (paintableElement.id) {
+ if (this.unregisterLayoutFunction(paintableElement)) removed++
+ }
+ var cn = paintableElement.getElementsByTagName("div");
+ if (cn) {
+ var len = cn.length;
+ for (var i=0;i<len;i++) {
+ if (cn[i].id) {
+ if (this.unregisterLayoutFunction(cn[i])) removed++
+ }
+ }
+ }
+
+ return removed;
+}
+MillstoneAjaxClient.prototype.processAllLayoutFunctions = function() {
+ if (this.layoutFunctions) {
+ this.debug("Processing layout functions...");
+ var lf = this.layoutFunctions;
+ var lfo = this.layoutFunctionsOrder;
+ var cnt = 0;
+ for (var pid in lfo) {
+ var idx = lfo[pid];
+ var func = lf[idx];
+ try {
+ func();
+ cnt++;
+ } catch (e) {
+ this.error("Layout function "+pid+" failed; "+ e + " Removing.");
+ delete this.layoutFunctionsOrder[pid];
+ this.layoutFunctions[idx] = null;
+ }
+ }
+ this.debug("...processed " + cnt + " successfully");
+ }
+}
+
+
+/** Returns a cross-browser object with useful event properties.
+ * e: the ('raw') event
+ * type: event type
+ * target: the target element
+ * targetX: X-position of the target element
+ * targetY: Y-position of the target element
+ * key: pressed key character
+ * alt: true if ALT -key was held
+ * shift: true if SHIFT -key was held
+ * ctrl: true if CTRL -key was held
+ * rightclick: true if the right mousebutton was clicked, or ctrl held while clicking
+ * mouseX: X-position of the mouse
+ * mouseY: Y-position of the mouse
+ *
+ * @param e The event, null for window.event (IE)
+ *
+ * @return Properties object.
+ */
+MillstoneAjaxClient.prototype.getEvent = function(e) {
+ var props = new Object()
+
+ if (!e) var e = window.event;
+ props.e = e;
+ props.type = e.type;
+
+ var targ;
+ if (e.target) {
+ targ = e.target;
+ } else if (e.srcElement) {
+ targ = e.srcElement;
+ }
+ if (targ.nodeType == 3) {
+ targ = targ.parentNode;
+ }
+ props.target = targ;
+ var p = this.getElementPosition(targ);
+ props.targetX = p.x;
+ props.targetY = p.y;
+
+ var code;
+ if (e.keyCode) {
+ code = e.keyCode;
+ } else if (e.which) {
+ code = e.which;
+ }
+ if (code) {
+ props.key = String.fromCharCode(code);
+ }
+
+ props.alt = e.altKey;
+ props.ctrl = e.ctrlKey;
+ props.shift = e.shiftKey;
+
+ var rightclick;
+ if (e.which) {
+ rightclick = (e.which == 3 || (props.ctrl));
+ } else if (e.button) {
+ rightclick = (e.button == 2|| (props.ctrl));
+ }
+ props.rightclick = rightclick;
+
+ /* New way to calculate mouse position, 9.6.2006 - Jouni Koivuviita */
+ var d = document, v = window, window_w, window_h, window_l, window_t;
+ if( typeof v.innerWidth==='number' ) {
+
+ window_w = v.innerWidth;
+ window_h = v.innerHeight;
+ window_l = v.pageXOffset;
+ window_t = v.pageYOffset;
+
+ } else if( ( v = d.documentElement ) &&
+ typeof v.clientWidth==='number' &&
+ v.clientWidth !== 0 || ( v = document.body ) ) {
+
+ window_w = v.clientWidth;
+ window_h = v.clientHeight;
+ window_l = v.scrollLeft;
+ window_t = v.scrollTop;
+
+ }
+
+ if( typeof e.pageX==='number' ) {
+ props.mouseX = e.pageX;
+ props.mouseY = e.pageY;
+ } else {
+ props.mouseX = e.x + window_l;
+ props.mouseY = e.y + window_t;
+ }
+
+ //props.mouseX = e.pageX||e.clientX;
+ //props.mouseY = e.pageY||e.clientY;
+
+ props.stop = function() {
+ e.cancelBubble = true;
+ if (e.stopPropagation) e.stopPropagation();
+ if (e.preventDefault) e.preventDefault();
+ return false;
+ }
+
+ return props;
+}
+
+MillstoneAjaxClient.prototype.getElementPosition = function(element) {
+ var props = new Object();
+// TODO scroll offsets testing in IE
+ var obj = element;
+ var x = obj.offsetLeft + (obj.scrollLeft||0);
+ var y = obj.offsetTop + (obj.scrollTop||0);
+ if (obj.parentNode||obj.offsetParent) {
+ while (obj.offsetParent||obj.parentNode) {
+ obj = obj.offsetParent||obj.parentNode;
+ if (obj.nodeName == "TBODY") continue;
+ x += (obj.offsetLeft||0) - (obj.scrollLeft||0);
+ y += (obj.offsetTop||0) - (obj.scrollTop||0);
+ }
+ } else if (obj.x) {
+ x += obj.x;
+ y += obj.y;
+ }
+ props.x = x;
+ props.y = y;
+ props.h = element.offsetHeight;
+ props.w = element.offsetWidth;
+
+ return props;
+}
+
+/** Prints objects properties into separate window.
+ *
+ * @obj Object to be printed
+ * @level recursion level
+ */
+MillstoneAjaxClient.prototype.debugObjectWindow = function(obj,level) {
+
+ // Default level
+ if (level == null) {
+ level = 2;
+ }
+
+ //print into string
+ var str = this.printObject(obj,level);
+
+ // open a window for debug
+ var win = window.open("", "ms_ajax_debug");
+ win.document.open();
+ win.document.write("<html><body>"+str+"+</body></html>");
+ win.document.close();
+}
+
+/** Print a object instace as html string.
+ * Prints (recursively) the objects properties into a html table.
+ *
+ * @obj Object to be printed
+ * @level recursion level
+ */
+MillstoneAjaxClient.prototype.printObject = function(obj,level) {
+ if (level == null || level < 1) {
+ level = 1;
+ }
+
+ var str = "<table border=\"0\"><tr><td colspan=\"3\">Object: "+obj+"<hr /></td></tr>";
+ try {
+ for (var prop in obj) {
+ str += "<tr><td valign=\"top\">"+prop+"</td><td valign=\"top\"> = </td><td valign=\"top\">";
+ try {
+ if (typeof obj[prop] == "object" && level > 1) {
+ str += this.printObject(obj[prop],level-1);
+ } else {
+ str += obj[prop];
+ }
+ } catch(ignored) {
+ str += "[EVAL FAILED]";
+ }
+ str += "</td></tr>";
+ }
+ } catch (e) {
+ str += "<tr><td colspan=\"3\">[Failed to list object properties: "+e.message+"]</td></tr>"
+ }
+ str += "</table>";
+ return str;
+}
+
+/** Creates a text node to the same document as target.
+ * If target is null or not given the document reference is
+ * used instead.
+ *
+ * @target Target element
+ * @text Textnode content
+ */
+MillstoneAjaxClient.prototype.createTextNode = function(text, target) {
+ if (target != null && target.ownerDocument != null) {
+ return target.ownerDocument.createTextNode(text);
+ } else {
+ return document.createTextNode(text);
+ }
+}
+
+/** Creates a element node to the same document as target.
+ * If target is null or not given the document reference is
+ * used instead.
+ *
+ * @nodeName Element nodeName
+ * @text Textnode content
+ */
+MillstoneAjaxClient.prototype.createElement = function(nodeName, target) {
+
+ if (target != null && target.ownerDocument != null) {
+ return target.ownerDocument.createElement(nodeName);
+ } else {
+ return document.createElement(nodeName);
+ }
+}
diff --git a/WebContent/client/debug.css b/WebContent/client/debug.css
new file mode 100644
index 0000000000..f94a0d6060
--- /dev/null
+++ b/WebContent/client/debug.css
@@ -0,0 +1,57 @@
+/*
+
+ Styles for ajax adapter debug window.
+
+*/
+
+body {
+ overflow: scroll;
+}
+* {
+ font-size: 10pt;
+ font-family: sans-serif;
+}
+
+xmp {
+ margin: 0px;
+ padding: 0px;
+}
+
+
+.folded {
+ margin-top: 4px;
+ background-color: #eeeeee;
+ background-image: url(img/on.gif);
+ background-repeat: no-repeat;
+ border: 1px dotted gray;
+ padding-left: 20px;
+ height: 20px;
+ width: 100%;
+ overflow: hidden;
+ cursor: hand;
+ cursor: pointer;
+}
+
+.unfolded {
+ margin-top: 4px;
+ background-color: #eeeeee;
+ background-image: url(img/off.gif);
+ background-repeat: no-repeat;
+ border: 1px dotted gray;
+ padding-left: 20px;
+ height:;
+ width: 100%;
+ overflow: hidden;
+ cursor: hand;
+ cursor: pointer;
+}
+
+.normal {
+ margin-top: 4px;
+ border-top: 1px dotted gray;
+ width: 100%;
+}
+
+.error {
+ border: 1px solid red;
+}
diff --git a/WebContent/client/img/off.gif b/WebContent/client/img/off.gif
new file mode 100644
index 0000000000..bc8b454f81
--- /dev/null
+++ b/WebContent/client/img/off.gif
Binary files differ
diff --git a/WebContent/client/img/on.gif b/WebContent/client/img/on.gif
new file mode 100644
index 0000000000..b23d660d90
--- /dev/null
+++ b/WebContent/client/img/on.gif
Binary files differ
diff --git a/WebContent/themes/default/calendar-default.css b/WebContent/themes/default/calendar-default.css
new file mode 100644
index 0000000000..d018ff7fac
--- /dev/null
+++ b/WebContent/themes/default/calendar-default.css
@@ -0,0 +1,236 @@
+/* The main calendar widget. DIV containing a table. */
+
+div.calendar { position: relative; }
+
+.calendar, .calendar table {
+ border: 1px solid #aaaaaa;
+ font-size: 11px;
+ color: #000000;
+ cursor: default;
+ background: #ffffff;
+ font-family: tahoma,verdana,sans-serif;
+ border-collapse: collapse;
+}
+
+/* Header part -- contains navigation buttons and day names. */
+
+.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */
+ text-align: center; /* They are the navigation buttons */
+ padding: 2px; /* Make the buttons seem like they're pressing */
+ border: 1px solid #aaaaaa;
+}
+
+.calendar .nav {
+ background: #ffffff url(menuarrow.gif) no-repeat 100% 100%;
+}
+
+.calendar thead .title { /* This holds the current "month, year" */
+ font-weight: bold; /* Pressing it will take you to the current date */
+ text-align: center;
+ background: #fff;
+ background-image: url('img/bg1.gif');
+ background-repeat: repeat-x; color: #000;
+ padding: 2px;
+}
+
+.calendar thead .headrow { /* Row <TR> containing navigation buttons */
+ background: #f5f5fa;
+ color: #000000;
+}
+
+.calendar thead .daynames { /* Row <TR> containing the day names */
+ background: #ffffff;
+ backgound-image:
+}
+
+.calendar thead .name { /* Cells <TD> containing the day names */
+ border-bottom: 1px solid #556;
+ padding: 2px;
+ text-align: center;
+ color: #000;
+}
+
+.calendar thead .weekend { /* How a weekend day name shows in header */
+ color: #a66;
+}
+
+.calendar thead .hilite { /* How do the buttons in header appear when hover */
+ background-color: #bbb;
+ background-repeat: repeat-x;
+ color: #000;
+ padding: 1px;
+}
+
+.calendar thead .active { /* Active (pressed) buttons in header */
+ padding: 2px 0px 0px 2px;
+}
+
+/* The body part -- contains all the days in month. */
+
+.calendar tbody .day { /* Cells <TD> containing month days dates */
+ width: 2em;
+ color: #456;
+ text-align: right;
+ padding: 2px 4px 2px 2px;
+}
+.calendar tbody .day.othermonth {
+ font-size: 80%;
+ color: #bbb;
+}
+.calendar tbody .day.othermonth.oweekend {
+ color: #fbb;
+}
+
+.calendar table .wn {
+ padding: 2px 3px 2px 2px;
+ border-right: 1px solid #000;
+ background: #ffffff;
+}
+
+.calendar tbody .rowhilite td {
+
+}
+
+.calendar tbody .rowhilite td.wn {
+
+}
+
+.calendar tbody td.hilite { /* Hovered cells <TD> */
+ Xpadding: 1px 3px 1px 1px;
+ xborder: 1px solid #bbb;
+ background-color: #bbb;
+
+}
+
+.calendar tbody td.active { /* Active (pressed) cells <TD> */
+ background: #cde;
+ padding: 2px 2px 0px 2px;
+}
+
+.calendar tbody td.selected { /* Cell showing today date */
+ font-weight: bold;
+ border: 1px solid #aaaaaa;
+ padding: 1px 3px 1px 1px;
+ background: #fff;
+ color: #000;
+}
+
+.calendar tbody td.weekend { /* Cells showing weekend days */
+ color: #a66;
+}
+
+.calendar tbody td.today { /* Cell showing selected date */
+ font-weight: bold;
+ color: #00f;
+}
+
+.calendar tbody .disabled { color: #999; }
+
+.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */
+ visibility: hidden;
+}
+
+.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */
+ display: none;
+}
+
+/* The footer part -- status bar and "Close" button */
+
+.calendar tfoot .footrow { /* The <TR> in footer (only one right now) */
+ text-align: center;
+ background: #556;
+ color: #fff;
+}
+
+.calendar tfoot .ttip { /* Tooltip (status bar) cell <TD> */
+ background: #fff;
+ color: #445;
+ border-top: 1px solid #556;
+ padding: 1px;
+}
+
+.calendar tfoot .hilite { /* Hover style for buttons in footer */
+ background: #aaf;
+ border: 1px solid #04f;
+ color: #000;
+ padding: 1px;
+}
+
+.calendar tfoot .active { /* Active (pressed) style for buttons in footer */
+ background: #77c;
+ padding: 2px 0px 0px 2px;
+}
+
+/* Combo boxes (menus that display months/years for direct selection) */
+
+.calendar .combo {
+ position: absolute;
+ display: none;
+ top: 0px;
+ left: 0px;
+ width: 4em;
+ cursor: default;
+ border: 1px solid #aaaaaa;
+ background: #ffffff;
+ color: #000;
+ font-size: 90%;
+ z-index: 100;
+}
+
+.calendar .combo .label,
+.calendar .combo .label-IEfix {
+ text-align: center;
+ padding: 1px;
+}
+
+.calendar .combo .label-IEfix {
+ width: 4em;
+}
+
+.calendar .combo .hilite {
+ background: #acf;
+}
+
+.calendar .combo .active {
+ border-top: 1px solid #46a;
+ border-bottom: 1px solid #46a;
+ background: #eef;
+ font-weight: bold;
+}
+
+.calendar td.time {
+ border-top: 1px solid #000;
+ padding: 1px 0px;
+ text-align: center;
+ background-color: #f4f0e8;
+}
+
+.calendar td.time .hour,
+.calendar td.time .minute,
+.calendar td.time .ampm {
+ padding: 0px 3px 0px 4px;
+ border: 1px solid #889;
+ font-weight: bold;
+ background-color: #fff;
+}
+
+.calendar td.time .ampm {
+ text-align: center;
+}
+
+.calendar td.time .colon {
+ padding: 0px 2px 0px 3px;
+ font-weight: bold;
+}
+
+.calendar td.time span.hilite {
+ border-color: #000;
+ background-color: #667;
+ color: #fff;
+}
+
+.calendar td.time span.active {
+ border-color: #f00;
+ background-color: #000;
+ color: #0f0;
+}
diff --git a/WebContent/themes/default/img/bg1.gif b/WebContent/themes/default/img/bg1.gif
new file mode 100644
index 0000000000..f93245029c
--- /dev/null
+++ b/WebContent/themes/default/img/bg1.gif
Binary files differ
diff --git a/WebContent/themes/default/img/bg3.jpg b/WebContent/themes/default/img/bg3.jpg
new file mode 100644
index 0000000000..51a70f18c3
--- /dev/null
+++ b/WebContent/themes/default/img/bg3.jpg
Binary files differ
diff --git a/WebContent/themes/default/img/button/btn-bg.gif b/WebContent/themes/default/img/button/btn-bg.gif
new file mode 100644
index 0000000000..2b9f4ceae7
--- /dev/null
+++ b/WebContent/themes/default/img/button/btn-bg.gif
Binary files differ
diff --git a/WebContent/themes/default/img/button/btn-left.gif b/WebContent/themes/default/img/button/btn-left.gif
new file mode 100644
index 0000000000..d11581e0e8
--- /dev/null
+++ b/WebContent/themes/default/img/button/btn-left.gif
Binary files differ
diff --git a/WebContent/themes/default/img/button/btn-left.png b/WebContent/themes/default/img/button/btn-left.png
new file mode 100644
index 0000000000..8ab99a0bd6
--- /dev/null
+++ b/WebContent/themes/default/img/button/btn-left.png
Binary files differ
diff --git a/WebContent/themes/default/img/button/btn-right.gif b/WebContent/themes/default/img/button/btn-right.gif
new file mode 100644
index 0000000000..870d3bc2bb
--- /dev/null
+++ b/WebContent/themes/default/img/button/btn-right.gif
Binary files differ
diff --git a/WebContent/themes/default/img/button/btn-right.png b/WebContent/themes/default/img/button/btn-right.png
new file mode 100644
index 0000000000..c9903c8479
--- /dev/null
+++ b/WebContent/themes/default/img/button/btn-right.png
Binary files differ
diff --git a/WebContent/themes/default/img/debug.gif b/WebContent/themes/default/img/debug.gif
new file mode 100644
index 0000000000..a27451e7c7
--- /dev/null
+++ b/WebContent/themes/default/img/debug.gif
Binary files differ
diff --git a/WebContent/themes/default/img/icon/attention.gif b/WebContent/themes/default/img/icon/attention.gif
new file mode 100644
index 0000000000..c3c8b2778c
--- /dev/null
+++ b/WebContent/themes/default/img/icon/attention.gif
Binary files differ
diff --git a/WebContent/themes/default/img/icon/attention.png b/WebContent/themes/default/img/icon/attention.png
new file mode 100644
index 0000000000..a5b13118ef
--- /dev/null
+++ b/WebContent/themes/default/img/icon/attention.png
Binary files differ
diff --git a/WebContent/themes/default/img/icon/error-mini.gif b/WebContent/themes/default/img/icon/error-mini.gif
new file mode 100644
index 0000000000..a17267228a
--- /dev/null
+++ b/WebContent/themes/default/img/icon/error-mini.gif
Binary files differ
diff --git a/WebContent/themes/default/img/icon/error.gif b/WebContent/themes/default/img/icon/error.gif
new file mode 100644
index 0000000000..8acbcfd443
--- /dev/null
+++ b/WebContent/themes/default/img/icon/error.gif
Binary files differ
diff --git a/WebContent/themes/default/img/icon/info-mini.gif b/WebContent/themes/default/img/icon/info-mini.gif
new file mode 100644
index 0000000000..2aedd2f9a9
--- /dev/null
+++ b/WebContent/themes/default/img/icon/info-mini.gif
Binary files differ
diff --git a/WebContent/themes/default/img/icon/info.gif b/WebContent/themes/default/img/icon/info.gif
new file mode 100644
index 0000000000..d181af0f73
--- /dev/null
+++ b/WebContent/themes/default/img/icon/info.gif
Binary files differ
diff --git a/WebContent/themes/default/img/panel/bottom-left.gif b/WebContent/themes/default/img/panel/bottom-left.gif
new file mode 100644
index 0000000000..8a9bb94e80
--- /dev/null
+++ b/WebContent/themes/default/img/panel/bottom-left.gif
Binary files differ
diff --git a/WebContent/themes/default/img/panel/bottom-right.gif b/WebContent/themes/default/img/panel/bottom-right.gif
new file mode 100644
index 0000000000..1527ccefc8
--- /dev/null
+++ b/WebContent/themes/default/img/panel/bottom-right.gif
Binary files differ
diff --git a/WebContent/themes/default/img/panel/bottom.gif b/WebContent/themes/default/img/panel/bottom.gif
new file mode 100644
index 0000000000..eb27901203
--- /dev/null
+++ b/WebContent/themes/default/img/panel/bottom.gif
Binary files differ
diff --git a/WebContent/themes/default/img/panel/middle-light.gif b/WebContent/themes/default/img/panel/middle-light.gif
new file mode 100644
index 0000000000..1d16e828f3
--- /dev/null
+++ b/WebContent/themes/default/img/panel/middle-light.gif
Binary files differ
diff --git a/WebContent/themes/default/img/panel/middle.gif b/WebContent/themes/default/img/panel/middle.gif
new file mode 100644
index 0000000000..e36e2f5a36
--- /dev/null
+++ b/WebContent/themes/default/img/panel/middle.gif
Binary files differ
diff --git a/WebContent/themes/default/img/panel/top-left-light.gif b/WebContent/themes/default/img/panel/top-left-light.gif
new file mode 100644
index 0000000000..1afc98e4ae
--- /dev/null
+++ b/WebContent/themes/default/img/panel/top-left-light.gif
Binary files differ
diff --git a/WebContent/themes/default/img/panel/top-left.gif b/WebContent/themes/default/img/panel/top-left.gif
new file mode 100644
index 0000000000..996483a0d6
--- /dev/null
+++ b/WebContent/themes/default/img/panel/top-left.gif
Binary files differ
diff --git a/WebContent/themes/default/img/panel/top-right-light.gif b/WebContent/themes/default/img/panel/top-right-light.gif
new file mode 100644
index 0000000000..8d24902fc3
--- /dev/null
+++ b/WebContent/themes/default/img/panel/top-right-light.gif
Binary files differ
diff --git a/WebContent/themes/default/img/panel/top-right.gif b/WebContent/themes/default/img/panel/top-right.gif
new file mode 100644
index 0000000000..0df2da052f
--- /dev/null
+++ b/WebContent/themes/default/img/panel/top-right.gif
Binary files differ
diff --git a/WebContent/themes/default/img/panel/top.gif b/WebContent/themes/default/img/panel/top.gif
new file mode 100644
index 0000000000..2479fb8d18
--- /dev/null
+++ b/WebContent/themes/default/img/panel/top.gif
Binary files differ
diff --git a/WebContent/themes/default/img/table/asc.gif b/WebContent/themes/default/img/table/asc.gif
new file mode 100644
index 0000000000..b23d660d90
--- /dev/null
+++ b/WebContent/themes/default/img/table/asc.gif
Binary files differ
diff --git a/WebContent/themes/default/img/table/bottom-left.gif b/WebContent/themes/default/img/table/bottom-left.gif
new file mode 100644
index 0000000000..601002bdf3
--- /dev/null
+++ b/WebContent/themes/default/img/table/bottom-left.gif
Binary files differ
diff --git a/WebContent/themes/default/img/table/bottom-right.gif b/WebContent/themes/default/img/table/bottom-right.gif
new file mode 100644
index 0000000000..f975e42e79
--- /dev/null
+++ b/WebContent/themes/default/img/table/bottom-right.gif
Binary files differ
diff --git a/WebContent/themes/default/img/table/caption-bg.gif b/WebContent/themes/default/img/table/caption-bg.gif
new file mode 100644
index 0000000000..ed8cca0f0d
--- /dev/null
+++ b/WebContent/themes/default/img/table/caption-bg.gif
Binary files differ
diff --git a/WebContent/themes/default/img/table/caption-left.gif b/WebContent/themes/default/img/table/caption-left.gif
new file mode 100644
index 0000000000..fe4f3203a6
--- /dev/null
+++ b/WebContent/themes/default/img/table/caption-left.gif
Binary files differ
diff --git a/WebContent/themes/default/img/table/caption-right.gif b/WebContent/themes/default/img/table/caption-right.gif
new file mode 100644
index 0000000000..e5d83b08e3
--- /dev/null
+++ b/WebContent/themes/default/img/table/caption-right.gif
Binary files differ
diff --git a/WebContent/themes/default/img/table/col-header-bg.gif b/WebContent/themes/default/img/table/col-header-bg.gif
new file mode 100644
index 0000000000..8a0e2efb4e
--- /dev/null
+++ b/WebContent/themes/default/img/table/col-header-bg.gif
Binary files differ
diff --git a/WebContent/themes/default/img/table/colsel.gif b/WebContent/themes/default/img/table/colsel.gif
new file mode 100644
index 0000000000..b23d660d90
--- /dev/null
+++ b/WebContent/themes/default/img/table/colsel.gif
Binary files differ
diff --git a/WebContent/themes/default/img/table/desc.gif b/WebContent/themes/default/img/table/desc.gif
new file mode 100644
index 0000000000..bc8b454f81
--- /dev/null
+++ b/WebContent/themes/default/img/table/desc.gif
Binary files differ
diff --git a/WebContent/themes/default/img/table/handle.gif b/WebContent/themes/default/img/table/handle.gif
new file mode 100644
index 0000000000..bdf7a77041
--- /dev/null
+++ b/WebContent/themes/default/img/table/handle.gif
Binary files differ
diff --git a/WebContent/themes/default/img/table/off.gif b/WebContent/themes/default/img/table/off.gif
new file mode 100644
index 0000000000..bc8b454f81
--- /dev/null
+++ b/WebContent/themes/default/img/table/off.gif
Binary files differ
diff --git a/WebContent/themes/default/img/table/on.gif b/WebContent/themes/default/img/table/on.gif
new file mode 100644
index 0000000000..b23d660d90
--- /dev/null
+++ b/WebContent/themes/default/img/table/on.gif
Binary files differ
diff --git a/WebContent/themes/default/img/table/test.gif b/WebContent/themes/default/img/table/test.gif
new file mode 100644
index 0000000000..8a21c28c18
--- /dev/null
+++ b/WebContent/themes/default/img/table/test.gif
Binary files differ
diff --git a/WebContent/themes/default/img/table/top-left.gif b/WebContent/themes/default/img/table/top-left.gif
new file mode 100644
index 0000000000..58554e9d77
--- /dev/null
+++ b/WebContent/themes/default/img/table/top-left.gif
Binary files differ
diff --git a/WebContent/themes/default/img/table/top-right.gif b/WebContent/themes/default/img/table/top-right.gif
new file mode 100644
index 0000000000..d0b36ec517
--- /dev/null
+++ b/WebContent/themes/default/img/table/top-right.gif
Binary files differ
diff --git a/WebContent/themes/default/img/tree/empty.gif b/WebContent/themes/default/img/tree/empty.gif
new file mode 100644
index 0000000000..1aa9e9bb71
--- /dev/null
+++ b/WebContent/themes/default/img/tree/empty.gif
Binary files differ
diff --git a/WebContent/themes/default/img/tree/off.gif b/WebContent/themes/default/img/tree/off.gif
new file mode 100644
index 0000000000..bc8b454f81
--- /dev/null
+++ b/WebContent/themes/default/img/tree/off.gif
Binary files differ
diff --git a/WebContent/themes/default/img/tree/on.gif b/WebContent/themes/default/img/tree/on.gif
new file mode 100644
index 0000000000..b23d660d90
--- /dev/null
+++ b/WebContent/themes/default/img/tree/on.gif
Binary files differ
diff --git a/WebContent/themes/default/img/w2x2.gif b/WebContent/themes/default/img/w2x2.gif
new file mode 100644
index 0000000000..03e0677003
--- /dev/null
+++ b/WebContent/themes/default/img/w2x2.gif
Binary files differ
diff --git a/WebContent/themes/default/jscalendar/calendar-blue.css b/WebContent/themes/default/jscalendar/calendar-blue.css
new file mode 100644
index 0000000000..ca33cde007
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/calendar-blue.css
@@ -0,0 +1,232 @@
+/* The main calendar widget. DIV containing a table. */
+
+div.calendar { position: relative; }
+
+.calendar, .calendar table {
+ border: 1px solid #556;
+ font-size: 11px;
+ color: #000;
+ cursor: default;
+ background: #eef;
+ font-family: tahoma,verdana,sans-serif;
+}
+
+/* Header part -- contains navigation buttons and day names. */
+
+.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */
+ text-align: center; /* They are the navigation buttons */
+ padding: 2px; /* Make the buttons seem like they're pressing */
+}
+
+.calendar .nav {
+ background: #778 url(menuarrow.gif) no-repeat 100% 100%;
+}
+
+.calendar thead .title { /* This holds the current "month, year" */
+ font-weight: bold; /* Pressing it will take you to the current date */
+ text-align: center;
+ background: #fff;
+ color: #000;
+ padding: 2px;
+}
+
+.calendar thead .headrow { /* Row <TR> containing navigation buttons */
+ background: #778;
+ color: #fff;
+}
+
+.calendar thead .daynames { /* Row <TR> containing the day names */
+ background: #bdf;
+}
+
+.calendar thead .name { /* Cells <TD> containing the day names */
+ border-bottom: 1px solid #556;
+ padding: 2px;
+ text-align: center;
+ color: #000;
+}
+
+.calendar thead .weekend { /* How a weekend day name shows in header */
+ color: #a66;
+}
+
+.calendar thead .hilite { /* How do the buttons in header appear when hover */
+ background-color: #aaf;
+ color: #000;
+ border: 1px solid #04f;
+ padding: 1px;
+}
+
+.calendar thead .active { /* Active (pressed) buttons in header */
+ background-color: #77c;
+ padding: 2px 0px 0px 2px;
+}
+
+/* The body part -- contains all the days in month. */
+
+.calendar tbody .day { /* Cells <TD> containing month days dates */
+ width: 2em;
+ color: #456;
+ text-align: right;
+ padding: 2px 4px 2px 2px;
+}
+.calendar tbody .day.othermonth {
+ font-size: 80%;
+ color: #bbb;
+}
+.calendar tbody .day.othermonth.oweekend {
+ color: #fbb;
+}
+
+.calendar table .wn {
+ padding: 2px 3px 2px 2px;
+ border-right: 1px solid #000;
+ background: #bdf;
+}
+
+.calendar tbody .rowhilite td {
+ background: #def;
+}
+
+.calendar tbody .rowhilite td.wn {
+ background: #eef;
+}
+
+.calendar tbody td.hilite { /* Hovered cells <TD> */
+ background: #def;
+ padding: 1px 3px 1px 1px;
+ border: 1px solid #bbb;
+}
+
+.calendar tbody td.active { /* Active (pressed) cells <TD> */
+ background: #cde;
+ padding: 2px 2px 0px 2px;
+}
+
+.calendar tbody td.selected { /* Cell showing today date */
+ font-weight: bold;
+ border: 1px solid #000;
+ padding: 1px 3px 1px 1px;
+ background: #fff;
+ color: #000;
+}
+
+.calendar tbody td.weekend { /* Cells showing weekend days */
+ color: #a66;
+}
+
+.calendar tbody td.today { /* Cell showing selected date */
+ font-weight: bold;
+ color: #00f;
+}
+
+.calendar tbody .disabled { color: #999; }
+
+.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */
+ visibility: hidden;
+}
+
+.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */
+ display: none;
+}
+
+/* The footer part -- status bar and "Close" button */
+
+.calendar tfoot .footrow { /* The <TR> in footer (only one right now) */
+ text-align: center;
+ background: #556;
+ color: #fff;
+}
+
+.calendar tfoot .ttip { /* Tooltip (status bar) cell <TD> */
+ background: #fff;
+ color: #445;
+ border-top: 1px solid #556;
+ padding: 1px;
+}
+
+.calendar tfoot .hilite { /* Hover style for buttons in footer */
+ background: #aaf;
+ border: 1px solid #04f;
+ color: #000;
+ padding: 1px;
+}
+
+.calendar tfoot .active { /* Active (pressed) style for buttons in footer */
+ background: #77c;
+ padding: 2px 0px 0px 2px;
+}
+
+/* Combo boxes (menus that display months/years for direct selection) */
+
+.calendar .combo {
+ position: absolute;
+ display: none;
+ top: 0px;
+ left: 0px;
+ width: 4em;
+ cursor: default;
+ border: 1px solid #655;
+ background: #def;
+ color: #000;
+ font-size: 90%;
+ z-index: 100;
+}
+
+.calendar .combo .label,
+.calendar .combo .label-IEfix {
+ text-align: center;
+ padding: 1px;
+}
+
+.calendar .combo .label-IEfix {
+ width: 4em;
+}
+
+.calendar .combo .hilite {
+ background: #acf;
+}
+
+.calendar .combo .active {
+ border-top: 1px solid #46a;
+ border-bottom: 1px solid #46a;
+ background: #eef;
+ font-weight: bold;
+}
+
+.calendar td.time {
+ border-top: 1px solid #000;
+ padding: 1px 0px;
+ text-align: center;
+ background-color: #f4f0e8;
+}
+
+.calendar td.time .hour,
+.calendar td.time .minute,
+.calendar td.time .ampm {
+ padding: 0px 3px 0px 4px;
+ border: 1px solid #889;
+ font-weight: bold;
+ background-color: #fff;
+}
+
+.calendar td.time .ampm {
+ text-align: center;
+}
+
+.calendar td.time .colon {
+ padding: 0px 2px 0px 3px;
+ font-weight: bold;
+}
+
+.calendar td.time span.hilite {
+ border-color: #000;
+ background-color: #667;
+ color: #fff;
+}
+
+.calendar td.time span.active {
+ border-color: #f00;
+ background-color: #000;
+ color: #0f0;
+}
diff --git a/WebContent/themes/default/jscalendar/calendar-blue2.css b/WebContent/themes/default/jscalendar/calendar-blue2.css
new file mode 100644
index 0000000000..47128ecb0f
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/calendar-blue2.css
@@ -0,0 +1,236 @@
+/* The main calendar widget. DIV containing a table. */
+
+div.calendar { position: relative; }
+
+.calendar, .calendar table {
+ border: 1px solid #206A9B;
+ font-size: 11px;
+ color: #000;
+ cursor: default;
+ background: #F1F8FC;
+ font-family: tahoma,verdana,sans-serif;
+}
+
+/* Header part -- contains navigation buttons and day names. */
+
+.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */
+ text-align: center; /* They are the navigation buttons */
+ padding: 2px; /* Make the buttons seem like they're pressing */
+}
+
+.calendar .nav {
+ background: #007ED1 url(menuarrow2.gif) no-repeat 100% 100%;
+}
+
+.calendar thead .title { /* This holds the current "month, year" */
+ font-weight: bold; /* Pressing it will take you to the current date */
+ text-align: center;
+ background: #000;
+ color: #fff;
+ padding: 2px;
+}
+
+.calendar thead tr { /* Row <TR> containing navigation buttons */
+ background: #007ED1;
+ color: #fff;
+}
+
+.calendar thead .daynames { /* Row <TR> containing the day names */
+ background: #C7E1F3;
+}
+
+.calendar thead .name { /* Cells <TD> containing the day names */
+ border-bottom: 1px solid #206A9B;
+ padding: 2px;
+ text-align: center;
+ color: #000;
+}
+
+.calendar thead .weekend { /* How a weekend day name shows in header */
+ color: #a66;
+}
+
+.calendar thead .hilite { /* How do the buttons in header appear when hover */
+ background-color: #34ABFA;
+ color: #000;
+ border: 1px solid #016DC5;
+ padding: 1px;
+}
+
+.calendar thead .active { /* Active (pressed) buttons in header */
+ background-color: #006AA9;
+ border: 1px solid #008AFF;
+ padding: 2px 0px 0px 2px;
+}
+
+/* The body part -- contains all the days in month. */
+
+.calendar tbody .day { /* Cells <TD> containing month days dates */
+ width: 2em;
+ color: #456;
+ text-align: right;
+ padding: 2px 4px 2px 2px;
+}
+.calendar tbody .day.othermonth {
+ font-size: 80%;
+ color: #bbb;
+}
+.calendar tbody .day.othermonth.oweekend {
+ color: #fbb;
+}
+
+.calendar table .wn {
+ padding: 2px 3px 2px 2px;
+ border-right: 1px solid #000;
+ background: #C7E1F3;
+}
+
+.calendar tbody .rowhilite td {
+ background: #def;
+}
+
+.calendar tbody .rowhilite td.wn {
+ background: #F1F8FC;
+}
+
+.calendar tbody td.hilite { /* Hovered cells <TD> */
+ background: #def;
+ padding: 1px 3px 1px 1px;
+ border: 1px solid #8FC4E8;
+}
+
+.calendar tbody td.active { /* Active (pressed) cells <TD> */
+ background: #cde;
+ padding: 2px 2px 0px 2px;
+}
+
+.calendar tbody td.selected { /* Cell showing today date */
+ font-weight: bold;
+ border: 1px solid #000;
+ padding: 1px 3px 1px 1px;
+ background: #fff;
+ color: #000;
+}
+
+.calendar tbody td.weekend { /* Cells showing weekend days */
+ color: #a66;
+}
+
+.calendar tbody td.today { /* Cell showing selected date */
+ font-weight: bold;
+ color: #D50000;
+}
+
+.calendar tbody .disabled { color: #999; }
+
+.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */
+ visibility: hidden;
+}
+
+.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */
+ display: none;
+}
+
+/* The footer part -- status bar and "Close" button */
+
+.calendar tfoot .footrow { /* The <TR> in footer (only one right now) */
+ text-align: center;
+ background: #206A9B;
+ color: #fff;
+}
+
+.calendar tfoot .ttip { /* Tooltip (status bar) cell <TD> */
+ background: #000;
+ color: #fff;
+ border-top: 1px solid #206A9B;
+ padding: 1px;
+}
+
+.calendar tfoot .hilite { /* Hover style for buttons in footer */
+ background: #B8DAF0;
+ border: 1px solid #178AEB;
+ color: #000;
+ padding: 1px;
+}
+
+.calendar tfoot .active { /* Active (pressed) style for buttons in footer */
+ background: #006AA9;
+ padding: 2px 0px 0px 2px;
+}
+
+/* Combo boxes (menus that display months/years for direct selection) */
+
+.calendar .combo {
+ position: absolute;
+ display: none;
+ top: 0px;
+ left: 0px;
+ width: 4em;
+ cursor: default;
+ border: 1px solid #655;
+ background: #def;
+ color: #000;
+ font-size: 90%;
+ z-index: 100;
+}
+
+.calendar .combo .label,
+.calendar .combo .label-IEfix {
+ text-align: center;
+ padding: 1px;
+}
+
+.calendar .combo .label-IEfix {
+ width: 4em;
+}
+
+.calendar .combo .hilite {
+ background: #34ABFA;
+ border-top: 1px solid #46a;
+ border-bottom: 1px solid #46a;
+ font-weight: bold;
+}
+
+.calendar .combo .active {
+ border-top: 1px solid #46a;
+ border-bottom: 1px solid #46a;
+ background: #F1F8FC;
+ font-weight: bold;
+}
+
+.calendar td.time {
+ border-top: 1px solid #000;
+ padding: 1px 0px;
+ text-align: center;
+ background-color: #E3F0F9;
+}
+
+.calendar td.time .hour,
+.calendar td.time .minute,
+.calendar td.time .ampm {
+ padding: 0px 3px 0px 4px;
+ border: 1px solid #889;
+ font-weight: bold;
+ background-color: #F1F8FC;
+}
+
+.calendar td.time .ampm {
+ text-align: center;
+}
+
+.calendar td.time .colon {
+ padding: 0px 2px 0px 3px;
+ font-weight: bold;
+}
+
+.calendar td.time span.hilite {
+ border-color: #000;
+ background-color: #267DB7;
+ color: #fff;
+}
+
+.calendar td.time span.active {
+ border-color: red;
+ background-color: #000;
+ color: #A5FF00;
+}
diff --git a/WebContent/themes/default/jscalendar/calendar-brown.css b/WebContent/themes/default/jscalendar/calendar-brown.css
new file mode 100644
index 0000000000..c42da5e0d9
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/calendar-brown.css
@@ -0,0 +1,225 @@
+/* The main calendar widget. DIV containing a table. */
+
+div.calendar { position: relative; }
+
+.calendar, .calendar table {
+ border: 1px solid #655;
+ font-size: 11px;
+ color: #000;
+ cursor: default;
+ background: #ffd;
+ font-family: tahoma,verdana,sans-serif;
+}
+
+/* Header part -- contains navigation buttons and day names. */
+
+.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */
+ text-align: center; /* They are the navigation buttons */
+ padding: 2px; /* Make the buttons seem like they're pressing */
+}
+
+.calendar .nav {
+ background: #edc url(menuarrow.gif) no-repeat 100% 100%;
+}
+
+.calendar thead .title { /* This holds the current "month, year" */
+ font-weight: bold; /* Pressing it will take you to the current date */
+ text-align: center;
+ background: #654;
+ color: #fed;
+ padding: 2px;
+}
+
+.calendar thead .headrow { /* Row <TR> containing navigation buttons */
+ background: #edc;
+ color: #000;
+}
+
+.calendar thead .name { /* Cells <TD> containing the day names */
+ border-bottom: 1px solid #655;
+ padding: 2px;
+ text-align: center;
+ color: #000;
+}
+
+.calendar thead .weekend { /* How a weekend day name shows in header */
+ color: #f00;
+}
+
+.calendar thead .hilite { /* How do the buttons in header appear when hover */
+ background-color: #faa;
+ color: #000;
+ border: 1px solid #f40;
+ padding: 1px;
+}
+
+.calendar thead .active { /* Active (pressed) buttons in header */
+ background-color: #c77;
+ padding: 2px 0px 0px 2px;
+}
+
+.calendar thead .daynames { /* Row <TR> containing the day names */
+ background: #fed;
+}
+
+/* The body part -- contains all the days in month. */
+
+.calendar tbody .day { /* Cells <TD> containing month days dates */
+ width: 2em;
+ text-align: right;
+ padding: 2px 4px 2px 2px;
+}
+.calendar tbody .day.othermonth {
+ font-size: 80%;
+ color: #bbb;
+}
+.calendar tbody .day.othermonth.oweekend {
+ color: #fbb;
+}
+
+.calendar table .wn {
+ padding: 2px 3px 2px 2px;
+ border-right: 1px solid #000;
+ background: #fed;
+}
+
+.calendar tbody .rowhilite td {
+ background: #ddf;
+}
+
+.calendar tbody .rowhilite td.wn {
+ background: #efe;
+}
+
+.calendar tbody td.hilite { /* Hovered cells <TD> */
+ background: #ffe;
+ padding: 1px 3px 1px 1px;
+ border: 1px solid #bbb;
+}
+
+.calendar tbody td.active { /* Active (pressed) cells <TD> */
+ background: #ddc;
+ padding: 2px 2px 0px 2px;
+}
+
+.calendar tbody td.selected { /* Cell showing today date */
+ font-weight: bold;
+ border: 1px solid #000;
+ padding: 1px 3px 1px 1px;
+ background: #fea;
+}
+
+.calendar tbody td.weekend { /* Cells showing weekend days */
+ color: #f00;
+}
+
+.calendar tbody td.today { font-weight: bold; }
+
+.calendar tbody .disabled { color: #999; }
+
+.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */
+ visibility: hidden;
+}
+
+.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */
+ display: none;
+}
+
+/* The footer part -- status bar and "Close" button */
+
+.calendar tfoot .footrow { /* The <TR> in footer (only one right now) */
+ text-align: center;
+ background: #988;
+ color: #000;
+}
+
+.calendar tfoot .ttip { /* Tooltip (status bar) cell <TD> */
+ border-top: 1px solid #655;
+ background: #dcb;
+ color: #840;
+}
+
+.calendar tfoot .hilite { /* Hover style for buttons in footer */
+ background: #faa;
+ border: 1px solid #f40;
+ padding: 1px;
+}
+
+.calendar tfoot .active { /* Active (pressed) style for buttons in footer */
+ background: #c77;
+ padding: 2px 0px 0px 2px;
+}
+
+/* Combo boxes (menus that display months/years for direct selection) */
+
+.calendar .combo {
+ position: absolute;
+ display: none;
+ top: 0px;
+ left: 0px;
+ width: 4em;
+ cursor: default;
+ border: 1px solid #655;
+ background: #ffe;
+ color: #000;
+ font-size: 90%;
+ z-index: 100;
+}
+
+.calendar .combo .label,
+.calendar .combo .label-IEfix {
+ text-align: center;
+ padding: 1px;
+}
+
+.calendar .combo .label-IEfix {
+ width: 4em;
+}
+
+.calendar .combo .hilite {
+ background: #fc8;
+}
+
+.calendar .combo .active {
+ border-top: 1px solid #a64;
+ border-bottom: 1px solid #a64;
+ background: #fee;
+ font-weight: bold;
+}
+
+.calendar td.time {
+ border-top: 1px solid #a88;
+ padding: 1px 0px;
+ text-align: center;
+ background-color: #fed;
+}
+
+.calendar td.time .hour,
+.calendar td.time .minute,
+.calendar td.time .ampm {
+ padding: 0px 3px 0px 4px;
+ border: 1px solid #988;
+ font-weight: bold;
+ background-color: #fff;
+}
+
+.calendar td.time .ampm {
+ text-align: center;
+}
+
+.calendar td.time .colon {
+ padding: 0px 2px 0px 3px;
+ font-weight: bold;
+}
+
+.calendar td.time span.hilite {
+ border-color: #000;
+ background-color: #866;
+ color: #fff;
+}
+
+.calendar td.time span.active {
+ border-color: #f00;
+ background-color: #000;
+ color: #0f0;
+}
diff --git a/WebContent/themes/default/jscalendar/calendar-green.css b/WebContent/themes/default/jscalendar/calendar-green.css
new file mode 100644
index 0000000000..2e1867a0c2
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/calendar-green.css
@@ -0,0 +1,229 @@
+/* The main calendar widget. DIV containing a table. */
+
+div.calendar { position: relative; }
+
+.calendar, .calendar table {
+ border: 1px solid #565;
+ font-size: 11px;
+ color: #000;
+ cursor: default;
+ background: #efe;
+ font-family: tahoma,verdana,sans-serif;
+}
+
+/* Header part -- contains navigation buttons and day names. */
+
+.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */
+ text-align: center; /* They are the navigation buttons */
+ padding: 2px; /* Make the buttons seem like they're pressing */
+ background: #676;
+ color: #fff;
+ font-size: 90%;
+}
+
+.calendar .nav {
+ background: #676 url(menuarrow.gif) no-repeat 100% 100%;
+}
+
+.calendar thead .title { /* This holds the current "month, year" */
+ font-weight: bold; /* Pressing it will take you to the current date */
+ text-align: center;
+ padding: 2px;
+ background: #250;
+ color: #efa;
+}
+
+.calendar thead .headrow { /* Row <TR> containing navigation buttons */
+}
+
+.calendar thead .name { /* Cells <TD> containing the day names */
+ border-bottom: 1px solid #565;
+ padding: 2px;
+ text-align: center;
+ color: #000;
+}
+
+.calendar thead .weekend { /* How a weekend day name shows in header */
+ color: #a66;
+}
+
+.calendar thead .hilite { /* How do the buttons in header appear when hover */
+ background-color: #afa;
+ color: #000;
+ border: 1px solid #084;
+ padding: 1px;
+}
+
+.calendar thead .active { /* Active (pressed) buttons in header */
+ background-color: #7c7;
+ padding: 2px 0px 0px 2px;
+}
+
+.calendar thead .daynames { /* Row <TR> containing the day names */
+ background: #dfb;
+}
+
+/* The body part -- contains all the days in month. */
+
+.calendar tbody .day { /* Cells <TD> containing month days dates */
+ width: 2em;
+ color: #564;
+ text-align: right;
+ padding: 2px 4px 2px 2px;
+}
+.calendar tbody .day.othermonth {
+ font-size: 80%;
+ color: #bbb;
+}
+.calendar tbody .day.othermonth.oweekend {
+ color: #fbb;
+}
+
+.calendar table .wn {
+ padding: 2px 3px 2px 2px;
+ border-right: 1px solid #8a8;
+ background: #dfb;
+}
+
+.calendar tbody .rowhilite td {
+ background: #dfd;
+}
+
+.calendar tbody .rowhilite td.wn {
+ background: #efe;
+}
+
+.calendar tbody td.hilite { /* Hovered cells <TD> */
+ background: #efd;
+ padding: 1px 3px 1px 1px;
+ border: 1px solid #bbb;
+}
+
+.calendar tbody td.active { /* Active (pressed) cells <TD> */
+ background: #dec;
+ padding: 2px 2px 0px 2px;
+}
+
+.calendar tbody td.selected { /* Cell showing today date */
+ font-weight: bold;
+ border: 1px solid #000;
+ padding: 1px 3px 1px 1px;
+ background: #f8fff8;
+ color: #000;
+}
+
+.calendar tbody td.weekend { /* Cells showing weekend days */
+ color: #a66;
+}
+
+.calendar tbody td.today { font-weight: bold; color: #0a0; }
+
+.calendar tbody .disabled { color: #999; }
+
+.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */
+ visibility: hidden;
+}
+
+.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */
+ display: none;
+}
+
+/* The footer part -- status bar and "Close" button */
+
+.calendar tfoot .footrow { /* The <TR> in footer (only one right now) */
+ text-align: center;
+ background: #565;
+ color: #fff;
+}
+
+.calendar tfoot .ttip { /* Tooltip (status bar) cell <TD> */
+ padding: 2px;
+ background: #250;
+ color: #efa;
+}
+
+.calendar tfoot .hilite { /* Hover style for buttons in footer */
+ background: #afa;
+ border: 1px solid #084;
+ color: #000;
+ padding: 1px;
+}
+
+.calendar tfoot .active { /* Active (pressed) style for buttons in footer */
+ background: #7c7;
+ padding: 2px 0px 0px 2px;
+}
+
+/* Combo boxes (menus that display months/years for direct selection) */
+
+.calendar .combo {
+ position: absolute;
+ display: none;
+ top: 0px;
+ left: 0px;
+ width: 4em;
+ cursor: default;
+ border: 1px solid #565;
+ background: #efd;
+ color: #000;
+ font-size: 90%;
+ z-index: 100;
+}
+
+.calendar .combo .label,
+.calendar .combo .label-IEfix {
+ text-align: center;
+ padding: 1px;
+}
+
+.calendar .combo .label-IEfix {
+ width: 4em;
+}
+
+.calendar .combo .hilite {
+ background: #af8;
+}
+
+.calendar .combo .active {
+ border-top: 1px solid #6a4;
+ border-bottom: 1px solid #6a4;
+ background: #efe;
+ font-weight: bold;
+}
+
+.calendar td.time {
+ border-top: 1px solid #8a8;
+ padding: 1px 0px;
+ text-align: center;
+ background-color: #dfb;
+}
+
+.calendar td.time .hour,
+.calendar td.time .minute,
+.calendar td.time .ampm {
+ padding: 0px 3px 0px 4px;
+ border: 1px solid #898;
+ font-weight: bold;
+ background-color: #fff;
+}
+
+.calendar td.time .ampm {
+ text-align: center;
+}
+
+.calendar td.time .colon {
+ padding: 0px 2px 0px 3px;
+ font-weight: bold;
+}
+
+.calendar td.time span.hilite {
+ border-color: #000;
+ background-color: #686;
+ color: #fff;
+}
+
+.calendar td.time span.active {
+ border-color: #f00;
+ background-color: #000;
+ color: #0f0;
+}
diff --git a/WebContent/themes/default/jscalendar/calendar-setup.js b/WebContent/themes/default/jscalendar/calendar-setup.js
new file mode 100644
index 0000000000..7f3855c07a
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/calendar-setup.js
@@ -0,0 +1,200 @@
+/* Copyright Mihai Bazon, 2002, 2003 | http://dynarch.com/mishoo/
+ * ---------------------------------------------------------------------------
+ *
+ * The DHTML Calendar
+ *
+ * Details and latest version at:
+ * http://dynarch.com/mishoo/calendar.epl
+ *
+ * This script is distributed under the GNU Lesser General Public License.
+ * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html
+ *
+ * This file defines helper functions for setting up the calendar. They are
+ * intended to help non-programmers get a working calendar on their site
+ * quickly. This script should not be seen as part of the calendar. It just
+ * shows you what one can do with the calendar, while in the same time
+ * providing a quick and simple method for setting it up. If you need
+ * exhaustive customization of the calendar creation process feel free to
+ * modify this code to suit your needs (this is recommended and much better
+ * than modifying calendar.js itself).
+ */
+
+// $Id: calendar-setup.js,v 1.1 2005/09/28 10:04:05 se Exp $
+
+/**
+ * This function "patches" an input field (or other element) to use a calendar
+ * widget for date selection.
+ *
+ * The "params" is a single object that can have the following properties:
+ *
+ * prop. name | description
+ * -------------------------------------------------------------------------------------------------
+ * inputField | the ID of an input field to store the date
+ * displayArea | the ID of a DIV or other element to show the date
+ * button | ID of a button or other element that will trigger the calendar
+ * eventName | event that will trigger the calendar, without the "on" prefix (default: "click")
+ * ifFormat | date format that will be stored in the input field
+ * daFormat | the date format that will be used to display the date in displayArea
+ * singleClick | (true/false) wether the calendar is in single click mode or not (default: true)
+ * firstDay | numeric: 0 to 6. "0" means display Sunday first, "1" means display Monday first, etc.
+ * align | alignment (default: "Br"); if you don't know what's this see the calendar documentation
+ * range | array with 2 elements. Default: [1900, 2999] -- the range of years available
+ * weekNumbers | (true/false) if it's true (default) the calendar will display week numbers
+ * flat | null or element ID; if not null the calendar will be a flat calendar having the parent with the given ID
+ * flatCallback | function that receives a JS Date object and returns an URL to point the browser to (for flat calendar)
+ * disableFunc | function that receives a JS Date object and should return true if that date has to be disabled in the calendar
+ * onSelect | function that gets called when a date is selected. You don't _have_ to supply this (the default is generally okay)
+ * onClose | function that gets called when the calendar is closed. [default]
+ * onUpdate | function that gets called after the date is updated in the input field. Receives a reference to the calendar.
+ * date | the date that the calendar will be initially displayed to
+ * showsTime | default: false; if true the calendar will include a time selector
+ * timeFormat | the time format; can be "12" or "24", default is "12"
+ * electric | if true (default) then given fields/date areas are updated for each move; otherwise they're updated only on close
+ * step | configures the step of the years in drop-down boxes; default: 2
+ * position | configures the calendar absolute position; default: null
+ * cache | if "true" (but default: "false") it will reuse the same calendar object, where possible
+ * showOthers | if "true" (but default: "false") it will show days from other months too
+ *
+ * None of them is required, they all have default values. However, if you
+ * pass none of "inputField", "displayArea" or "button" you'll get a warning
+ * saying "nothing to setup".
+ */
+Calendar.setup = function (params) {
+ function param_default(pname, def) { if (typeof params[pname] == "undefined") { params[pname] = def; } };
+
+ param_default("inputField", null);
+ param_default("displayArea", null);
+ param_default("button", null);
+ param_default("eventName", "click");
+ param_default("ifFormat", "%Y/%m/%d");
+ param_default("daFormat", "%Y/%m/%d");
+ param_default("singleClick", true);
+ param_default("disableFunc", null);
+ param_default("dateStatusFunc", params["disableFunc"]); // takes precedence if both are defined
+ param_default("dateText", null);
+ param_default("firstDay", null);
+ param_default("align", "Br");
+ param_default("range", [1900, 2999]);
+ param_default("weekNumbers", true);
+ param_default("flat", null);
+ param_default("flatCallback", null);
+ param_default("onSelect", null);
+ param_default("onClose", null);
+ param_default("onUpdate", null);
+ param_default("date", null);
+ param_default("showsTime", false);
+ param_default("timeFormat", "24");
+ param_default("electric", true);
+ param_default("step", 2);
+ param_default("position", null);
+ param_default("cache", false);
+ param_default("showOthers", false);
+ param_default("multiple", null);
+
+ var tmp = ["inputField", "displayArea", "button"];
+ for (var i in tmp) {
+ if (typeof params[tmp[i]] == "string") {
+ params[tmp[i]] = document.getElementById(params[tmp[i]]);
+ }
+ }
+ if (!(params.flat || params.multiple || params.inputField || params.displayArea || params.button)) {
+ alert("Calendar.setup:\n Nothing to setup (no fields found). Please check your code");
+ return false;
+ }
+
+ function onSelect(cal) {
+ var p = cal.params;
+ var update = (cal.dateClicked || p.electric);
+ if (update && p.inputField) {
+ p.inputField.value = cal.date.print(p.ifFormat);
+ if (typeof p.inputField.onchange == "function")
+ p.inputField.onchange();
+ }
+ if (update && p.displayArea)
+ p.displayArea.innerHTML = cal.date.print(p.daFormat);
+ if (update && typeof p.onUpdate == "function")
+ p.onUpdate(cal);
+ if (update && p.flat) {
+ if (typeof p.flatCallback == "function")
+ p.flatCallback(cal);
+ }
+ if (update && p.singleClick && cal.dateClicked)
+ cal.callCloseHandler();
+ };
+
+ if (params.flat != null) {
+ if (typeof params.flat == "string")
+ params.flat = document.getElementById(params.flat);
+ if (!params.flat) {
+ alert("Calendar.setup:\n Flat specified but can't find parent.");
+ return false;
+ }
+ var cal = new Calendar(params.firstDay, params.date, params.onSelect || onSelect);
+ cal.showsOtherMonths = params.showOthers;
+ cal.showsTime = params.showsTime;
+ cal.time24 = (params.timeFormat == "24");
+ cal.params = params;
+ cal.weekNumbers = params.weekNumbers;
+ cal.setRange(params.range[0], params.range[1]);
+ cal.setDateStatusHandler(params.dateStatusFunc);
+ cal.getDateText = params.dateText;
+ if (params.ifFormat) {
+ cal.setDateFormat(params.ifFormat);
+ }
+ if (params.inputField && typeof params.inputField.value == "string") {
+ cal.parseDate(params.inputField.value);
+ }
+ cal.create(params.flat);
+ cal.show();
+ return false;
+ }
+
+ var triggerEl = params.button || params.displayArea || params.inputField;
+ triggerEl["on" + params.eventName] = function() {
+ var dateEl = params.inputField || params.displayArea;
+ var dateFmt = params.inputField ? params.ifFormat : params.daFormat;
+ var mustCreate = false;
+ var cal = window.calendar;
+ if (dateEl)
+ params.date = Date.parseDate(dateEl.value || dateEl.innerHTML, dateFmt);
+ if (!(cal && params.cache)) {
+ window.calendar = cal = new Calendar(params.firstDay,
+ params.date,
+ params.onSelect || onSelect,
+ params.onClose || function(cal) { cal.hide(); });
+ cal.showsTime = params.showsTime;
+ cal.time24 = (params.timeFormat == "24");
+ cal.weekNumbers = params.weekNumbers;
+ mustCreate = true;
+ } else {
+ if (params.date)
+ cal.setDate(params.date);
+ cal.hide();
+ }
+ if (params.multiple) {
+ cal.multiple = {};
+ for (var i = params.multiple.length; --i >= 0;) {
+ var d = params.multiple[i];
+ var ds = d.print("%Y%m%d");
+ cal.multiple[ds] = d;
+ }
+ }
+ cal.showsOtherMonths = params.showOthers;
+ cal.yearStep = params.step;
+ cal.setRange(params.range[0], params.range[1]);
+ cal.params = params;
+ cal.setDateStatusHandler(params.dateStatusFunc);
+ cal.getDateText = params.dateText;
+ cal.setDateFormat(dateFmt);
+ if (mustCreate)
+ cal.create();
+ cal.refresh();
+ if (!params.position)
+ cal.showAtElement(params.button || params.displayArea || params.inputField, params.align);
+ else
+ cal.showAt(params.position[0], params.position[1]);
+ return false;
+ };
+
+ return cal;
+};
diff --git a/WebContent/themes/default/jscalendar/calendar-setup_stripped.js b/WebContent/themes/default/jscalendar/calendar-setup_stripped.js
new file mode 100644
index 0000000000..91c927f82e
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/calendar-setup_stripped.js
@@ -0,0 +1,21 @@
+/* Copyright Mihai Bazon, 2002, 2003 | http://dynarch.com/mishoo/
+ * ---------------------------------------------------------------------------
+ *
+ * The DHTML Calendar
+ *
+ * Details and latest version at:
+ * http://dynarch.com/mishoo/calendar.epl
+ *
+ * This script is distributed under the GNU Lesser General Public License.
+ * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html
+ *
+ * This file defines helper functions for setting up the calendar. They are
+ * intended to help non-programmers get a working calendar on their site
+ * quickly. This script should not be seen as part of the calendar. It just
+ * shows you what one can do with the calendar, while in the same time
+ * providing a quick and simple method for setting it up. If you need
+ * exhaustive customization of the calendar creation process feel free to
+ * modify this code to suit your needs (this is recommended and much better
+ * than modifying calendar.js itself).
+ */
+ Calendar.setup=function(params){function param_default(pname,def){if(typeof params[pname]=="undefined"){params[pname]=def;}};param_default("inputField",null);param_default("displayArea",null);param_default("button",null);param_default("eventName","click");param_default("ifFormat","%Y/%m/%d");param_default("daFormat","%Y/%m/%d");param_default("singleClick",true);param_default("disableFunc",null);param_default("dateStatusFunc",params["disableFunc"]);param_default("dateText",null);param_default("firstDay",null);param_default("align","Br");param_default("range",[1900,2999]);param_default("weekNumbers",true);param_default("flat",null);param_default("flatCallback",null);param_default("onSelect",null);param_default("onClose",null);param_default("onUpdate",null);param_default("date",null);param_default("showsTime",false);param_default("timeFormat","24");param_default("electric",true);param_default("step",2);param_default("position",null);param_default("cache",false);param_default("showOthers",false);param_default("multiple",null);var tmp=["inputField","displayArea","button"];for(var i in tmp){if(typeof params[tmp[i]]=="string"){params[tmp[i]]=document.getElementById(params[tmp[i]]);}}if(!(params.flat||params.multiple||params.inputField||params.displayArea||params.button)){alert("Calendar.setup:\n Nothing to setup (no fields found). Please check your code");return false;}function onSelect(cal){var p=cal.params;var update=(cal.dateClicked||p.electric);if(update&&p.inputField){p.inputField.value=cal.date.print(p.ifFormat);if(typeof p.inputField.onchange=="function")p.inputField.onchange();}if(update&&p.displayArea)p.displayArea.innerHTML=cal.date.print(p.daFormat);if(update&&typeof p.onUpdate=="function")p.onUpdate(cal);if(update&&p.flat){if(typeof p.flatCallback=="function")p.flatCallback(cal);}if(update&&p.singleClick&&cal.dateClicked)cal.callCloseHandler();};if(params.flat!=null){if(typeof params.flat=="string")params.flat=document.getElementById(params.flat);if(!params.flat){alert("Calendar.setup:\n Flat specified but can't find parent.");return false;}var cal=new Calendar(params.firstDay,params.date,params.onSelect||onSelect);cal.showsOtherMonths=params.showOthers;cal.showsTime=params.showsTime;cal.time24=(params.timeFormat=="24");cal.params=params;cal.weekNumbers=params.weekNumbers;cal.setRange(params.range[0],params.range[1]);cal.setDateStatusHandler(params.dateStatusFunc);cal.getDateText=params.dateText;if(params.ifFormat){cal.setDateFormat(params.ifFormat);}if(params.inputField&&typeof params.inputField.value=="string"){cal.parseDate(params.inputField.value);}cal.create(params.flat);cal.show();return false;}var triggerEl=params.button||params.displayArea||params.inputField;triggerEl["on"+params.eventName]=function(){var dateEl=params.inputField||params.displayArea;var dateFmt=params.inputField?params.ifFormat:params.daFormat;var mustCreate=false;var cal=window.calendar;if(dateEl)params.date=Date.parseDate(dateEl.value||dateEl.innerHTML,dateFmt);if(!(cal&&params.cache)){window.calendar=cal=new Calendar(params.firstDay,params.date,params.onSelect||onSelect,params.onClose||function(cal){cal.hide();});cal.showsTime=params.showsTime;cal.time24=(params.timeFormat=="24");cal.weekNumbers=params.weekNumbers;mustCreate=true;}else{if(params.date)cal.setDate(params.date);cal.hide();}if(params.multiple){cal.multiple={};for(var i=params.multiple.length;--i>=0;){var d=params.multiple[i];var ds=d.print("%Y%m%d");cal.multiple[ds]=d;}}cal.showsOtherMonths=params.showOthers;cal.yearStep=params.step;cal.setRange(params.range[0],params.range[1]);cal.params=params;cal.setDateStatusHandler(params.dateStatusFunc);cal.getDateText=params.dateText;cal.setDateFormat(dateFmt);if(mustCreate)cal.create();cal.refresh();if(!params.position)cal.showAtElement(params.button||params.displayArea||params.inputField,params.align);else cal.showAt(params.position[0],params.position[1]);return false;};return cal;}; \ No newline at end of file
diff --git a/WebContent/themes/default/jscalendar/calendar-system.css b/WebContent/themes/default/jscalendar/calendar-system.css
new file mode 100644
index 0000000000..b22488572e
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/calendar-system.css
@@ -0,0 +1,251 @@
+/* The main calendar widget. DIV containing a table. */
+
+.calendar {
+ position: relative;
+ display: none;
+ border: 1px solid;
+ border-color: #fff #000 #000 #fff;
+ font-size: 11px;
+ cursor: default;
+ background: Window;
+ color: WindowText;
+ font-family: tahoma,verdana,sans-serif;
+}
+
+.calendar table {
+ border: 1px solid;
+ border-color: #fff #000 #000 #fff;
+ font-size: 11px;
+ cursor: default;
+ background: Window;
+ color: WindowText;
+ font-family: tahoma,verdana,sans-serif;
+}
+
+/* Header part -- contains navigation buttons and day names. */
+
+.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */
+ text-align: center;
+ padding: 1px;
+ border: 1px solid;
+ border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+ background: ButtonFace;
+}
+
+.calendar .nav {
+ background: ButtonFace url(menuarrow.gif) no-repeat 100% 100%;
+}
+
+.calendar thead .title { /* This holds the current "month, year" */
+ font-weight: bold;
+ padding: 1px;
+ border: 1px solid #000;
+ background: ActiveCaption;
+ color: CaptionText;
+ text-align: center;
+}
+
+.calendar thead .headrow { /* Row <TR> containing navigation buttons */
+}
+
+.calendar thead .daynames { /* Row <TR> containing the day names */
+}
+
+.calendar thead .name { /* Cells <TD> containing the day names */
+ border-bottom: 1px solid ButtonShadow;
+ padding: 2px;
+ text-align: center;
+ background: ButtonFace;
+ color: ButtonText;
+}
+
+.calendar thead .weekend { /* How a weekend day name shows in header */
+ color: #f00;
+}
+
+.calendar thead .hilite { /* How do the buttons in header appear when hover */
+ border: 2px solid;
+ padding: 0px;
+ border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+}
+
+.calendar thead .active { /* Active (pressed) buttons in header */
+ border-width: 1px;
+ padding: 2px 0px 0px 2px;
+ border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
+}
+
+/* The body part -- contains all the days in month. */
+
+.calendar tbody .day { /* Cells <TD> containing month days dates */
+ width: 2em;
+ text-align: right;
+ padding: 2px 4px 2px 2px;
+}
+.calendar tbody .day.othermonth {
+ font-size: 80%;
+ color: #aaa;
+}
+.calendar tbody .day.othermonth.oweekend {
+ color: #faa;
+}
+
+.calendar table .wn {
+ padding: 2px 3px 2px 2px;
+ border-right: 1px solid ButtonShadow;
+ background: ButtonFace;
+ color: ButtonText;
+}
+
+.calendar tbody .rowhilite td {
+ background: Highlight;
+ color: HighlightText;
+}
+
+.calendar tbody td.hilite { /* Hovered cells <TD> */
+ padding: 1px 3px 1px 1px;
+ border-top: 1px solid #fff;
+ border-right: 1px solid #000;
+ border-bottom: 1px solid #000;
+ border-left: 1px solid #fff;
+}
+
+.calendar tbody td.active { /* Active (pressed) cells <TD> */
+ padding: 2px 2px 0px 2px;
+ border: 1px solid;
+ border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
+}
+
+.calendar tbody td.selected { /* Cell showing selected date */
+ font-weight: bold;
+ border: 1px solid;
+ border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
+ padding: 2px 2px 0px 2px;
+ background: ButtonFace;
+ color: ButtonText;
+}
+
+.calendar tbody td.weekend { /* Cells showing weekend days */
+ color: #f00;
+}
+
+.calendar tbody td.today { /* Cell showing today date */
+ font-weight: bold;
+ color: #00f;
+}
+
+.calendar tbody td.disabled { color: GrayText; }
+
+.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */
+ visibility: hidden;
+}
+
+.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */
+ display: none;
+}
+
+/* The footer part -- status bar and "Close" button */
+
+.calendar tfoot .footrow { /* The <TR> in footer (only one right now) */
+}
+
+.calendar tfoot .ttip { /* Tooltip (status bar) cell <TD> */
+ background: ButtonFace;
+ padding: 1px;
+ border: 1px solid;
+ border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
+ color: ButtonText;
+ text-align: center;
+}
+
+.calendar tfoot .hilite { /* Hover style for buttons in footer */
+ border-top: 1px solid #fff;
+ border-right: 1px solid #000;
+ border-bottom: 1px solid #000;
+ border-left: 1px solid #fff;
+ padding: 1px;
+ background: #e4e0d8;
+}
+
+.calendar tfoot .active { /* Active (pressed) style for buttons in footer */
+ padding: 2px 0px 0px 2px;
+ border-top: 1px solid #000;
+ border-right: 1px solid #fff;
+ border-bottom: 1px solid #fff;
+ border-left: 1px solid #000;
+}
+
+/* Combo boxes (menus that display months/years for direct selection) */
+
+.calendar .combo {
+ position: absolute;
+ display: none;
+ width: 4em;
+ top: 0px;
+ left: 0px;
+ cursor: default;
+ border: 1px solid;
+ border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
+ background: Menu;
+ color: MenuText;
+ font-size: 90%;
+ padding: 1px;
+ z-index: 100;
+}
+
+.calendar .combo .label,
+.calendar .combo .label-IEfix {
+ text-align: center;
+ padding: 1px;
+}
+
+.calendar .combo .label-IEfix {
+ width: 4em;
+}
+
+.calendar .combo .active {
+ padding: 0px;
+ border: 1px solid #000;
+}
+
+.calendar .combo .hilite {
+ background: Highlight;
+ color: HighlightText;
+}
+
+.calendar td.time {
+ border-top: 1px solid ButtonShadow;
+ padding: 1px 0px;
+ text-align: center;
+ background-color: ButtonFace;
+}
+
+.calendar td.time .hour,
+.calendar td.time .minute,
+.calendar td.time .ampm {
+ padding: 0px 3px 0px 4px;
+ border: 1px solid #889;
+ font-weight: bold;
+ background-color: Menu;
+}
+
+.calendar td.time .ampm {
+ text-align: center;
+}
+
+.calendar td.time .colon {
+ padding: 0px 2px 0px 3px;
+ font-weight: bold;
+}
+
+.calendar td.time span.hilite {
+ border-color: #000;
+ background-color: Highlight;
+ color: HighlightText;
+}
+
+.calendar td.time span.active {
+ border-color: #f00;
+ background-color: #000;
+ color: #0f0;
+}
diff --git a/WebContent/themes/default/jscalendar/calendar-tas.css b/WebContent/themes/default/jscalendar/calendar-tas.css
new file mode 100644
index 0000000000..c2f872168c
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/calendar-tas.css
@@ -0,0 +1,239 @@
+/* The main calendar widget. DIV containing a table. */
+
+div.calendar { position: relative; }
+
+.calendar, .calendar table {
+ border: 1px solid #655;
+ font-size: 11px;
+ color: #000;
+ cursor: default;
+ background: #ffd;
+ font-family: tahoma,verdana,sans-serif;
+ filter:
+progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#DDDCCC,EndColorStr=#FFFFFF);
+}
+
+/* Header part -- contains navigation buttons and day names. */
+
+.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */
+ text-align: center; /* They are the navigation buttons */
+ padding: 2px; /* Make the buttons seem like they're pressing */
+ color:#363636;
+}
+
+.calendar .nav {
+ background: #edc url(menuarrow.gif) no-repeat 100% 100%;
+}
+
+.calendar thead .title { /* This holds the current "month, year" */
+ font-weight: bold; /* Pressing it will take you to the current date */
+ text-align: center;
+ background: #654;
+ color: #363636;
+ padding: 2px;
+ filter:
+progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#ffffff,EndColorStr=#dddccc);
+}
+
+.calendar thead .headrow { /* Row <TR> containing navigation buttons */
+ /*background: #3B86A0;*/
+ color: #363636;
+ font-weight: bold;
+filter:
+progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#ffffff,EndColorStr=#3b86a0);
+}
+
+.calendar thead .name { /* Cells <TD> containing the day names */
+ border-bottom: 1px solid #655;
+ padding: 2px;
+ text-align: center;
+ color: #363636;
+ filter:
+progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#DDDCCC,EndColorStr=#FFFFFF);
+}
+
+.calendar thead .weekend { /* How a weekend day name shows in header */
+ color: #f00;
+}
+
+.calendar thead .hilite { /* How do the buttons in header appear when hover */
+ background-color: #ffcc86;
+ color: #000;
+ border: 1px solid #b59345;
+ padding: 1px;
+}
+
+.calendar thead .active { /* Active (pressed) buttons in header */
+ background-color: #c77;
+ padding: 2px 0px 0px 2px;
+}
+
+.calendar thead .daynames { /* Row <TR> containing the day names */
+ background: #fed;
+}
+
+/* The body part -- contains all the days in month. */
+
+.calendar tbody .day { /* Cells <TD> containing month days dates */
+ width: 2em;
+ text-align: right;
+ padding: 2px 4px 2px 2px;
+}
+.calendar tbody .day.othermonth {
+ font-size: 80%;
+ color: #aaa;
+}
+.calendar tbody .day.othermonth.oweekend {
+ color: #faa;
+}
+
+.calendar table .wn {
+ padding: 2px 3px 2px 2px;
+ border-right: 1px solid #000;
+ background: #fed;
+}
+
+.calendar tbody .rowhilite td {
+ background: #ddf;
+
+}
+
+.calendar tbody .rowhilite td.wn {
+ background: #efe;
+}
+
+.calendar tbody td.hilite { /* Hovered cells <TD> */
+ background: #ffe;
+ padding: 1px 3px 1px 1px;
+ border: 1px solid #bbb;
+}
+
+.calendar tbody td.active { /* Active (pressed) cells <TD> */
+ background: #ddc;
+ padding: 2px 2px 0px 2px;
+}
+
+.calendar tbody td.selected { /* Cell showing today date */
+ font-weight: bold;
+ border: 1px solid #000;
+ padding: 1px 3px 1px 1px;
+ background: #fea;
+}
+
+.calendar tbody td.weekend { /* Cells showing weekend days */
+ color: #f00;
+}
+
+.calendar tbody td.today { font-weight: bold; }
+
+.calendar tbody .disabled { color: #999; }
+
+.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */
+ visibility: hidden;
+}
+
+.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */
+ display: none;
+}
+
+/* The footer part -- status bar and "Close" button */
+
+.calendar tfoot .footrow { /* The <TR> in footer (only one right now) */
+ text-align: center;
+ background: #988;
+ color: #000;
+
+}
+
+.calendar tfoot .ttip { /* Tooltip (status bar) cell <TD> */
+ border-top: 1px solid #655;
+ background: #dcb;
+ color: #363636;
+ font-weight: bold;
+ filter:
+progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#FFFFFF,EndColorStr=#DDDCCC);
+}
+.calendar tfoot .hilite { /* Hover style for buttons in footer */
+ background: #faa;
+ border: 1px solid #f40;
+ padding: 1px;
+}
+
+.calendar tfoot .active { /* Active (pressed) style for buttons in footer */
+ background: #c77;
+ padding: 2px 0px 0px 2px;
+}
+
+/* Combo boxes (menus that display months/years for direct selection) */
+
+.combo {
+ position: absolute;
+ display: none;
+ top: 0px;
+ left: 0px;
+ width: 4em;
+ cursor: default;
+ border: 1px solid #655;
+ background: #ffe;
+ color: #000;
+ font-size: smaller;
+ z-index: 100;
+}
+
+.combo .label,
+.combo .label-IEfix {
+ text-align: center;
+ padding: 1px;
+}
+
+.combo .label-IEfix {
+ width: 4em;
+}
+
+.combo .hilite {
+ background: #fc8;
+}
+
+.combo .active {
+ border-top: 1px solid #a64;
+ border-bottom: 1px solid #a64;
+ background: #fee;
+ font-weight: bold;
+}
+
+.calendar td.time {
+ border-top: 1px solid #a88;
+ padding: 1px 0px;
+ text-align: center;
+ background-color: #fed;
+}
+
+.calendar td.time .hour,
+.calendar td.time .minute,
+.calendar td.time .ampm {
+ padding: 0px 3px 0px 4px;
+ border: 1px solid #988;
+ font-weight: bold;
+ background-color: #fff;
+}
+
+.calendar td.time .ampm {
+ text-align: center;
+}
+
+.calendar td.time .colon {
+ padding: 0px 2px 0px 3px;
+ font-weight: bold;
+}
+
+.calendar td.time span.hilite {
+ border-color: #000;
+ background-color: #866;
+ color: #fff;
+}
+
+.calendar td.time span.active {
+ border-color: #f00;
+ background-color: #000;
+ color: #0f0;
+}
diff --git a/WebContent/themes/default/jscalendar/calendar-win2k-1.css b/WebContent/themes/default/jscalendar/calendar-win2k-1.css
new file mode 100644
index 0000000000..8c5d026657
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/calendar-win2k-1.css
@@ -0,0 +1,271 @@
+/* The main calendar widget. DIV containing a table. */
+
+.calendar {
+ position: relative;
+ display: none;
+ border-top: 2px solid #fff;
+ border-right: 2px solid #000;
+ border-bottom: 2px solid #000;
+ border-left: 2px solid #fff;
+ font-size: 11px;
+ color: #000;
+ cursor: default;
+ background: #d4d0c8;
+ font-family: tahoma,verdana,sans-serif;
+}
+
+.calendar table {
+ border-top: 1px solid #000;
+ border-right: 1px solid #fff;
+ border-bottom: 1px solid #fff;
+ border-left: 1px solid #000;
+ font-size: 11px;
+ color: #000;
+ cursor: default;
+ background: #d4d0c8;
+ font-family: tahoma,verdana,sans-serif;
+}
+
+/* Header part -- contains navigation buttons and day names. */
+
+.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */
+ text-align: center;
+ padding: 1px;
+ border-top: 1px solid #fff;
+ border-right: 1px solid #000;
+ border-bottom: 1px solid #000;
+ border-left: 1px solid #fff;
+}
+
+.calendar .nav {
+ background: transparent url(menuarrow.gif) no-repeat 100% 100%;
+}
+
+.calendar thead .title { /* This holds the current "month, year" */
+ font-weight: bold;
+ padding: 1px;
+ border: 1px solid #000;
+ background: #848078;
+ color: #fff;
+ text-align: center;
+}
+
+.calendar thead .headrow { /* Row <TR> containing navigation buttons */
+}
+
+.calendar thead .daynames { /* Row <TR> containing the day names */
+}
+
+.calendar thead .name { /* Cells <TD> containing the day names */
+ border-bottom: 1px solid #000;
+ padding: 2px;
+ text-align: center;
+ background: #f4f0e8;
+}
+
+.calendar thead .weekend { /* How a weekend day name shows in header */
+ color: #f00;
+}
+
+.calendar thead .hilite { /* How do the buttons in header appear when hover */
+ border-top: 2px solid #fff;
+ border-right: 2px solid #000;
+ border-bottom: 2px solid #000;
+ border-left: 2px solid #fff;
+ padding: 0px;
+ background-color: #e4e0d8;
+}
+
+.calendar thead .active { /* Active (pressed) buttons in header */
+ padding: 2px 0px 0px 2px;
+ border-top: 1px solid #000;
+ border-right: 1px solid #fff;
+ border-bottom: 1px solid #fff;
+ border-left: 1px solid #000;
+ background-color: #c4c0b8;
+}
+
+/* The body part -- contains all the days in month. */
+
+.calendar tbody .day { /* Cells <TD> containing month days dates */
+ width: 2em;
+ text-align: right;
+ padding: 2px 4px 2px 2px;
+}
+.calendar tbody .day.othermonth {
+ font-size: 80%;
+ color: #aaa;
+}
+.calendar tbody .day.othermonth.oweekend {
+ color: #faa;
+}
+
+.calendar table .wn {
+ padding: 2px 3px 2px 2px;
+ border-right: 1px solid #000;
+ background: #f4f0e8;
+}
+
+.calendar tbody .rowhilite td {
+ background: #e4e0d8;
+}
+
+.calendar tbody .rowhilite td.wn {
+ background: #d4d0c8;
+}
+
+.calendar tbody td.hilite { /* Hovered cells <TD> */
+ padding: 1px 3px 1px 1px;
+ border-top: 1px solid #fff;
+ border-right: 1px solid #000;
+ border-bottom: 1px solid #000;
+ border-left: 1px solid #fff;
+}
+
+.calendar tbody td.active { /* Active (pressed) cells <TD> */
+ padding: 2px 2px 0px 2px;
+ border-top: 1px solid #000;
+ border-right: 1px solid #fff;
+ border-bottom: 1px solid #fff;
+ border-left: 1px solid #000;
+}
+
+.calendar tbody td.selected { /* Cell showing selected date */
+ font-weight: bold;
+ border-top: 1px solid #000;
+ border-right: 1px solid #fff;
+ border-bottom: 1px solid #fff;
+ border-left: 1px solid #000;
+ padding: 2px 2px 0px 2px;
+ background: #e4e0d8;
+}
+
+.calendar tbody td.weekend { /* Cells showing weekend days */
+ color: #f00;
+}
+
+.calendar tbody td.today { /* Cell showing today date */
+ font-weight: bold;
+ color: #00f;
+}
+
+.calendar tbody .disabled { color: #999; }
+
+.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */
+ visibility: hidden;
+}
+
+.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */
+ display: none;
+}
+
+/* The footer part -- status bar and "Close" button */
+
+.calendar tfoot .footrow { /* The <TR> in footer (only one right now) */
+}
+
+.calendar tfoot .ttip { /* Tooltip (status bar) cell <TD> */
+ background: #f4f0e8;
+ padding: 1px;
+ border: 1px solid #000;
+ background: #848078;
+ color: #fff;
+ text-align: center;
+}
+
+.calendar tfoot .hilite { /* Hover style for buttons in footer */
+ border-top: 1px solid #fff;
+ border-right: 1px solid #000;
+ border-bottom: 1px solid #000;
+ border-left: 1px solid #fff;
+ padding: 1px;
+ background: #e4e0d8;
+}
+
+.calendar tfoot .active { /* Active (pressed) style for buttons in footer */
+ padding: 2px 0px 0px 2px;
+ border-top: 1px solid #000;
+ border-right: 1px solid #fff;
+ border-bottom: 1px solid #fff;
+ border-left: 1px solid #000;
+}
+
+/* Combo boxes (menus that display months/years for direct selection) */
+
+.calendar .combo {
+ position: absolute;
+ display: none;
+ width: 4em;
+ top: 0px;
+ left: 0px;
+ cursor: default;
+ border-top: 1px solid #fff;
+ border-right: 1px solid #000;
+ border-bottom: 1px solid #000;
+ border-left: 1px solid #fff;
+ background: #e4e0d8;
+ font-size: 90%;
+ padding: 1px;
+ z-index: 100;
+}
+
+.calendar .combo .label,
+.calendar .combo .label-IEfix {
+ text-align: center;
+ padding: 1px;
+}
+
+.calendar .combo .label-IEfix {
+ width: 4em;
+}
+
+.calendar .combo .active {
+ background: #c4c0b8;
+ padding: 0px;
+ border-top: 1px solid #000;
+ border-right: 1px solid #fff;
+ border-bottom: 1px solid #fff;
+ border-left: 1px solid #000;
+}
+
+.calendar .combo .hilite {
+ background: #048;
+ color: #fea;
+}
+
+.calendar td.time {
+ border-top: 1px solid #000;
+ padding: 1px 0px;
+ text-align: center;
+ background-color: #f4f0e8;
+}
+
+.calendar td.time .hour,
+.calendar td.time .minute,
+.calendar td.time .ampm {
+ padding: 0px 3px 0px 4px;
+ border: 1px solid #889;
+ font-weight: bold;
+ background-color: #fff;
+}
+
+.calendar td.time .ampm {
+ text-align: center;
+}
+
+.calendar td.time .colon {
+ padding: 0px 2px 0px 3px;
+ font-weight: bold;
+}
+
+.calendar td.time span.hilite {
+ border-color: #000;
+ background-color: #766;
+ color: #fff;
+}
+
+.calendar td.time span.active {
+ border-color: #f00;
+ background-color: #000;
+ color: #0f0;
+}
diff --git a/WebContent/themes/default/jscalendar/calendar-win2k-2.css b/WebContent/themes/default/jscalendar/calendar-win2k-2.css
new file mode 100644
index 0000000000..6f37b7dcd7
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/calendar-win2k-2.css
@@ -0,0 +1,271 @@
+/* The main calendar widget. DIV containing a table. */
+
+.calendar {
+ position: relative;
+ display: none;
+ border-top: 2px solid #fff;
+ border-right: 2px solid #000;
+ border-bottom: 2px solid #000;
+ border-left: 2px solid #fff;
+ font-size: 11px;
+ color: #000;
+ cursor: default;
+ background: #d4c8d0;
+ font-family: tahoma,verdana,sans-serif;
+}
+
+.calendar table {
+ border-top: 1px solid #000;
+ border-right: 1px solid #fff;
+ border-bottom: 1px solid #fff;
+ border-left: 1px solid #000;
+ font-size: 11px;
+ color: #000;
+ cursor: default;
+ background: #d4c8d0;
+ font-family: tahoma,verdana,sans-serif;
+}
+
+/* Header part -- contains navigation buttons and day names. */
+
+.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */
+ text-align: center;
+ padding: 1px;
+ border-top: 1px solid #fff;
+ border-right: 1px solid #000;
+ border-bottom: 1px solid #000;
+ border-left: 1px solid #fff;
+}
+
+.calendar .nav {
+ background: transparent url(menuarrow.gif) no-repeat 100% 100%;
+}
+
+.calendar thead .title { /* This holds the current "month, year" */
+ font-weight: bold;
+ padding: 1px;
+ border: 1px solid #000;
+ background: #847880;
+ color: #fff;
+ text-align: center;
+}
+
+.calendar thead .headrow { /* Row <TR> containing navigation buttons */
+}
+
+.calendar thead .daynames { /* Row <TR> containing the day names */
+}
+
+.calendar thead .name { /* Cells <TD> containing the day names */
+ border-bottom: 1px solid #000;
+ padding: 2px;
+ text-align: center;
+ background: #f4e8f0;
+}
+
+.calendar thead .weekend { /* How a weekend day name shows in header */
+ color: #f00;
+}
+
+.calendar thead .hilite { /* How do the buttons in header appear when hover */
+ border-top: 2px solid #fff;
+ border-right: 2px solid #000;
+ border-bottom: 2px solid #000;
+ border-left: 2px solid #fff;
+ padding: 0px;
+ background-color: #e4d8e0;
+}
+
+.calendar thead .active { /* Active (pressed) buttons in header */
+ padding: 2px 0px 0px 2px;
+ border-top: 1px solid #000;
+ border-right: 1px solid #fff;
+ border-bottom: 1px solid #fff;
+ border-left: 1px solid #000;
+ background-color: #c4b8c0;
+}
+
+/* The body part -- contains all the days in month. */
+
+.calendar tbody .day { /* Cells <TD> containing month days dates */
+ width: 2em;
+ text-align: right;
+ padding: 2px 4px 2px 2px;
+}
+.calendar tbody .day.othermonth {
+ font-size: 80%;
+ color: #aaa;
+}
+.calendar tbody .day.othermonth.oweekend {
+ color: #faa;
+}
+
+.calendar table .wn {
+ padding: 2px 3px 2px 2px;
+ border-right: 1px solid #000;
+ background: #f4e8f0;
+}
+
+.calendar tbody .rowhilite td {
+ background: #e4d8e0;
+}
+
+.calendar tbody .rowhilite td.wn {
+ background: #d4c8d0;
+}
+
+.calendar tbody td.hilite { /* Hovered cells <TD> */
+ padding: 1px 3px 1px 1px;
+ border-top: 1px solid #fff;
+ border-right: 1px solid #000;
+ border-bottom: 1px solid #000;
+ border-left: 1px solid #fff;
+}
+
+.calendar tbody td.active { /* Active (pressed) cells <TD> */
+ padding: 2px 2px 0px 2px;
+ border-top: 1px solid #000;
+ border-right: 1px solid #fff;
+ border-bottom: 1px solid #fff;
+ border-left: 1px solid #000;
+}
+
+.calendar tbody td.selected { /* Cell showing selected date */
+ font-weight: bold;
+ border-top: 1px solid #000;
+ border-right: 1px solid #fff;
+ border-bottom: 1px solid #fff;
+ border-left: 1px solid #000;
+ padding: 2px 2px 0px 2px;
+ background: #e4d8e0;
+}
+
+.calendar tbody td.weekend { /* Cells showing weekend days */
+ color: #f00;
+}
+
+.calendar tbody td.today { /* Cell showing today date */
+ font-weight: bold;
+ color: #00f;
+}
+
+.calendar tbody .disabled { color: #999; }
+
+.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */
+ visibility: hidden;
+}
+
+.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */
+ display: none;
+}
+
+/* The footer part -- status bar and "Close" button */
+
+.calendar tfoot .footrow { /* The <TR> in footer (only one right now) */
+}
+
+.calendar tfoot .ttip { /* Tooltip (status bar) cell <TD> */
+ background: #f4e8f0;
+ padding: 1px;
+ border: 1px solid #000;
+ background: #847880;
+ color: #fff;
+ text-align: center;
+}
+
+.calendar tfoot .hilite { /* Hover style for buttons in footer */
+ border-top: 1px solid #fff;
+ border-right: 1px solid #000;
+ border-bottom: 1px solid #000;
+ border-left: 1px solid #fff;
+ padding: 1px;
+ background: #e4d8e0;
+}
+
+.calendar tfoot .active { /* Active (pressed) style for buttons in footer */
+ padding: 2px 0px 0px 2px;
+ border-top: 1px solid #000;
+ border-right: 1px solid #fff;
+ border-bottom: 1px solid #fff;
+ border-left: 1px solid #000;
+}
+
+/* Combo boxes (menus that display months/years for direct selection) */
+
+.calendar .combo {
+ position: absolute;
+ display: none;
+ width: 4em;
+ top: 0px;
+ left: 0px;
+ cursor: default;
+ border-top: 1px solid #fff;
+ border-right: 1px solid #000;
+ border-bottom: 1px solid #000;
+ border-left: 1px solid #fff;
+ background: #e4d8e0;
+ font-size: 90%;
+ padding: 1px;
+ z-index: 100;
+}
+
+.calendar .combo .label,
+.calendar .combo .label-IEfix {
+ text-align: center;
+ padding: 1px;
+}
+
+.calendar .combo .label-IEfix {
+ width: 4em;
+}
+
+.calendar .combo .active {
+ background: #d4c8d0;
+ padding: 0px;
+ border-top: 1px solid #000;
+ border-right: 1px solid #fff;
+ border-bottom: 1px solid #fff;
+ border-left: 1px solid #000;
+}
+
+.calendar .combo .hilite {
+ background: #408;
+ color: #fea;
+}
+
+.calendar td.time {
+ border-top: 1px solid #000;
+ padding: 1px 0px;
+ text-align: center;
+ background-color: #f4f0e8;
+}
+
+.calendar td.time .hour,
+.calendar td.time .minute,
+.calendar td.time .ampm {
+ padding: 0px 3px 0px 4px;
+ border: 1px solid #889;
+ font-weight: bold;
+ background-color: #fff;
+}
+
+.calendar td.time .ampm {
+ text-align: center;
+}
+
+.calendar td.time .colon {
+ padding: 0px 2px 0px 3px;
+ font-weight: bold;
+}
+
+.calendar td.time span.hilite {
+ border-color: #000;
+ background-color: #766;
+ color: #fff;
+}
+
+.calendar td.time span.active {
+ border-color: #f00;
+ background-color: #000;
+ color: #0f0;
+}
diff --git a/WebContent/themes/default/jscalendar/calendar-win2k-cold-1.css b/WebContent/themes/default/jscalendar/calendar-win2k-cold-1.css
new file mode 100644
index 0000000000..fa5c093217
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/calendar-win2k-cold-1.css
@@ -0,0 +1,265 @@
+/* The main calendar widget. DIV containing a table. */
+
+.calendar {
+ position: relative;
+ display: none;
+ border-top: 2px solid #fff;
+ border-right: 2px solid #000;
+ border-bottom: 2px solid #000;
+ border-left: 2px solid #fff;
+ font-size: 11px;
+ color: #000;
+ cursor: default;
+ background: #c8d0d4;
+ font-family: tahoma,verdana,sans-serif;
+}
+
+.calendar table {
+ border-top: 1px solid #000;
+ border-right: 1px solid #fff;
+ border-bottom: 1px solid #fff;
+ border-left: 1px solid #000;
+ font-size: 11px;
+ color: #000;
+ cursor: default;
+ background: #c8d0d4;
+ font-family: tahoma,verdana,sans-serif;
+}
+
+/* Header part -- contains navigation buttons and day names. */
+
+.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */
+ text-align: center;
+ padding: 1px;
+ border-top: 1px solid #fff;
+ border-right: 1px solid #000;
+ border-bottom: 1px solid #000;
+ border-left: 1px solid #fff;
+}
+
+.calendar .nav {
+ background: transparent url(menuarrow.gif) no-repeat 100% 100%;
+}
+
+.calendar thead .title { /* This holds the current "month, year" */
+ font-weight: bold;
+ padding: 1px;
+ border: 1px solid #000;
+ background: #788084;
+ color: #fff;
+ text-align: center;
+}
+
+.calendar thead .headrow { /* Row <TR> containing navigation buttons */
+}
+
+.calendar thead .daynames { /* Row <TR> containing the day names */
+}
+
+.calendar thead .name { /* Cells <TD> containing the day names */
+ border-bottom: 1px solid #000;
+ padding: 2px;
+ text-align: center;
+ background: #e8f0f4;
+}
+
+.calendar thead .weekend { /* How a weekend day name shows in header */
+ color: #f00;
+}
+
+.calendar thead .hilite { /* How do the buttons in header appear when hover */
+ border-top: 2px solid #fff;
+ border-right: 2px solid #000;
+ border-bottom: 2px solid #000;
+ border-left: 2px solid #fff;
+ padding: 0px;
+ background-color: #d8e0e4;
+}
+
+.calendar thead .active { /* Active (pressed) buttons in header */
+ padding: 2px 0px 0px 2px;
+ border-top: 1px solid #000;
+ border-right: 1px solid #fff;
+ border-bottom: 1px solid #fff;
+ border-left: 1px solid #000;
+ background-color: #b8c0c4;
+}
+
+/* The body part -- contains all the days in month. */
+
+.calendar tbody .day { /* Cells <TD> containing month days dates */
+ width: 2em;
+ text-align: right;
+ padding: 2px 4px 2px 2px;
+}
+.calendar tbody .day.othermonth {
+ font-size: 80%;
+ color: #aaa;
+}
+.calendar tbody .day.othermonth.oweekend {
+ color: #faa;
+}
+
+.calendar table .wn {
+ padding: 2px 3px 2px 2px;
+ border-right: 1px solid #000;
+ background: #e8f4f0;
+}
+
+.calendar tbody .rowhilite td {
+ background: #d8e4e0;
+}
+
+.calendar tbody .rowhilite td.wn {
+ background: #c8d4d0;
+}
+
+.calendar tbody td.hilite { /* Hovered cells <TD> */
+ padding: 1px 3px 1px 1px;
+ border: 1px solid;
+ border-color: #fff #000 #000 #fff;
+}
+
+.calendar tbody td.active { /* Active (pressed) cells <TD> */
+ padding: 2px 2px 0px 2px;
+ border: 1px solid;
+ border-color: #000 #fff #fff #000;
+}
+
+.calendar tbody td.selected { /* Cell showing selected date */
+ font-weight: bold;
+ padding: 2px 2px 0px 2px;
+ border: 1px solid;
+ border-color: #000 #fff #fff #000;
+ background: #d8e0e4;
+}
+
+.calendar tbody td.weekend { /* Cells showing weekend days */
+ color: #f00;
+}
+
+.calendar tbody td.today { /* Cell showing today date */
+ font-weight: bold;
+ color: #00f;
+}
+
+.calendar tbody .disabled { color: #999; }
+
+.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */
+ visibility: hidden;
+}
+
+.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */
+ display: none;
+}
+
+/* The footer part -- status bar and "Close" button */
+
+.calendar tfoot .footrow { /* The <TR> in footer (only one right now) */
+}
+
+.calendar tfoot .ttip { /* Tooltip (status bar) cell <TD> */
+ background: #e8f0f4;
+ padding: 1px;
+ border: 1px solid #000;
+ background: #788084;
+ color: #fff;
+ text-align: center;
+}
+
+.calendar tfoot .hilite { /* Hover style for buttons in footer */
+ border-top: 1px solid #fff;
+ border-right: 1px solid #000;
+ border-bottom: 1px solid #000;
+ border-left: 1px solid #fff;
+ padding: 1px;
+ background: #d8e0e4;
+}
+
+.calendar tfoot .active { /* Active (pressed) style for buttons in footer */
+ padding: 2px 0px 0px 2px;
+ border-top: 1px solid #000;
+ border-right: 1px solid #fff;
+ border-bottom: 1px solid #fff;
+ border-left: 1px solid #000;
+}
+
+/* Combo boxes (menus that display months/years for direct selection) */
+
+.calendar .combo {
+ position: absolute;
+ display: none;
+ width: 4em;
+ top: 0px;
+ left: 0px;
+ cursor: default;
+ border-top: 1px solid #fff;
+ border-right: 1px solid #000;
+ border-bottom: 1px solid #000;
+ border-left: 1px solid #fff;
+ background: #d8e0e4;
+ font-size: 90%;
+ padding: 1px;
+ z-index: 100;
+}
+
+.calendar .combo .label,
+.calendar .combo .label-IEfix {
+ text-align: center;
+ padding: 1px;
+}
+
+.calendar .combo .label-IEfix {
+ width: 4em;
+}
+
+.calendar .combo .active {
+ background: #c8d0d4;
+ padding: 0px;
+ border-top: 1px solid #000;
+ border-right: 1px solid #fff;
+ border-bottom: 1px solid #fff;
+ border-left: 1px solid #000;
+}
+
+.calendar .combo .hilite {
+ background: #048;
+ color: #aef;
+}
+
+.calendar td.time {
+ border-top: 1px solid #000;
+ padding: 1px 0px;
+ text-align: center;
+ background-color: #e8f0f4;
+}
+
+.calendar td.time .hour,
+.calendar td.time .minute,
+.calendar td.time .ampm {
+ padding: 0px 3px 0px 4px;
+ border: 1px solid #889;
+ font-weight: bold;
+ background-color: #fff;
+}
+
+.calendar td.time .ampm {
+ text-align: center;
+}
+
+.calendar td.time .colon {
+ padding: 0px 2px 0px 3px;
+ font-weight: bold;
+}
+
+.calendar td.time span.hilite {
+ border-color: #000;
+ background-color: #667;
+ color: #fff;
+}
+
+.calendar td.time span.active {
+ border-color: #f00;
+ background-color: #000;
+ color: #0f0;
+}
diff --git a/WebContent/themes/default/jscalendar/calendar-win2k-cold-2.css b/WebContent/themes/default/jscalendar/calendar-win2k-cold-2.css
new file mode 100644
index 0000000000..8e930c8f4f
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/calendar-win2k-cold-2.css
@@ -0,0 +1,271 @@
+/* The main calendar widget. DIV containing a table. */
+
+.calendar {
+ position: relative;
+ display: none;
+ border-top: 2px solid #fff;
+ border-right: 2px solid #000;
+ border-bottom: 2px solid #000;
+ border-left: 2px solid #fff;
+ font-size: 11px;
+ color: #000;
+ cursor: default;
+ background: #c8d4d0;
+ font-family: tahoma,verdana,sans-serif;
+}
+
+.calendar table {
+ border-top: 1px solid #000;
+ border-right: 1px solid #fff;
+ border-bottom: 1px solid #fff;
+ border-left: 1px solid #000;
+ font-size: 11px;
+ color: #000;
+ cursor: default;
+ background: #c8d4d0;
+ font-family: tahoma,verdana,sans-serif;
+}
+
+/* Header part -- contains navigation buttons and day names. */
+
+.calendar .button { /* "<<", "<", ">", ">>" buttons have this class */
+ text-align: center;
+ padding: 1px;
+ border-top: 1px solid #fff;
+ border-right: 1px solid #000;
+ border-bottom: 1px solid #000;
+ border-left: 1px solid #fff;
+}
+
+.calendar .nav {
+ background: transparent url(menuarrow.gif) no-repeat 100% 100%;
+}
+
+.calendar thead .title { /* This holds the current "month, year" */
+ font-weight: bold;
+ padding: 1px;
+ border: 1px solid #000;
+ background: #788480;
+ color: #fff;
+ text-align: center;
+}
+
+.calendar thead .headrow { /* Row <TR> containing navigation buttons */
+}
+
+.calendar thead .daynames { /* Row <TR> containing the day names */
+}
+
+.calendar thead .name { /* Cells <TD> containing the day names */
+ border-bottom: 1px solid #000;
+ padding: 2px;
+ text-align: center;
+ background: #e8f4f0;
+}
+
+.calendar thead .weekend { /* How a weekend day name shows in header */
+ color: #f00;
+}
+
+.calendar thead .hilite { /* How do the buttons in header appear when hover */
+ border-top: 2px solid #fff;
+ border-right: 2px solid #000;
+ border-bottom: 2px solid #000;
+ border-left: 2px solid #fff;
+ padding: 0px;
+ background-color: #d8e4e0;
+}
+
+.calendar thead .active { /* Active (pressed) buttons in header */
+ padding: 2px 0px 0px 2px;
+ border-top: 1px solid #000;
+ border-right: 1px solid #fff;
+ border-bottom: 1px solid #fff;
+ border-left: 1px solid #000;
+ background-color: #b8c4c0;
+}
+
+/* The body part -- contains all the days in month. */
+
+.calendar tbody .day { /* Cells <TD> containing month days dates */
+ width: 2em;
+ text-align: right;
+ padding: 2px 4px 2px 2px;
+}
+.calendar tbody .day.othermonth {
+ font-size: 80%;
+ color: #aaa;
+}
+.calendar tbody .day.othermonth.oweekend {
+ color: #faa;
+}
+
+.calendar table .wn {
+ padding: 2px 3px 2px 2px;
+ border-right: 1px solid #000;
+ background: #e8f4f0;
+}
+
+.calendar tbody .rowhilite td {
+ background: #d8e4e0;
+}
+
+.calendar tbody .rowhilite td.wn {
+ background: #c8d4d0;
+}
+
+.calendar tbody td.hilite { /* Hovered cells <TD> */
+ padding: 1px 3px 1px 1px;
+ border-top: 1px solid #fff;
+ border-right: 1px solid #000;
+ border-bottom: 1px solid #000;
+ border-left: 1px solid #fff;
+}
+
+.calendar tbody td.active { /* Active (pressed) cells <TD> */
+ padding: 2px 2px 0px 2px;
+ border-top: 1px solid #000;
+ border-right: 1px solid #fff;
+ border-bottom: 1px solid #fff;
+ border-left: 1px solid #000;
+}
+
+.calendar tbody td.selected { /* Cell showing selected date */
+ font-weight: bold;
+ border-top: 1px solid #000;
+ border-right: 1px solid #fff;
+ border-bottom: 1px solid #fff;
+ border-left: 1px solid #000;
+ padding: 2px 2px 0px 2px;
+ background: #d8e4e0;
+}
+
+.calendar tbody td.weekend { /* Cells showing weekend days */
+ color: #f00;
+}
+
+.calendar tbody td.today { /* Cell showing today date */
+ font-weight: bold;
+ color: #00f;
+}
+
+.calendar tbody .disabled { color: #999; }
+
+.calendar tbody .emptycell { /* Empty cells (the best is to hide them) */
+ visibility: hidden;
+}
+
+.calendar tbody .emptyrow { /* Empty row (some months need less than 6 rows) */
+ display: none;
+}
+
+/* The footer part -- status bar and "Close" button */
+
+.calendar tfoot .footrow { /* The <TR> in footer (only one right now) */
+}
+
+.calendar tfoot .ttip { /* Tooltip (status bar) cell <TD> */
+ background: #e8f4f0;
+ padding: 1px;
+ border: 1px solid #000;
+ background: #788480;
+ color: #fff;
+ text-align: center;
+}
+
+.calendar tfoot .hilite { /* Hover style for buttons in footer */
+ border-top: 1px solid #fff;
+ border-right: 1px solid #000;
+ border-bottom: 1px solid #000;
+ border-left: 1px solid #fff;
+ padding: 1px;
+ background: #d8e4e0;
+}
+
+.calendar tfoot .active { /* Active (pressed) style for buttons in footer */
+ padding: 2px 0px 0px 2px;
+ border-top: 1px solid #000;
+ border-right: 1px solid #fff;
+ border-bottom: 1px solid #fff;
+ border-left: 1px solid #000;
+}
+
+/* Combo boxes (menus that display months/years for direct selection) */
+
+.calendar .combo {
+ position: absolute;
+ display: none;
+ width: 4em;
+ top: 0px;
+ left: 0px;
+ cursor: default;
+ border-top: 1px solid #fff;
+ border-right: 1px solid #000;
+ border-bottom: 1px solid #000;
+ border-left: 1px solid #fff;
+ background: #d8e4e0;
+ font-size: 90%;
+ padding: 1px;
+ z-index: 100;
+}
+
+.calendar .combo .label,
+.calendar .combo .label-IEfix {
+ text-align: center;
+ padding: 1px;
+}
+
+.calendar .combo .label-IEfix {
+ width: 4em;
+}
+
+.calendar .combo .active {
+ background: #c8d4d0;
+ padding: 0px;
+ border-top: 1px solid #000;
+ border-right: 1px solid #fff;
+ border-bottom: 1px solid #fff;
+ border-left: 1px solid #000;
+}
+
+.calendar .combo .hilite {
+ background: #048;
+ color: #aef;
+}
+
+.calendar td.time {
+ border-top: 1px solid #000;
+ padding: 1px 0px;
+ text-align: center;
+ background-color: #e8f0f4;
+}
+
+.calendar td.time .hour,
+.calendar td.time .minute,
+.calendar td.time .ampm {
+ padding: 0px 3px 0px 4px;
+ border: 1px solid #889;
+ font-weight: bold;
+ background-color: #fff;
+}
+
+.calendar td.time .ampm {
+ text-align: center;
+}
+
+.calendar td.time .colon {
+ padding: 0px 2px 0px 3px;
+ font-weight: bold;
+}
+
+.calendar td.time span.hilite {
+ border-color: #000;
+ background-color: #667;
+ color: #fff;
+}
+
+.calendar td.time span.active {
+ border-color: #f00;
+ background-color: #000;
+ color: #0f0;
+}
diff --git a/WebContent/themes/default/jscalendar/calendar.js b/WebContent/themes/default/jscalendar/calendar.js
new file mode 100644
index 0000000000..633b251b99
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/calendar.js
@@ -0,0 +1,1806 @@
+/* Copyright Mihai Bazon, 2002-2005 | www.bazon.net/mishoo
+ * -----------------------------------------------------------
+ *
+ * The DHTML Calendar, version 1.0 "It is happening again"
+ *
+ * Details and latest version at:
+ * www.dynarch.com/projects/calendar
+ *
+ * This script is developed by Dynarch.com. Visit us at www.dynarch.com.
+ *
+ * This script is distributed under the GNU Lesser General Public License.
+ * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html
+ */
+
+// $Id: calendar.js,v 1.1 2005/09/28 10:04:05 se Exp $
+
+/** The Calendar object constructor. */
+Calendar = function (firstDayOfWeek, dateStr, onSelected, onClose) {
+ // member variables
+ this.activeDiv = null;
+ this.currentDateEl = null;
+ this.getDateStatus = null;
+ this.getDateToolTip = null;
+ this.getDateText = null;
+ this.timeout = null;
+ this.onSelected = onSelected || null;
+ this.onClose = onClose || null;
+ this.dragging = false;
+ this.hidden = false;
+ this.minYear = 1970;
+ this.maxYear = 2050;
+ this.dateFormat = Calendar._TT["DEF_DATE_FORMAT"];
+ this.ttDateFormat = Calendar._TT["TT_DATE_FORMAT"];
+ this.isPopup = true;
+ this.weekNumbers = true;
+ this.firstDayOfWeek = typeof firstDayOfWeek == "number" ? firstDayOfWeek : Calendar._FD; // 0 for Sunday, 1 for Monday, etc.
+ this.showsOtherMonths = false;
+ this.dateStr = dateStr;
+ this.ar_days = null;
+ this.showsTime = false;
+ this.time24 = true;
+ this.yearStep = 2;
+ this.hiliteToday = true;
+ this.multiple = null;
+ // HTML elements
+ this.table = null;
+ this.element = null;
+ this.tbody = null;
+ this.firstdayname = null;
+ // Combo boxes
+ this.monthsCombo = null;
+ this.yearsCombo = null;
+ this.hilitedMonth = null;
+ this.activeMonth = null;
+ this.hilitedYear = null;
+ this.activeYear = null;
+ // Information
+ this.dateClicked = false;
+
+ // one-time initializations
+ if (typeof Calendar._SDN == "undefined") {
+ // table of short day names
+ if (typeof Calendar._SDN_len == "undefined")
+ Calendar._SDN_len = 3;
+ var ar = new Array();
+ for (var i = 8; i > 0;) {
+ ar[--i] = Calendar._DN[i].substr(0, Calendar._SDN_len);
+ }
+ Calendar._SDN = ar;
+ // table of short month names
+ if (typeof Calendar._SMN_len == "undefined")
+ Calendar._SMN_len = 3;
+ ar = new Array();
+ for (var i = 12; i > 0;) {
+ ar[--i] = Calendar._MN[i].substr(0, Calendar._SMN_len);
+ }
+ Calendar._SMN = ar;
+ }
+};
+
+// ** constants
+
+/// "static", needed for event handlers.
+Calendar._C = null;
+
+/// detect a special case of "web browser"
+Calendar.is_ie = ( /msie/i.test(navigator.userAgent) &&
+ !/opera/i.test(navigator.userAgent) );
+
+Calendar.is_ie5 = ( Calendar.is_ie && /msie 5\.0/i.test(navigator.userAgent) );
+
+/// detect Opera browser
+Calendar.is_opera = /opera/i.test(navigator.userAgent);
+
+/// detect KHTML-based browsers
+Calendar.is_khtml = /Konqueror|Safari|KHTML/i.test(navigator.userAgent);
+
+// BEGIN: UTILITY FUNCTIONS; beware that these might be moved into a separate
+// library, at some point.
+
+Calendar.getAbsolutePos = function(el) {
+ var SL = 0, ST = 0;
+ var is_div = /^div$/i.test(el.tagName);
+ if (is_div && el.scrollLeft)
+ SL = el.scrollLeft;
+ if (is_div && el.scrollTop)
+ ST = el.scrollTop;
+ var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST };
+ if (el.offsetParent) {
+ var tmp = this.getAbsolutePos(el.offsetParent);
+ r.x += tmp.x;
+ r.y += tmp.y;
+ }
+ return r;
+};
+
+Calendar.isRelated = function (el, evt) {
+ var related = evt.relatedTarget;
+ if (!related) {
+ var type = evt.type;
+ if (type == "mouseover") {
+ related = evt.fromElement;
+ } else if (type == "mouseout") {
+ related = evt.toElement;
+ }
+ }
+ while (related) {
+ if (related == el) {
+ return true;
+ }
+ related = related.parentNode;
+ }
+ return false;
+};
+
+Calendar.removeClass = function(el, className) {
+ if (!(el && el.className)) {
+ return;
+ }
+ var cls = el.className.split(" ");
+ var ar = new Array();
+ for (var i = cls.length; i > 0;) {
+ if (cls[--i] != className) {
+ ar[ar.length] = cls[i];
+ }
+ }
+ el.className = ar.join(" ");
+};
+
+Calendar.addClass = function(el, className) {
+ Calendar.removeClass(el, className);
+ el.className += " " + className;
+};
+
+// FIXME: the following 2 functions totally suck, are useless and should be replaced immediately.
+Calendar.getElement = function(ev) {
+ var f = Calendar.is_ie ? window.event.srcElement : ev.currentTarget;
+ while (f.nodeType != 1 || /^div$/i.test(f.tagName))
+ f = f.parentNode;
+ return f;
+};
+
+Calendar.getTargetElement = function(ev) {
+ var f = Calendar.is_ie ? window.event.srcElement : ev.target;
+ while (f.nodeType != 1)
+ f = f.parentNode;
+ return f;
+};
+
+Calendar.stopEvent = function(ev) {
+ ev || (ev = window.event);
+ if (Calendar.is_ie) {
+ ev.cancelBubble = true;
+ ev.returnValue = false;
+ } else {
+ ev.preventDefault();
+ ev.stopPropagation();
+ }
+ return false;
+};
+
+Calendar.addEvent = function(el, evname, func) {
+ if (el.attachEvent) { // IE
+ el.attachEvent("on" + evname, func);
+ } else if (el.addEventListener) { // Gecko / W3C
+ el.addEventListener(evname, func, true);
+ } else {
+ el["on" + evname] = func;
+ }
+};
+
+Calendar.removeEvent = function(el, evname, func) {
+ if (el.detachEvent) { // IE
+ el.detachEvent("on" + evname, func);
+ } else if (el.removeEventListener) { // Gecko / W3C
+ el.removeEventListener(evname, func, true);
+ } else {
+ el["on" + evname] = null;
+ }
+};
+
+Calendar.createElement = function(type, parent) {
+ var el = null;
+ if (document.createElementNS) {
+ // use the XHTML namespace; IE won't normally get here unless
+ // _they_ "fix" the DOM2 implementation.
+ el = document.createElementNS("http://www.w3.org/1999/xhtml", type);
+ } else {
+ el = document.createElement(type);
+ }
+ if (typeof parent != "undefined") {
+ parent.appendChild(el);
+ }
+ return el;
+};
+
+// END: UTILITY FUNCTIONS
+
+// BEGIN: CALENDAR STATIC FUNCTIONS
+
+/** Internal -- adds a set of events to make some element behave like a button. */
+Calendar._add_evs = function(el) {
+ with (Calendar) {
+ addEvent(el, "mouseover", dayMouseOver);
+ addEvent(el, "mousedown", dayMouseDown);
+ addEvent(el, "mouseout", dayMouseOut);
+ if (is_ie) {
+ addEvent(el, "dblclick", dayMouseDblClick);
+ el.setAttribute("unselectable", true);
+ }
+ }
+};
+
+Calendar.findMonth = function(el) {
+ if (typeof el.month != "undefined") {
+ return el;
+ } else if (typeof el.parentNode.month != "undefined") {
+ return el.parentNode;
+ }
+ return null;
+};
+
+Calendar.findYear = function(el) {
+ if (typeof el.year != "undefined") {
+ return el;
+ } else if (typeof el.parentNode.year != "undefined") {
+ return el.parentNode;
+ }
+ return null;
+};
+
+Calendar.showMonthsCombo = function () {
+ var cal = Calendar._C;
+ if (!cal) {
+ return false;
+ }
+ var cal = cal;
+ var cd = cal.activeDiv;
+ var mc = cal.monthsCombo;
+ if (cal.hilitedMonth) {
+ Calendar.removeClass(cal.hilitedMonth, "hilite");
+ }
+ if (cal.activeMonth) {
+ Calendar.removeClass(cal.activeMonth, "active");
+ }
+ var mon = cal.monthsCombo.getElementsByTagName("div")[cal.date.getMonth()];
+ Calendar.addClass(mon, "active");
+ cal.activeMonth = mon;
+ var s = mc.style;
+ s.display = "block";
+ if (cd.navtype < 0)
+ s.left = cd.offsetLeft + "px";
+ else {
+ var mcw = mc.offsetWidth;
+ if (typeof mcw == "undefined")
+ // Konqueror brain-dead techniques
+ mcw = 50;
+ s.left = (cd.offsetLeft + cd.offsetWidth - mcw) + "px";
+ }
+ s.top = (cd.offsetTop + cd.offsetHeight) + "px";
+};
+
+Calendar.showYearsCombo = function (fwd) {
+ var cal = Calendar._C;
+ if (!cal) {
+ return false;
+ }
+ var cal = cal;
+ var cd = cal.activeDiv;
+ var yc = cal.yearsCombo;
+ if (cal.hilitedYear) {
+ Calendar.removeClass(cal.hilitedYear, "hilite");
+ }
+ if (cal.activeYear) {
+ Calendar.removeClass(cal.activeYear, "active");
+ }
+ cal.activeYear = null;
+ var Y = cal.date.getFullYear() + (fwd ? 1 : -1);
+ var yr = yc.firstChild;
+ var show = false;
+ for (var i = 12; i > 0; --i) {
+ if (Y >= cal.minYear && Y <= cal.maxYear) {
+ yr.innerHTML = Y;
+ yr.year = Y;
+ yr.style.display = "block";
+ show = true;
+ } else {
+ yr.style.display = "none";
+ }
+ yr = yr.nextSibling;
+ Y += fwd ? cal.yearStep : -cal.yearStep;
+ }
+ if (show) {
+ var s = yc.style;
+ s.display = "block";
+ if (cd.navtype < 0)
+ s.left = cd.offsetLeft + "px";
+ else {
+ var ycw = yc.offsetWidth;
+ if (typeof ycw == "undefined")
+ // Konqueror brain-dead techniques
+ ycw = 50;
+ s.left = (cd.offsetLeft + cd.offsetWidth - ycw) + "px";
+ }
+ s.top = (cd.offsetTop + cd.offsetHeight) + "px";
+ }
+};
+
+// event handlers
+
+Calendar.tableMouseUp = function(ev) {
+ var cal = Calendar._C;
+ if (!cal) {
+ return false;
+ }
+ if (cal.timeout) {
+ clearTimeout(cal.timeout);
+ }
+ var el = cal.activeDiv;
+ if (!el) {
+ return false;
+ }
+ var target = Calendar.getTargetElement(ev);
+ ev || (ev = window.event);
+ Calendar.removeClass(el, "active");
+ if (target == el || target.parentNode == el) {
+ Calendar.cellClick(el, ev);
+ }
+ var mon = Calendar.findMonth(target);
+ var date = null;
+ if (mon) {
+ date = new Date(cal.date);
+ if (mon.month != date.getMonth()) {
+ date.setMonth(mon.month);
+ cal.setDate(date);
+ cal.dateClicked = false;
+ cal.callHandler();
+ }
+ } else {
+ var year = Calendar.findYear(target);
+ if (year) {
+ date = new Date(cal.date);
+ if (year.year != date.getFullYear()) {
+ date.setFullYear(year.year);
+ cal.setDate(date);
+ cal.dateClicked = false;
+ cal.callHandler();
+ }
+ }
+ }
+ with (Calendar) {
+ removeEvent(document, "mouseup", tableMouseUp);
+ removeEvent(document, "mouseover", tableMouseOver);
+ removeEvent(document, "mousemove", tableMouseOver);
+ cal._hideCombos();
+ _C = null;
+ return stopEvent(ev);
+ }
+};
+
+Calendar.tableMouseOver = function (ev) {
+ var cal = Calendar._C;
+ if (!cal) {
+ return;
+ }
+ var el = cal.activeDiv;
+ var target = Calendar.getTargetElement(ev);
+ if (target == el || target.parentNode == el) {
+ Calendar.addClass(el, "hilite active");
+ Calendar.addClass(el.parentNode, "rowhilite");
+ } else {
+ if (typeof el.navtype == "undefined" || (el.navtype != 50 && (el.navtype == 0 || Math.abs(el.navtype) > 2)))
+ Calendar.removeClass(el, "active");
+ Calendar.removeClass(el, "hilite");
+ Calendar.removeClass(el.parentNode, "rowhilite");
+ }
+ ev || (ev = window.event);
+ if (el.navtype == 50 && target != el) {
+ var pos = Calendar.getAbsolutePos(el);
+ var w = el.offsetWidth;
+ var x = ev.clientX;
+ var dx;
+ var decrease = true;
+ if (x > pos.x + w) {
+ dx = x - pos.x - w;
+ decrease = false;
+ } else
+ dx = pos.x - x;
+
+ if (dx < 0) dx = 0;
+ var range = el._range;
+ var current = el._current;
+ var count = Math.floor(dx / 10) % range.length;
+ for (var i = range.length; --i >= 0;)
+ if (range[i] == current)
+ break;
+ while (count-- > 0)
+ if (decrease) {
+ if (--i < 0)
+ i = range.length - 1;
+ } else if ( ++i >= range.length )
+ i = 0;
+ var newval = range[i];
+ el.innerHTML = newval;
+
+ cal.onUpdateTime();
+ }
+ var mon = Calendar.findMonth(target);
+ if (mon) {
+ if (mon.month != cal.date.getMonth()) {
+ if (cal.hilitedMonth) {
+ Calendar.removeClass(cal.hilitedMonth, "hilite");
+ }
+ Calendar.addClass(mon, "hilite");
+ cal.hilitedMonth = mon;
+ } else if (cal.hilitedMonth) {
+ Calendar.removeClass(cal.hilitedMonth, "hilite");
+ }
+ } else {
+ if (cal.hilitedMonth) {
+ Calendar.removeClass(cal.hilitedMonth, "hilite");
+ }
+ var year = Calendar.findYear(target);
+ if (year) {
+ if (year.year != cal.date.getFullYear()) {
+ if (cal.hilitedYear) {
+ Calendar.removeClass(cal.hilitedYear, "hilite");
+ }
+ Calendar.addClass(year, "hilite");
+ cal.hilitedYear = year;
+ } else if (cal.hilitedYear) {
+ Calendar.removeClass(cal.hilitedYear, "hilite");
+ }
+ } else if (cal.hilitedYear) {
+ Calendar.removeClass(cal.hilitedYear, "hilite");
+ }
+ }
+ return Calendar.stopEvent(ev);
+};
+
+Calendar.tableMouseDown = function (ev) {
+ if (Calendar.getTargetElement(ev) == Calendar.getElement(ev)) {
+ return Calendar.stopEvent(ev);
+ }
+};
+
+Calendar.calDragIt = function (ev) {
+ var cal = Calendar._C;
+ if (!(cal && cal.dragging)) {
+ return false;
+ }
+ var posX;
+ var posY;
+ if (Calendar.is_ie) {
+ posY = window.event.clientY + document.body.scrollTop;
+ posX = window.event.clientX + document.body.scrollLeft;
+ } else {
+ posX = ev.pageX;
+ posY = ev.pageY;
+ }
+ cal.hideShowCovered();
+ var st = cal.element.style;
+ st.left = (posX - cal.xOffs) + "px";
+ st.top = (posY - cal.yOffs) + "px";
+ return Calendar.stopEvent(ev);
+};
+
+Calendar.calDragEnd = function (ev) {
+ var cal = Calendar._C;
+ if (!cal) {
+ return false;
+ }
+ cal.dragging = false;
+ with (Calendar) {
+ removeEvent(document, "mousemove", calDragIt);
+ removeEvent(document, "mouseup", calDragEnd);
+ tableMouseUp(ev);
+ }
+ cal.hideShowCovered();
+};
+
+Calendar.dayMouseDown = function(ev) {
+ var el = Calendar.getElement(ev);
+ if (el.disabled) {
+ return false;
+ }
+ var cal = el.calendar;
+ cal.activeDiv = el;
+ Calendar._C = cal;
+ if (el.navtype != 300) with (Calendar) {
+ if (el.navtype == 50) {
+ el._current = el.innerHTML;
+ addEvent(document, "mousemove", tableMouseOver);
+ } else
+ addEvent(document, Calendar.is_ie5 ? "mousemove" : "mouseover", tableMouseOver);
+ addClass(el, "hilite active");
+ addEvent(document, "mouseup", tableMouseUp);
+ } else if (cal.isPopup) {
+ cal._dragStart(ev);
+ }
+ if (el.navtype == -1 || el.navtype == 1) {
+ if (cal.timeout) clearTimeout(cal.timeout);
+ cal.timeout = setTimeout("Calendar.showMonthsCombo()", 250);
+ } else if (el.navtype == -2 || el.navtype == 2) {
+ if (cal.timeout) clearTimeout(cal.timeout);
+ cal.timeout = setTimeout((el.navtype > 0) ? "Calendar.showYearsCombo(true)" : "Calendar.showYearsCombo(false)", 250);
+ } else {
+ cal.timeout = null;
+ }
+ return Calendar.stopEvent(ev);
+};
+
+Calendar.dayMouseDblClick = function(ev) {
+ Calendar.cellClick(Calendar.getElement(ev), ev || window.event);
+ if (Calendar.is_ie) {
+ document.selection.empty();
+ }
+};
+
+Calendar.dayMouseOver = function(ev) {
+ var el = Calendar.getElement(ev);
+ if (Calendar.isRelated(el, ev) || Calendar._C || el.disabled) {
+ return false;
+ }
+ if (el.ttip) {
+ if (el.ttip.substr(0, 1) == "_") {
+ el.ttip = el.caldate.print(el.calendar.ttDateFormat) + el.ttip.substr(1);
+ }
+ el.calendar.tooltips.innerHTML = el.ttip;
+ }
+ if (el.navtype != 300) {
+ Calendar.addClass(el, "hilite");
+ if (el.caldate) {
+ Calendar.addClass(el.parentNode, "rowhilite");
+ }
+ }
+ return Calendar.stopEvent(ev);
+};
+
+Calendar.dayMouseOut = function(ev) {
+ with (Calendar) {
+ var el = getElement(ev);
+ if (isRelated(el, ev) || _C || el.disabled)
+ return false;
+ removeClass(el, "hilite");
+ if (el.caldate)
+ removeClass(el.parentNode, "rowhilite");
+ if (el.calendar)
+ el.calendar.tooltips.innerHTML = _TT["SEL_DATE"];
+ return stopEvent(ev);
+ }
+};
+
+/**
+ * A generic "click" handler :) handles all types of buttons defined in this
+ * calendar.
+ */
+Calendar.cellClick = function(el, ev) {
+ var cal = el.calendar;
+ var closing = false;
+ var newdate = false;
+ var date = null;
+ if (typeof el.navtype == "undefined") {
+ if (cal.currentDateEl) {
+ Calendar.removeClass(cal.currentDateEl, "selected");
+ Calendar.addClass(el, "selected");
+ closing = (cal.currentDateEl == el);
+ if (!closing) {
+ cal.currentDateEl = el;
+ }
+ }
+ cal.date.setDateOnly(el.caldate);
+ date = cal.date;
+ var other_month = !(cal.dateClicked = !el.otherMonth);
+ if (!other_month && !cal.currentDateEl)
+ cal._toggleMultipleDate(new Date(date));
+ else
+ newdate = !el.disabled;
+ // a date was clicked
+ if (other_month)
+ cal._init(cal.firstDayOfWeek, date);
+ } else {
+ if (el.navtype == 200) {
+ Calendar.removeClass(el, "hilite");
+ cal.callCloseHandler();
+ return;
+ }
+ date = new Date(cal.date);
+ if (el.navtype == 0)
+ date.setDateOnly(new Date()); // TODAY
+ // unless "today" was clicked, we assume no date was clicked so
+ // the selected handler will know not to close the calenar when
+ // in single-click mode.
+ // cal.dateClicked = (el.navtype == 0);
+ cal.dateClicked = false;
+ var year = date.getFullYear();
+ var mon = date.getMonth();
+ function setMonth(m) {
+ var day = date.getDate();
+ var max = date.getMonthDays(m);
+ if (day > max) {
+ date.setDate(max);
+ }
+ date.setMonth(m);
+ };
+ switch (el.navtype) {
+ case 400:
+ Calendar.removeClass(el, "hilite");
+ var text = Calendar._TT["ABOUT"];
+ if (typeof text != "undefined") {
+ text += cal.showsTime ? Calendar._TT["ABOUT_TIME"] : "";
+ } else {
+ // FIXME: this should be removed as soon as lang files get updated!
+ text = "Help and about box text is not translated into this language.\n" +
+ "If you know this language and you feel generous please update\n" +
+ "the corresponding file in \"lang\" subdir to match calendar-en.js\n" +
+ "and send it back to <mihai_bazon@yahoo.com> to get it into the distribution ;-)\n\n" +
+ "Thank you!\n" +
+ "http://dynarch.com/mishoo/calendar.epl\n";
+ }
+ alert(text);
+ return;
+ case -2:
+ if (year > cal.minYear) {
+ date.setFullYear(year - 1);
+ }
+ break;
+ case -1:
+ if (mon > 0) {
+ setMonth(mon - 1);
+ } else if (year-- > cal.minYear) {
+ date.setFullYear(year);
+ setMonth(11);
+ }
+ break;
+ case 1:
+ if (mon < 11) {
+ setMonth(mon + 1);
+ } else if (year < cal.maxYear) {
+ date.setFullYear(year + 1);
+ setMonth(0);
+ }
+ break;
+ case 2:
+ if (year < cal.maxYear) {
+ date.setFullYear(year + 1);
+ }
+ break;
+ case 100:
+ cal.setFirstDayOfWeek(el.fdow);
+ return;
+ case 50:
+ var range = el._range;
+ var current = el.innerHTML;
+ for (var i = range.length; --i >= 0;)
+ if (range[i] == current)
+ break;
+ if (ev && ev.shiftKey) {
+ if (--i < 0)
+ i = range.length - 1;
+ } else if ( ++i >= range.length )
+ i = 0;
+ var newval = range[i];
+ el.innerHTML = newval;
+ cal.onUpdateTime();
+ return;
+ case 0:
+ // TODAY will bring us here
+ if ((typeof cal.getDateStatus == "function") &&
+ cal.getDateStatus(date, date.getFullYear(), date.getMonth(), date.getDate())) {
+ return false;
+ }
+ break;
+ }
+ if (!date.equalsTo(cal.date)) {
+ cal.setDate(date);
+ newdate = true;
+ } else if (el.navtype == 0)
+ newdate = closing = true;
+ }
+ if (newdate) {
+ ev && cal.callHandler();
+ }
+ if (closing) {
+ Calendar.removeClass(el, "hilite");
+ ev && cal.callCloseHandler();
+ }
+};
+
+// END: CALENDAR STATIC FUNCTIONS
+
+// BEGIN: CALENDAR OBJECT FUNCTIONS
+
+/**
+ * This function creates the calendar inside the given parent. If _par is
+ * null than it creates a popup calendar inside the BODY element. If _par is
+ * an element, be it BODY, then it creates a non-popup calendar (still
+ * hidden). Some properties need to be set before calling this function.
+ */
+Calendar.prototype.create = function (_par) {
+ var parent = null;
+ if (! _par) {
+ // default parent is the document body, in which case we create
+ // a popup calendar.
+ parent = document.getElementsByTagName("body")[0];
+ this.isPopup = true;
+ } else {
+ parent = _par;
+ this.isPopup = false;
+ }
+ this.date = this.dateStr ? new Date(this.dateStr) : new Date();
+
+ var table = Calendar.createElement("table");
+ this.table = table;
+ table.cellSpacing = 0;
+ table.cellPadding = 0;
+ table.calendar = this;
+ Calendar.addEvent(table, "mousedown", Calendar.tableMouseDown);
+
+ var div = Calendar.createElement("div");
+ this.element = div;
+ div.className = "calendar";
+ if (this.isPopup) {
+ div.style.position = "absolute";
+ div.style.display = "none";
+ }
+ div.appendChild(table);
+
+ var thead = Calendar.createElement("thead", table);
+ var cell = null;
+ var row = null;
+
+ var cal = this;
+ var hh = function (text, cs, navtype) {
+ cell = Calendar.createElement("td", row);
+ cell.colSpan = cs;
+ cell.className = "button";
+ if (navtype != 0 && Math.abs(navtype) <= 2)
+ cell.className += " nav";
+ Calendar._add_evs(cell);
+ cell.calendar = cal;
+ cell.navtype = navtype;
+ cell.innerHTML = "<div unselectable='on'>" + text + "</div>";
+ return cell;
+ };
+
+ row = Calendar.createElement("tr", thead);
+ var title_length = 6;
+ (this.isPopup) && --title_length;
+ (this.weekNumbers) && ++title_length;
+
+ hh("?", 1, 400).ttip = Calendar._TT["INFO"];
+ this.title = hh("", title_length, 300);
+ this.title.className = "title";
+ if (this.isPopup) {
+ this.title.ttip = Calendar._TT["DRAG_TO_MOVE"];
+ this.title.style.cursor = "move";
+ hh("&#x00d7;", 1, 200).ttip = Calendar._TT["CLOSE"];
+ }
+
+ row = Calendar.createElement("tr", thead);
+ row.className = "headrow";
+
+ this._nav_py = hh("&#x00ab;", 1, -2);
+ this._nav_py.ttip = Calendar._TT["PREV_YEAR"];
+
+ this._nav_pm = hh("&#x2039;", 1, -1);
+ this._nav_pm.ttip = Calendar._TT["PREV_MONTH"];
+
+ this._nav_now = hh(Calendar._TT["TODAY"], this.weekNumbers ? 4 : 3, 0);
+ this._nav_now.ttip = Calendar._TT["GO_TODAY"];
+
+ this._nav_nm = hh("&#x203a;", 1, 1);
+ this._nav_nm.ttip = Calendar._TT["NEXT_MONTH"];
+
+ this._nav_ny = hh("&#x00bb;", 1, 2);
+ this._nav_ny.ttip = Calendar._TT["NEXT_YEAR"];
+
+ // day names
+ row = Calendar.createElement("tr", thead);
+ row.className = "daynames";
+ if (this.weekNumbers) {
+ cell = Calendar.createElement("td", row);
+ cell.className = "name wn";
+ cell.innerHTML = Calendar._TT["WK"];
+ }
+ for (var i = 7; i > 0; --i) {
+ cell = Calendar.createElement("td", row);
+ if (!i) {
+ cell.navtype = 100;
+ cell.calendar = this;
+ Calendar._add_evs(cell);
+ }
+ }
+ this.firstdayname = (this.weekNumbers) ? row.firstChild.nextSibling : row.firstChild;
+ this._displayWeekdays();
+
+ var tbody = Calendar.createElement("tbody", table);
+ this.tbody = tbody;
+
+ for (i = 6; i > 0; --i) {
+ row = Calendar.createElement("tr", tbody);
+ if (this.weekNumbers) {
+ cell = Calendar.createElement("td", row);
+ }
+ for (var j = 7; j > 0; --j) {
+ cell = Calendar.createElement("td", row);
+ cell.calendar = this;
+ Calendar._add_evs(cell);
+ }
+ }
+
+ if (this.showsTime) {
+ row = Calendar.createElement("tr", tbody);
+ row.className = "time";
+
+ cell = Calendar.createElement("td", row);
+ cell.className = "time";
+ cell.colSpan = 2;
+ cell.innerHTML = Calendar._TT["TIME"] || "&nbsp;";
+
+ cell = Calendar.createElement("td", row);
+ cell.className = "time";
+ cell.colSpan = this.weekNumbers ? 4 : 3;
+
+ (function(){
+ function makeTimePart(className, init, range_start, range_end) {
+ var part = Calendar.createElement("span", cell);
+ part.className = className;
+ part.innerHTML = init;
+ part.calendar = cal;
+ part.ttip = Calendar._TT["TIME_PART"];
+ part.navtype = 50;
+ part._range = [];
+ if (typeof range_start != "number")
+ part._range = range_start;
+ else {
+ for (var i = range_start; i <= range_end; ++i) {
+ var txt;
+ if (i < 10 && range_end >= 10) txt = '0' + i;
+ else txt = '' + i;
+ part._range[part._range.length] = txt;
+ }
+ }
+ Calendar._add_evs(part);
+ return part;
+ };
+ var hrs = cal.date.getHours();
+ var mins = cal.date.getMinutes();
+ var t12 = !cal.time24;
+ var pm = (hrs > 12);
+ if (t12 && pm) hrs -= 12;
+ var H = makeTimePart("hour", hrs, t12 ? 1 : 0, t12 ? 12 : 23);
+ var span = Calendar.createElement("span", cell);
+ span.innerHTML = ":";
+ span.className = "colon";
+ var M = makeTimePart("minute", mins, 0, 59);
+ var AP = null;
+ cell = Calendar.createElement("td", row);
+ cell.className = "time";
+ cell.colSpan = 2;
+ if (t12)
+ AP = makeTimePart("ampm", pm ? "pm" : "am", ["am", "pm"]);
+ else
+ cell.innerHTML = "&nbsp;";
+
+ cal.onSetTime = function() {
+ var pm, hrs = this.date.getHours(),
+ mins = this.date.getMinutes();
+ if (t12) {
+ pm = (hrs >= 12);
+ if (pm) hrs -= 12;
+ if (hrs == 0) hrs = 12;
+ AP.innerHTML = pm ? "pm" : "am";
+ }
+ H.innerHTML = (hrs < 10) ? ("0" + hrs) : hrs;
+ M.innerHTML = (mins < 10) ? ("0" + mins) : mins;
+ };
+
+ cal.onUpdateTime = function() {
+ var date = this.date;
+ var h = parseInt(H.innerHTML, 10);
+ if (t12) {
+ if (/pm/i.test(AP.innerHTML) && h < 12)
+ h += 12;
+ else if (/am/i.test(AP.innerHTML) && h == 12)
+ h = 0;
+ }
+ var d = date.getDate();
+ var m = date.getMonth();
+ var y = date.getFullYear();
+ date.setHours(h);
+ date.setMinutes(parseInt(M.innerHTML, 10));
+ date.setFullYear(y);
+ date.setMonth(m);
+ date.setDate(d);
+ this.dateClicked = false;
+ this.callHandler();
+ };
+ })();
+ } else {
+ this.onSetTime = this.onUpdateTime = function() {};
+ }
+
+ var tfoot = Calendar.createElement("tfoot", table);
+
+ row = Calendar.createElement("tr", tfoot);
+ row.className = "footrow";
+
+ cell = hh(Calendar._TT["SEL_DATE"], this.weekNumbers ? 8 : 7, 300);
+ cell.className = "ttip";
+ if (this.isPopup) {
+ cell.ttip = Calendar._TT["DRAG_TO_MOVE"];
+ cell.style.cursor = "move";
+ }
+ this.tooltips = cell;
+
+ div = Calendar.createElement("div", this.element);
+ this.monthsCombo = div;
+ div.className = "combo";
+ for (i = 0; i < Calendar._MN.length; ++i) {
+ var mn = Calendar.createElement("div");
+ mn.className = Calendar.is_ie ? "label-IEfix" : "label";
+ mn.month = i;
+ mn.innerHTML = Calendar._SMN[i];
+ div.appendChild(mn);
+ }
+
+ div = Calendar.createElement("div", this.element);
+ this.yearsCombo = div;
+ div.className = "combo";
+ for (i = 12; i > 0; --i) {
+ var yr = Calendar.createElement("div");
+ yr.className = Calendar.is_ie ? "label-IEfix" : "label";
+ div.appendChild(yr);
+ }
+
+ this._init(this.firstDayOfWeek, this.date);
+ parent.appendChild(this.element);
+};
+
+/** keyboard navigation, only for popup calendars */
+Calendar._keyEvent = function(ev) {
+ var cal = window._dynarch_popupCalendar;
+ if (!cal || cal.multiple)
+ return false;
+ (Calendar.is_ie) && (ev = window.event);
+ var act = (Calendar.is_ie || ev.type == "keypress"),
+ K = ev.keyCode;
+ if (ev.ctrlKey) {
+ switch (K) {
+ case 37: // KEY left
+ act && Calendar.cellClick(cal._nav_pm);
+ break;
+ case 38: // KEY up
+ act && Calendar.cellClick(cal._nav_py);
+ break;
+ case 39: // KEY right
+ act && Calendar.cellClick(cal._nav_nm);
+ break;
+ case 40: // KEY down
+ act && Calendar.cellClick(cal._nav_ny);
+ break;
+ default:
+ return false;
+ }
+ } else switch (K) {
+ case 32: // KEY space (now)
+ Calendar.cellClick(cal._nav_now);
+ break;
+ case 27: // KEY esc
+ act && cal.callCloseHandler();
+ break;
+ case 37: // KEY left
+ case 38: // KEY up
+ case 39: // KEY right
+ case 40: // KEY down
+ if (act) {
+ var prev, x, y, ne, el, step;
+ prev = K == 37 || K == 38;
+ step = (K == 37 || K == 39) ? 1 : 7;
+ function setVars() {
+ el = cal.currentDateEl;
+ var p = el.pos;
+ x = p & 15;
+ y = p >> 4;
+ ne = cal.ar_days[y][x];
+ };setVars();
+ function prevMonth() {
+ var date = new Date(cal.date);
+ date.setDate(date.getDate() - step);
+ cal.setDate(date);
+ };
+ function nextMonth() {
+ var date = new Date(cal.date);
+ date.setDate(date.getDate() + step);
+ cal.setDate(date);
+ };
+ while (1) {
+ switch (K) {
+ case 37: // KEY left
+ if (--x >= 0)
+ ne = cal.ar_days[y][x];
+ else {
+ x = 6;
+ K = 38;
+ continue;
+ }
+ break;
+ case 38: // KEY up
+ if (--y >= 0)
+ ne = cal.ar_days[y][x];
+ else {
+ prevMonth();
+ setVars();
+ }
+ break;
+ case 39: // KEY right
+ if (++x < 7)
+ ne = cal.ar_days[y][x];
+ else {
+ x = 0;
+ K = 40;
+ continue;
+ }
+ break;
+ case 40: // KEY down
+ if (++y < cal.ar_days.length)
+ ne = cal.ar_days[y][x];
+ else {
+ nextMonth();
+ setVars();
+ }
+ break;
+ }
+ break;
+ }
+ if (ne) {
+ if (!ne.disabled)
+ Calendar.cellClick(ne);
+ else if (prev)
+ prevMonth();
+ else
+ nextMonth();
+ }
+ }
+ break;
+ case 13: // KEY enter
+ if (act)
+ Calendar.cellClick(cal.currentDateEl, ev);
+ break;
+ default:
+ return false;
+ }
+ return Calendar.stopEvent(ev);
+};
+
+/**
+ * (RE)Initializes the calendar to the given date and firstDayOfWeek
+ */
+Calendar.prototype._init = function (firstDayOfWeek, date) {
+ var today = new Date(),
+ TY = today.getFullYear(),
+ TM = today.getMonth(),
+ TD = today.getDate();
+ this.table.style.visibility = "hidden";
+ var year = date.getFullYear();
+ if (year < this.minYear) {
+ year = this.minYear;
+ date.setFullYear(year);
+ } else if (year > this.maxYear) {
+ year = this.maxYear;
+ date.setFullYear(year);
+ }
+ this.firstDayOfWeek = firstDayOfWeek;
+ this.date = new Date(date);
+ var month = date.getMonth();
+ var mday = date.getDate();
+ var no_days = date.getMonthDays();
+
+ // calendar voodoo for computing the first day that would actually be
+ // displayed in the calendar, even if it's from the previous month.
+ // WARNING: this is magic. ;-)
+ date.setDate(1);
+ var day1 = (date.getDay() - this.firstDayOfWeek) % 7;
+ if (day1 < 0)
+ day1 += 7;
+ date.setDate(-day1);
+ date.setDate(date.getDate() + 1);
+
+ var row = this.tbody.firstChild;
+ var MN = Calendar._SMN[month];
+ var ar_days = this.ar_days = new Array();
+ var weekend = Calendar._TT["WEEKEND"];
+ var dates = this.multiple ? (this.datesCells = {}) : null;
+ for (var i = 0; i < 6; ++i, row = row.nextSibling) {
+ var cell = row.firstChild;
+ if (this.weekNumbers) {
+ cell.className = "day wn";
+ cell.innerHTML = date.getWeekNumber();
+ cell = cell.nextSibling;
+ }
+ row.className = "daysrow";
+ var hasdays = false, iday, dpos = ar_days[i] = [];
+ for (var j = 0; j < 7; ++j, cell = cell.nextSibling, date.setDate(iday + 1)) {
+ iday = date.getDate();
+ var wday = date.getDay();
+ cell.className = "day";
+ cell.pos = i << 4 | j;
+ dpos[j] = cell;
+ var current_month = (date.getMonth() == month);
+ if (!current_month) {
+ if (this.showsOtherMonths) {
+ cell.className += " othermonth";
+ cell.otherMonth = true;
+ } else {
+ cell.className = "emptycell";
+ cell.innerHTML = "&nbsp;";
+ cell.disabled = true;
+ continue;
+ }
+ } else {
+ cell.otherMonth = false;
+ hasdays = true;
+ }
+ cell.disabled = false;
+ cell.innerHTML = this.getDateText ? this.getDateText(date, iday) : iday;
+ if (dates)
+ dates[date.print("%Y%m%d")] = cell;
+ if (this.getDateStatus) {
+ var status = this.getDateStatus(date, year, month, iday);
+ if (this.getDateToolTip) {
+ var toolTip = this.getDateToolTip(date, year, month, iday);
+ if (toolTip)
+ cell.title = toolTip;
+ }
+ if (status === true) {
+ cell.className += " disabled";
+ cell.disabled = true;
+ } else {
+ if (/disabled/i.test(status))
+ cell.disabled = true;
+ cell.className += " " + status;
+ }
+ }
+ if (!cell.disabled) {
+ cell.caldate = new Date(date);
+ cell.ttip = "_";
+ if (!this.multiple && current_month
+ && iday == mday && this.hiliteToday) {
+ cell.className += " selected";
+ this.currentDateEl = cell;
+ }
+ if (date.getFullYear() == TY &&
+ date.getMonth() == TM &&
+ iday == TD) {
+ cell.className += " today";
+ cell.ttip += Calendar._TT["PART_TODAY"];
+ }
+ if (weekend.indexOf(wday.toString()) != -1)
+ cell.className += cell.otherMonth ? " oweekend" : " weekend";
+ }
+ }
+ if (!(hasdays || this.showsOtherMonths))
+ row.className = "emptyrow";
+ }
+ this.title.innerHTML = Calendar._MN[month] + ", " + year;
+ this.onSetTime();
+ this.table.style.visibility = "visible";
+ this._initMultipleDates();
+ // PROFILE
+ // this.tooltips.innerHTML = "Generated in " + ((new Date()) - today) + " ms";
+};
+
+Calendar.prototype._initMultipleDates = function() {
+ if (this.multiple) {
+ for (var i in this.multiple) {
+ var cell = this.datesCells[i];
+ var d = this.multiple[i];
+ if (!d)
+ continue;
+ if (cell)
+ cell.className += " selected";
+ }
+ }
+};
+
+Calendar.prototype._toggleMultipleDate = function(date) {
+ if (this.multiple) {
+ var ds = date.print("%Y%m%d");
+ var cell = this.datesCells[ds];
+ if (cell) {
+ var d = this.multiple[ds];
+ if (!d) {
+ Calendar.addClass(cell, "selected");
+ this.multiple[ds] = date;
+ } else {
+ Calendar.removeClass(cell, "selected");
+ delete this.multiple[ds];
+ }
+ }
+ }
+};
+
+Calendar.prototype.setDateToolTipHandler = function (unaryFunction) {
+ this.getDateToolTip = unaryFunction;
+};
+
+/**
+ * Calls _init function above for going to a certain date (but only if the
+ * date is different than the currently selected one).
+ */
+Calendar.prototype.setDate = function (date) {
+ if (!date.equalsTo(this.date)) {
+ this._init(this.firstDayOfWeek, date);
+ }
+};
+
+/**
+ * Refreshes the calendar. Useful if the "disabledHandler" function is
+ * dynamic, meaning that the list of disabled date can change at runtime.
+ * Just * call this function if you think that the list of disabled dates
+ * should * change.
+ */
+Calendar.prototype.refresh = function () {
+ this._init(this.firstDayOfWeek, this.date);
+};
+
+/** Modifies the "firstDayOfWeek" parameter (pass 0 for Synday, 1 for Monday, etc.). */
+Calendar.prototype.setFirstDayOfWeek = function (firstDayOfWeek) {
+ this._init(firstDayOfWeek, this.date);
+ this._displayWeekdays();
+};
+
+/**
+ * Allows customization of what dates are enabled. The "unaryFunction"
+ * parameter must be a function object that receives the date (as a JS Date
+ * object) and returns a boolean value. If the returned value is true then
+ * the passed date will be marked as disabled.
+ */
+Calendar.prototype.setDateStatusHandler = Calendar.prototype.setDisabledHandler = function (unaryFunction) {
+ this.getDateStatus = unaryFunction;
+};
+
+/** Customization of allowed year range for the calendar. */
+Calendar.prototype.setRange = function (a, z) {
+ this.minYear = a;
+ this.maxYear = z;
+};
+
+/** Calls the first user handler (selectedHandler). */
+Calendar.prototype.callHandler = function () {
+ if (this.onSelected) {
+ this.onSelected(this, this.date.print(this.dateFormat));
+ }
+};
+
+/** Calls the second user handler (closeHandler). */
+Calendar.prototype.callCloseHandler = function () {
+ if (this.onClose) {
+ this.onClose(this);
+ }
+ this.hideShowCovered();
+};
+
+/** Removes the calendar object from the DOM tree and destroys it. */
+Calendar.prototype.destroy = function () {
+ var el = this.element.parentNode;
+ el.removeChild(this.element);
+ Calendar._C = null;
+ window._dynarch_popupCalendar = null;
+};
+
+/**
+ * Moves the calendar element to a different section in the DOM tree (changes
+ * its parent).
+ */
+Calendar.prototype.reparent = function (new_parent) {
+ var el = this.element;
+ el.parentNode.removeChild(el);
+ new_parent.appendChild(el);
+};
+
+// This gets called when the user presses a mouse button anywhere in the
+// document, if the calendar is shown. If the click was outside the open
+// calendar this function closes it.
+Calendar._checkCalendar = function(ev) {
+ var calendar = window._dynarch_popupCalendar;
+ if (!calendar) {
+ return false;
+ }
+ var el = Calendar.is_ie ? Calendar.getElement(ev) : Calendar.getTargetElement(ev);
+ for (; el != null && el != calendar.element; el = el.parentNode);
+ if (el == null) {
+ // calls closeHandler which should hide the calendar.
+ window._dynarch_popupCalendar.callCloseHandler();
+ return Calendar.stopEvent(ev);
+ }
+};
+
+/** Shows the calendar. */
+Calendar.prototype.show = function () {
+ var rows = this.table.getElementsByTagName("tr");
+ for (var i = rows.length; i > 0;) {
+ var row = rows[--i];
+ Calendar.removeClass(row, "rowhilite");
+ var cells = row.getElementsByTagName("td");
+ for (var j = cells.length; j > 0;) {
+ var cell = cells[--j];
+ Calendar.removeClass(cell, "hilite");
+ Calendar.removeClass(cell, "active");
+ }
+ }
+ this.element.style.display = "block";
+ this.hidden = false;
+ if (this.isPopup) {
+ window._dynarch_popupCalendar = this;
+ Calendar.addEvent(document, "keydown", Calendar._keyEvent);
+ Calendar.addEvent(document, "keypress", Calendar._keyEvent);
+ Calendar.addEvent(document, "mousedown", Calendar._checkCalendar);
+ }
+ this.hideShowCovered();
+};
+
+/**
+ * Hides the calendar. Also removes any "hilite" from the class of any TD
+ * element.
+ */
+Calendar.prototype.hide = function () {
+ if (this.isPopup) {
+ Calendar.removeEvent(document, "keydown", Calendar._keyEvent);
+ Calendar.removeEvent(document, "keypress", Calendar._keyEvent);
+ Calendar.removeEvent(document, "mousedown", Calendar._checkCalendar);
+ }
+ this.element.style.display = "none";
+ this.hidden = true;
+ this.hideShowCovered();
+};
+
+/**
+ * Shows the calendar at a given absolute position (beware that, depending on
+ * the calendar element style -- position property -- this might be relative
+ * to the parent's containing rectangle).
+ */
+Calendar.prototype.showAt = function (x, y) {
+ var s = this.element.style;
+ s.left = x + "px";
+ s.top = y + "px";
+ this.show();
+};
+
+/** Shows the calendar near a given element. */
+Calendar.prototype.showAtElement = function (el, opts) {
+ var self = this;
+ var p = Calendar.getAbsolutePos(el);
+ if (!opts || typeof opts != "string") {
+ this.showAt(p.x, p.y + el.offsetHeight);
+ return true;
+ }
+ function fixPosition(box) {
+ if (box.x < 0)
+ box.x = 0;
+ if (box.y < 0)
+ box.y = 0;
+ var cp = document.createElement("div");
+ var s = cp.style;
+ s.position = "absolute";
+ s.right = s.bottom = s.width = s.height = "0px";
+ document.body.appendChild(cp);
+ var br = Calendar.getAbsolutePos(cp);
+ document.body.removeChild(cp);
+ if (Calendar.is_ie) {
+ br.y += document.body.scrollTop;
+ br.x += document.body.scrollLeft;
+ } else {
+ br.y += window.scrollY;
+ br.x += window.scrollX;
+ }
+ var tmp = box.x + box.width - br.x;
+ if (tmp > 0) box.x -= tmp;
+ tmp = box.y + box.height - br.y;
+ if (tmp > 0) box.y -= tmp;
+ };
+ this.element.style.display = "block";
+ Calendar.continuation_for_the_fucking_khtml_browser = function() {
+ var w = self.element.offsetWidth;
+ var h = self.element.offsetHeight;
+ self.element.style.display = "none";
+ var valign = opts.substr(0, 1);
+ var halign = "l";
+ if (opts.length > 1) {
+ halign = opts.substr(1, 1);
+ }
+ // vertical alignment
+ switch (valign) {
+ case "T": p.y -= h; break;
+ case "B": p.y += el.offsetHeight; break;
+ case "C": p.y += (el.offsetHeight - h) / 2; break;
+ case "t": p.y += el.offsetHeight - h; break;
+ case "b": break; // already there
+ }
+ // horizontal alignment
+ switch (halign) {
+ case "L": p.x -= w; break;
+ case "R": p.x += el.offsetWidth; break;
+ case "C": p.x += (el.offsetWidth - w) / 2; break;
+ case "l": p.x += el.offsetWidth - w; break;
+ case "r": break; // already there
+ }
+ p.width = w;
+ p.height = h + 40;
+ self.monthsCombo.style.display = "none";
+ fixPosition(p);
+ self.showAt(p.x, p.y);
+ };
+ if (Calendar.is_khtml)
+ setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()", 10);
+ else
+ Calendar.continuation_for_the_fucking_khtml_browser();
+};
+
+/** Customizes the date format. */
+Calendar.prototype.setDateFormat = function (str) {
+ this.dateFormat = str;
+};
+
+/** Customizes the tooltip date format. */
+Calendar.prototype.setTtDateFormat = function (str) {
+ this.ttDateFormat = str;
+};
+
+/**
+ * Tries to identify the date represented in a string. If successful it also
+ * calls this.setDate which moves the calendar to the given date.
+ */
+Calendar.prototype.parseDate = function(str, fmt) {
+ if (!fmt)
+ fmt = this.dateFormat;
+ this.setDate(Date.parseDate(str, fmt));
+};
+
+Calendar.prototype.hideShowCovered = function () {
+ if (!Calendar.is_ie && !Calendar.is_opera)
+ return;
+ function getVisib(obj){
+ var value = obj.style.visibility;
+ if (!value) {
+ if (document.defaultView && typeof (document.defaultView.getComputedStyle) == "function") { // Gecko, W3C
+ if (!Calendar.is_khtml)
+ value = document.defaultView.
+ getComputedStyle(obj, "").getPropertyValue("visibility");
+ else
+ value = '';
+ } else if (obj.currentStyle) { // IE
+ value = obj.currentStyle.visibility;
+ } else
+ value = '';
+ }
+ return value;
+ };
+
+ var tags = new Array("applet", "iframe", "select");
+ var el = this.element;
+
+ var p = Calendar.getAbsolutePos(el);
+ var EX1 = p.x;
+ var EX2 = el.offsetWidth + EX1;
+ var EY1 = p.y;
+ var EY2 = el.offsetHeight + EY1;
+
+ for (var k = tags.length; k > 0; ) {
+ var ar = document.getElementsByTagName(tags[--k]);
+ var cc = null;
+
+ for (var i = ar.length; i > 0;) {
+ cc = ar[--i];
+
+ p = Calendar.getAbsolutePos(cc);
+ var CX1 = p.x;
+ var CX2 = cc.offsetWidth + CX1;
+ var CY1 = p.y;
+ var CY2 = cc.offsetHeight + CY1;
+
+ if (this.hidden || (CX1 > EX2) || (CX2 < EX1) || (CY1 > EY2) || (CY2 < EY1)) {
+ if (!cc.__msh_save_visibility) {
+ cc.__msh_save_visibility = getVisib(cc);
+ }
+ cc.style.visibility = cc.__msh_save_visibility;
+ } else {
+ if (!cc.__msh_save_visibility) {
+ cc.__msh_save_visibility = getVisib(cc);
+ }
+ cc.style.visibility = "hidden";
+ }
+ }
+ }
+};
+
+/** Internal function; it displays the bar with the names of the weekday. */
+Calendar.prototype._displayWeekdays = function () {
+ var fdow = this.firstDayOfWeek;
+ var cell = this.firstdayname;
+ var weekend = Calendar._TT["WEEKEND"];
+ for (var i = 0; i < 7; ++i) {
+ cell.className = "day name";
+ var realday = (i + fdow) % 7;
+ if (i) {
+ cell.ttip = Calendar._TT["DAY_FIRST"].replace("%s", Calendar._DN[realday]);
+ cell.navtype = 100;
+ cell.calendar = this;
+ cell.fdow = realday;
+ Calendar._add_evs(cell);
+ }
+ if (weekend.indexOf(realday.toString()) != -1) {
+ Calendar.addClass(cell, "weekend");
+ }
+ cell.innerHTML = Calendar._SDN[(i + fdow) % 7];
+ cell = cell.nextSibling;
+ }
+};
+
+/** Internal function. Hides all combo boxes that might be displayed. */
+Calendar.prototype._hideCombos = function () {
+ this.monthsCombo.style.display = "none";
+ this.yearsCombo.style.display = "none";
+};
+
+/** Internal function. Starts dragging the element. */
+Calendar.prototype._dragStart = function (ev) {
+ if (this.dragging) {
+ return;
+ }
+ this.dragging = true;
+ var posX;
+ var posY;
+ if (Calendar.is_ie) {
+ posY = window.event.clientY + document.body.scrollTop;
+ posX = window.event.clientX + document.body.scrollLeft;
+ } else {
+ posY = ev.clientY + window.scrollY;
+ posX = ev.clientX + window.scrollX;
+ }
+ var st = this.element.style;
+ this.xOffs = posX - parseInt(st.left);
+ this.yOffs = posY - parseInt(st.top);
+ with (Calendar) {
+ addEvent(document, "mousemove", calDragIt);
+ addEvent(document, "mouseup", calDragEnd);
+ }
+};
+
+// BEGIN: DATE OBJECT PATCHES
+
+/** Adds the number of days array to the Date object. */
+Date._MD = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
+
+/** Constants used for time computations */
+Date.SECOND = 1000 /* milliseconds */;
+Date.MINUTE = 60 * Date.SECOND;
+Date.HOUR = 60 * Date.MINUTE;
+Date.DAY = 24 * Date.HOUR;
+Date.WEEK = 7 * Date.DAY;
+
+Date.parseDate = function(str, fmt) {
+ var today = new Date();
+ var y = 0;
+ var m = -1;
+ var d = 0;
+ var a = str.split(/\W+/);
+ var b = fmt.match(/%./g);
+ var i = 0, j = 0;
+ var hr = 0;
+ var min = 0;
+ for (i = 0; i < a.length; ++i) {
+ if (!a[i])
+ continue;
+ switch (b[i]) {
+ case "%d":
+ case "%e":
+ d = parseInt(a[i], 10);
+ break;
+
+ case "%m":
+ m = parseInt(a[i], 10) - 1;
+ break;
+
+ case "%Y":
+ case "%y":
+ y = parseInt(a[i], 10);
+ (y < 100) && (y += (y > 29) ? 1900 : 2000);
+ break;
+
+ case "%b":
+ case "%B":
+ for (j = 0; j < 12; ++j) {
+ if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { m = j; break; }
+ }
+ break;
+
+ case "%H":
+ case "%I":
+ case "%k":
+ case "%l":
+ hr = parseInt(a[i], 10);
+ break;
+
+ case "%P":
+ case "%p":
+ if (/pm/i.test(a[i]) && hr < 12)
+ hr += 12;
+ else if (/am/i.test(a[i]) && hr >= 12)
+ hr -= 12;
+ break;
+
+ case "%M":
+ min = parseInt(a[i], 10);
+ break;
+ }
+ }
+ if (isNaN(y)) y = today.getFullYear();
+ if (isNaN(m)) m = today.getMonth();
+ if (isNaN(d)) d = today.getDate();
+ if (isNaN(hr)) hr = today.getHours();
+ if (isNaN(min)) min = today.getMinutes();
+ if (y != 0 && m != -1 && d != 0)
+ return new Date(y, m, d, hr, min, 0);
+ y = 0; m = -1; d = 0;
+ for (i = 0; i < a.length; ++i) {
+ if (a[i].search(/[a-zA-Z]+/) != -1) {
+ var t = -1;
+ for (j = 0; j < 12; ++j) {
+ if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { t = j; break; }
+ }
+ if (t != -1) {
+ if (m != -1) {
+ d = m+1;
+ }
+ m = t;
+ }
+ } else if (parseInt(a[i], 10) <= 12 && m == -1) {
+ m = a[i]-1;
+ } else if (parseInt(a[i], 10) > 31 && y == 0) {
+ y = parseInt(a[i], 10);
+ (y < 100) && (y += (y > 29) ? 1900 : 2000);
+ } else if (d == 0) {
+ d = a[i];
+ }
+ }
+ if (y == 0)
+ y = today.getFullYear();
+ if (m != -1 && d != 0)
+ return new Date(y, m, d, hr, min, 0);
+ return today;
+};
+
+/** Returns the number of days in the current month */
+Date.prototype.getMonthDays = function(month) {
+ var year = this.getFullYear();
+ if (typeof month == "undefined") {
+ month = this.getMonth();
+ }
+ if (((0 == (year%4)) && ( (0 != (year%100)) || (0 == (year%400)))) && month == 1) {
+ return 29;
+ } else {
+ return Date._MD[month];
+ }
+};
+
+/** Returns the number of day in the year. */
+Date.prototype.getDayOfYear = function() {
+ var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
+ var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0);
+ var time = now - then;
+ return Math.floor(time / Date.DAY);
+};
+
+/** Returns the number of the week in year, as defined in ISO 8601. */
+Date.prototype.getWeekNumber = function() {
+ var d = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
+ var DoW = d.getDay();
+ d.setDate(d.getDate() - (DoW + 6) % 7 + 3); // Nearest Thu
+ var ms = d.valueOf(); // GMT
+ d.setMonth(0);
+ d.setDate(4); // Thu in Week 1
+ return Math.round((ms - d.valueOf()) / (7 * 864e5)) + 1;
+};
+
+/** Checks date and time equality */
+Date.prototype.equalsTo = function(date) {
+ return ((this.getFullYear() == date.getFullYear()) &&
+ (this.getMonth() == date.getMonth()) &&
+ (this.getDate() == date.getDate()) &&
+ (this.getHours() == date.getHours()) &&
+ (this.getMinutes() == date.getMinutes()));
+};
+
+/** Set only the year, month, date parts (keep existing time) */
+Date.prototype.setDateOnly = function(date) {
+ var tmp = new Date(date);
+ this.setDate(1);
+ this.setFullYear(tmp.getFullYear());
+ this.setMonth(tmp.getMonth());
+ this.setDate(tmp.getDate());
+};
+
+/** Prints the date in a string according to the given format. */
+Date.prototype.print = function (str) {
+ var m = this.getMonth();
+ var d = this.getDate();
+ var y = this.getFullYear();
+ var wn = this.getWeekNumber();
+ var w = this.getDay();
+ var s = {};
+ var hr = this.getHours();
+ var pm = (hr >= 12);
+ var ir = (pm) ? (hr - 12) : hr;
+ var dy = this.getDayOfYear();
+ if (ir == 0)
+ ir = 12;
+ var min = this.getMinutes();
+ var sec = this.getSeconds();
+ s["%a"] = Calendar._SDN[w]; // abbreviated weekday name [FIXME: I18N]
+ s["%A"] = Calendar._DN[w]; // full weekday name
+ s["%b"] = Calendar._SMN[m]; // abbreviated month name [FIXME: I18N]
+ s["%B"] = Calendar._MN[m]; // full month name
+ // FIXME: %c : preferred date and time representation for the current locale
+ s["%C"] = 1 + Math.floor(y / 100); // the century number
+ s["%d"] = (d < 10) ? ("0" + d) : d; // the day of the month (range 01 to 31)
+ s["%e"] = d; // the day of the month (range 1 to 31)
+ // FIXME: %D : american date style: %m/%d/%y
+ // FIXME: %E, %F, %G, %g, %h (man strftime)
+ s["%H"] = (hr < 10) ? ("0" + hr) : hr; // hour, range 00 to 23 (24h format)
+ s["%I"] = (ir < 10) ? ("0" + ir) : ir; // hour, range 01 to 12 (12h format)
+ s["%j"] = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy; // day of the year (range 001 to 366)
+ s["%k"] = hr; // hour, range 0 to 23 (24h format)
+ s["%l"] = ir; // hour, range 1 to 12 (12h format)
+ s["%m"] = (m < 9) ? ("0" + (1+m)) : (1+m); // month, range 01 to 12
+ s["%M"] = (min < 10) ? ("0" + min) : min; // minute, range 00 to 59
+ s["%n"] = "\n"; // a newline character
+ s["%p"] = pm ? "PM" : "AM";
+ s["%P"] = pm ? "pm" : "am";
+ // FIXME: %r : the time in am/pm notation %I:%M:%S %p
+ // FIXME: %R : the time in 24-hour notation %H:%M
+ s["%s"] = Math.floor(this.getTime() / 1000);
+ s["%S"] = (sec < 10) ? ("0" + sec) : sec; // seconds, range 00 to 59
+ s["%t"] = "\t"; // a tab character
+ // FIXME: %T : the time in 24-hour notation (%H:%M:%S)
+ s["%U"] = s["%W"] = s["%V"] = (wn < 10) ? ("0" + wn) : wn;
+ s["%u"] = w + 1; // the day of the week (range 1 to 7, 1 = MON)
+ s["%w"] = w; // the day of the week (range 0 to 6, 0 = SUN)
+ // FIXME: %x : preferred date representation for the current locale without the time
+ // FIXME: %X : preferred time representation for the current locale without the date
+ s["%y"] = ('' + y).substr(2, 2); // year without the century (range 00 to 99)
+ s["%Y"] = y; // year with the century
+ s["%%"] = "%"; // a literal '%' character
+
+ var re = /%./g;
+ if (!Calendar.is_ie5 && !Calendar.is_khtml)
+ return str.replace(re, function (par) { return s[par] || par; });
+
+ var a = str.match(re);
+ for (var i = 0; i < a.length; i++) {
+ var tmp = s[a[i]];
+ if (tmp) {
+ re = new RegExp(a[i], 'g');
+ str = str.replace(re, tmp);
+ }
+ }
+
+ return str;
+};
+
+Date.prototype.__msh_oldSetFullYear = Date.prototype.setFullYear;
+Date.prototype.setFullYear = function(y) {
+ var d = new Date(this);
+ d.__msh_oldSetFullYear(y);
+ if (d.getMonth() != this.getMonth())
+ this.setDate(28);
+ this.__msh_oldSetFullYear(y);
+};
+
+// END: DATE OBJECT PATCHES
+
+
+// global object that remembers the calendar
+window._dynarch_popupCalendar = null;
diff --git a/WebContent/themes/default/jscalendar/calendar_stripped.js b/WebContent/themes/default/jscalendar/calendar_stripped.js
new file mode 100644
index 0000000000..4fe03f1ea9
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/calendar_stripped.js
@@ -0,0 +1,14 @@
+/* Copyright Mihai Bazon, 2002-2005 | www.bazon.net/mishoo
+ * -----------------------------------------------------------
+ *
+ * The DHTML Calendar, version 1.0 "It is happening again"
+ *
+ * Details and latest version at:
+ * www.dynarch.com/projects/calendar
+ *
+ * This script is developed by Dynarch.com. Visit us at www.dynarch.com.
+ *
+ * This script is distributed under the GNU Lesser General Public License.
+ * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html
+ */
+ Calendar=function(firstDayOfWeek,dateStr,onSelected,onClose){this.activeDiv=null;this.currentDateEl=null;this.getDateStatus=null;this.getDateToolTip=null;this.getDateText=null;this.timeout=null;this.onSelected=onSelected||null;this.onClose=onClose||null;this.dragging=false;this.hidden=false;this.minYear=1970;this.maxYear=2050;this.dateFormat=Calendar._TT["DEF_DATE_FORMAT"];this.ttDateFormat=Calendar._TT["TT_DATE_FORMAT"];this.isPopup=true;this.weekNumbers=true;this.firstDayOfWeek=typeof firstDayOfWeek=="number"?firstDayOfWeek:Calendar._FD;this.showsOtherMonths=false;this.dateStr=dateStr;this.ar_days=null;this.showsTime=false;this.time24=true;this.yearStep=2;this.hiliteToday=true;this.multiple=null;this.table=null;this.element=null;this.tbody=null;this.firstdayname=null;this.monthsCombo=null;this.yearsCombo=null;this.hilitedMonth=null;this.activeMonth=null;this.hilitedYear=null;this.activeYear=null;this.dateClicked=false;if(typeof Calendar._SDN=="undefined"){if(typeof Calendar._SDN_len=="undefined")Calendar._SDN_len=3;var ar=new Array();for(var i=8;i>0;){ar[--i]=Calendar._DN[i].substr(0,Calendar._SDN_len);}Calendar._SDN=ar;if(typeof Calendar._SMN_len=="undefined")Calendar._SMN_len=3;ar=new Array();for(var i=12;i>0;){ar[--i]=Calendar._MN[i].substr(0,Calendar._SMN_len);}Calendar._SMN=ar;}};Calendar._C=null;Calendar.is_ie=(/msie/i.test(navigator.userAgent)&&!/opera/i.test(navigator.userAgent));Calendar.is_ie5=(Calendar.is_ie&&/msie 5\.0/i.test(navigator.userAgent));Calendar.is_opera=/opera/i.test(navigator.userAgent);Calendar.is_khtml=/Konqueror|Safari|KHTML/i.test(navigator.userAgent);Calendar.getAbsolutePos=function(el){var SL=0,ST=0;var is_div=/^div$/i.test(el.tagName);if(is_div&&el.scrollLeft)SL=el.scrollLeft;if(is_div&&el.scrollTop)ST=el.scrollTop;var r={x:el.offsetLeft-SL,y:el.offsetTop-ST};if(el.offsetParent){var tmp=this.getAbsolutePos(el.offsetParent);r.x+=tmp.x;r.y+=tmp.y;}return r;};Calendar.isRelated=function(el,evt){var related=evt.relatedTarget;if(!related){var type=evt.type;if(type=="mouseover"){related=evt.fromElement;}else if(type=="mouseout"){related=evt.toElement;}}while(related){if(related==el){return true;}related=related.parentNode;}return false;};Calendar.removeClass=function(el,className){if(!(el&&el.className)){return;}var cls=el.className.split(" ");var ar=new Array();for(var i=cls.length;i>0;){if(cls[--i]!=className){ar[ar.length]=cls[i];}}el.className=ar.join(" ");};Calendar.addClass=function(el,className){Calendar.removeClass(el,className);el.className+=" "+className;};Calendar.getElement=function(ev){var f=Calendar.is_ie?window.event.srcElement:ev.currentTarget;while(f.nodeType!=1||/^div$/i.test(f.tagName))f=f.parentNode;return f;};Calendar.getTargetElement=function(ev){var f=Calendar.is_ie?window.event.srcElement:ev.target;while(f.nodeType!=1)f=f.parentNode;return f;};Calendar.stopEvent=function(ev){ev||(ev=window.event);if(Calendar.is_ie){ev.cancelBubble=true;ev.returnValue=false;}else{ev.preventDefault();ev.stopPropagation();}return false;};Calendar.addEvent=function(el,evname,func){if(el.attachEvent){el.attachEvent("on"+evname,func);}else if(el.addEventListener){el.addEventListener(evname,func,true);}else{el["on"+evname]=func;}};Calendar.removeEvent=function(el,evname,func){if(el.detachEvent){el.detachEvent("on"+evname,func);}else if(el.removeEventListener){el.removeEventListener(evname,func,true);}else{el["on"+evname]=null;}};Calendar.createElement=function(type,parent){var el=null;if(document.createElementNS){el=document.createElementNS("http://www.w3.org/1999/xhtml",type);}else{el=document.createElement(type);}if(typeof parent!="undefined"){parent.appendChild(el);}return el;};Calendar._add_evs=function(el){with(Calendar){addEvent(el,"mouseover",dayMouseOver);addEvent(el,"mousedown",dayMouseDown);addEvent(el,"mouseout",dayMouseOut);if(is_ie){addEvent(el,"dblclick",dayMouseDblClick);el.setAttribute("unselectable",true);}}};Calendar.findMonth=function(el){if(typeof el.month!="undefined"){return el;}else if(typeof el.parentNode.month!="undefined"){return el.parentNode;}return null;};Calendar.findYear=function(el){if(typeof el.year!="undefined"){return el;}else if(typeof el.parentNode.year!="undefined"){return el.parentNode;}return null;};Calendar.showMonthsCombo=function(){var cal=Calendar._C;if(!cal){return false;}var cal=cal;var cd=cal.activeDiv;var mc=cal.monthsCombo;if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}if(cal.activeMonth){Calendar.removeClass(cal.activeMonth,"active");}var mon=cal.monthsCombo.getElementsByTagName("div")[cal.date.getMonth()];Calendar.addClass(mon,"active");cal.activeMonth=mon;var s=mc.style;s.display="block";if(cd.navtype<0)s.left=cd.offsetLeft+"px";else{var mcw=mc.offsetWidth;if(typeof mcw=="undefined")mcw=50;s.left=(cd.offsetLeft+cd.offsetWidth-mcw)+"px";}s.top=(cd.offsetTop+cd.offsetHeight)+"px";};Calendar.showYearsCombo=function(fwd){var cal=Calendar._C;if(!cal){return false;}var cal=cal;var cd=cal.activeDiv;var yc=cal.yearsCombo;if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}if(cal.activeYear){Calendar.removeClass(cal.activeYear,"active");}cal.activeYear=null;var Y=cal.date.getFullYear()+(fwd?1:-1);var yr=yc.firstChild;var show=false;for(var i=12;i>0;--i){if(Y>=cal.minYear&&Y<=cal.maxYear){yr.innerHTML=Y;yr.year=Y;yr.style.display="block";show=true;}else{yr.style.display="none";}yr=yr.nextSibling;Y+=fwd?cal.yearStep:-cal.yearStep;}if(show){var s=yc.style;s.display="block";if(cd.navtype<0)s.left=cd.offsetLeft+"px";else{var ycw=yc.offsetWidth;if(typeof ycw=="undefined")ycw=50;s.left=(cd.offsetLeft+cd.offsetWidth-ycw)+"px";}s.top=(cd.offsetTop+cd.offsetHeight)+"px";}};Calendar.tableMouseUp=function(ev){var cal=Calendar._C;if(!cal){return false;}if(cal.timeout){clearTimeout(cal.timeout);}var el=cal.activeDiv;if(!el){return false;}var target=Calendar.getTargetElement(ev);ev||(ev=window.event);Calendar.removeClass(el,"active");if(target==el||target.parentNode==el){Calendar.cellClick(el,ev);}var mon=Calendar.findMonth(target);var date=null;if(mon){date=new Date(cal.date);if(mon.month!=date.getMonth()){date.setMonth(mon.month);cal.setDate(date);cal.dateClicked=false;cal.callHandler();}}else{var year=Calendar.findYear(target);if(year){date=new Date(cal.date);if(year.year!=date.getFullYear()){date.setFullYear(year.year);cal.setDate(date);cal.dateClicked=false;cal.callHandler();}}}with(Calendar){removeEvent(document,"mouseup",tableMouseUp);removeEvent(document,"mouseover",tableMouseOver);removeEvent(document,"mousemove",tableMouseOver);cal._hideCombos();_C=null;return stopEvent(ev);}};Calendar.tableMouseOver=function(ev){var cal=Calendar._C;if(!cal){return;}var el=cal.activeDiv;var target=Calendar.getTargetElement(ev);if(target==el||target.parentNode==el){Calendar.addClass(el,"hilite active");Calendar.addClass(el.parentNode,"rowhilite");}else{if(typeof el.navtype=="undefined"||(el.navtype!=50&&(el.navtype==0||Math.abs(el.navtype)>2)))Calendar.removeClass(el,"active");Calendar.removeClass(el,"hilite");Calendar.removeClass(el.parentNode,"rowhilite");}ev||(ev=window.event);if(el.navtype==50&&target!=el){var pos=Calendar.getAbsolutePos(el);var w=el.offsetWidth;var x=ev.clientX;var dx;var decrease=true;if(x>pos.x+w){dx=x-pos.x-w;decrease=false;}else dx=pos.x-x;if(dx<0)dx=0;var range=el._range;var current=el._current;var count=Math.floor(dx/10)%range.length;for(var i=range.length;--i>=0;)if(range[i]==current)break;while(count-->0)if(decrease){if(--i<0)i=range.length-1;}else if(++i>=range.length)i=0;var newval=range[i];el.innerHTML=newval;cal.onUpdateTime();}var mon=Calendar.findMonth(target);if(mon){if(mon.month!=cal.date.getMonth()){if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}Calendar.addClass(mon,"hilite");cal.hilitedMonth=mon;}else if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}}else{if(cal.hilitedMonth){Calendar.removeClass(cal.hilitedMonth,"hilite");}var year=Calendar.findYear(target);if(year){if(year.year!=cal.date.getFullYear()){if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}Calendar.addClass(year,"hilite");cal.hilitedYear=year;}else if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}}else if(cal.hilitedYear){Calendar.removeClass(cal.hilitedYear,"hilite");}}return Calendar.stopEvent(ev);};Calendar.tableMouseDown=function(ev){if(Calendar.getTargetElement(ev)==Calendar.getElement(ev)){return Calendar.stopEvent(ev);}};Calendar.calDragIt=function(ev){var cal=Calendar._C;if(!(cal&&cal.dragging)){return false;}var posX;var posY;if(Calendar.is_ie){posY=window.event.clientY+document.body.scrollTop;posX=window.event.clientX+document.body.scrollLeft;}else{posX=ev.pageX;posY=ev.pageY;}cal.hideShowCovered();var st=cal.element.style;st.left=(posX-cal.xOffs)+"px";st.top=(posY-cal.yOffs)+"px";return Calendar.stopEvent(ev);};Calendar.calDragEnd=function(ev){var cal=Calendar._C;if(!cal){return false;}cal.dragging=false;with(Calendar){removeEvent(document,"mousemove",calDragIt);removeEvent(document,"mouseup",calDragEnd);tableMouseUp(ev);}cal.hideShowCovered();};Calendar.dayMouseDown=function(ev){var el=Calendar.getElement(ev);if(el.disabled){return false;}var cal=el.calendar;cal.activeDiv=el;Calendar._C=cal;if(el.navtype!=300)with(Calendar){if(el.navtype==50){el._current=el.innerHTML;addEvent(document,"mousemove",tableMouseOver);}else addEvent(document,Calendar.is_ie5?"mousemove":"mouseover",tableMouseOver);addClass(el,"hilite active");addEvent(document,"mouseup",tableMouseUp);}else if(cal.isPopup){cal._dragStart(ev);}if(el.navtype==-1||el.navtype==1){if(cal.timeout)clearTimeout(cal.timeout);cal.timeout=setTimeout("Calendar.showMonthsCombo()",250);}else if(el.navtype==-2||el.navtype==2){if(cal.timeout)clearTimeout(cal.timeout);cal.timeout=setTimeout((el.navtype>0)?"Calendar.showYearsCombo(true)":"Calendar.showYearsCombo(false)",250);}else{cal.timeout=null;}return Calendar.stopEvent(ev);};Calendar.dayMouseDblClick=function(ev){Calendar.cellClick(Calendar.getElement(ev),ev||window.event);if(Calendar.is_ie){document.selection.empty();}};Calendar.dayMouseOver=function(ev){var el=Calendar.getElement(ev);if(Calendar.isRelated(el,ev)||Calendar._C||el.disabled){return false;}if(el.ttip){if(el.ttip.substr(0,1)=="_"){el.ttip=el.caldate.print(el.calendar.ttDateFormat)+el.ttip.substr(1);}el.calendar.tooltips.innerHTML=el.ttip;}if(el.navtype!=300){Calendar.addClass(el,"hilite");if(el.caldate){Calendar.addClass(el.parentNode,"rowhilite");}}return Calendar.stopEvent(ev);};Calendar.dayMouseOut=function(ev){with(Calendar){var el=getElement(ev);if(isRelated(el,ev)||_C||el.disabled)return false;removeClass(el,"hilite");if(el.caldate)removeClass(el.parentNode,"rowhilite");if(el.calendar)el.calendar.tooltips.innerHTML=_TT["SEL_DATE"];return stopEvent(ev);}};Calendar.cellClick=function(el,ev){var cal=el.calendar;var closing=false;var newdate=false;var date=null;if(typeof el.navtype=="undefined"){if(cal.currentDateEl){Calendar.removeClass(cal.currentDateEl,"selected");Calendar.addClass(el,"selected");closing=(cal.currentDateEl==el);if(!closing){cal.currentDateEl=el;}}cal.date.setDateOnly(el.caldate);date=cal.date;var other_month=!(cal.dateClicked=!el.otherMonth);if(!other_month&&!cal.currentDateEl)cal._toggleMultipleDate(new Date(date));else newdate=!el.disabled;if(other_month)cal._init(cal.firstDayOfWeek,date);}else{if(el.navtype==200){Calendar.removeClass(el,"hilite");cal.callCloseHandler();return;}date=new Date(cal.date);if(el.navtype==0)date.setDateOnly(new Date());cal.dateClicked=false;var year=date.getFullYear();var mon=date.getMonth();function setMonth(m){var day=date.getDate();var max=date.getMonthDays(m);if(day>max){date.setDate(max);}date.setMonth(m);};switch(el.navtype){case 400:Calendar.removeClass(el,"hilite");var text=Calendar._TT["ABOUT"];if(typeof text!="undefined"){text+=cal.showsTime?Calendar._TT["ABOUT_TIME"]:"";}else{text="Help and about box text is not translated into this language.\n"+"If you know this language and you feel generous please update\n"+"the corresponding file in \"lang\" subdir to match calendar-en.js\n"+"and send it back to <mihai_bazon@yahoo.com> to get it into the distribution ;-)\n\n"+"Thank you!\n"+"http://dynarch.com/mishoo/calendar.epl\n";}alert(text);return;case-2:if(year>cal.minYear){date.setFullYear(year-1);}break;case-1:if(mon>0){setMonth(mon-1);}else if(year-->cal.minYear){date.setFullYear(year);setMonth(11);}break;case 1:if(mon<11){setMonth(mon+1);}else if(year<cal.maxYear){date.setFullYear(year+1);setMonth(0);}break;case 2:if(year<cal.maxYear){date.setFullYear(year+1);}break;case 100:cal.setFirstDayOfWeek(el.fdow);return;case 50:var range=el._range;var current=el.innerHTML;for(var i=range.length;--i>=0;)if(range[i]==current)break;if(ev&&ev.shiftKey){if(--i<0)i=range.length-1;}else if(++i>=range.length)i=0;var newval=range[i];el.innerHTML=newval;cal.onUpdateTime();return;case 0:if((typeof cal.getDateStatus=="function")&&cal.getDateStatus(date,date.getFullYear(),date.getMonth(),date.getDate())){return false;}break;}if(!date.equalsTo(cal.date)){cal.setDate(date);newdate=true;}else if(el.navtype==0)newdate=closing=true;}if(newdate){ev&&cal.callHandler();}if(closing){Calendar.removeClass(el,"hilite");ev&&cal.callCloseHandler();}};Calendar.prototype.create=function(_par){var parent=null;if(!_par){parent=document.getElementsByTagName("body")[0];this.isPopup=true;}else{parent=_par;this.isPopup=false;}this.date=this.dateStr?new Date(this.dateStr):new Date();var table=Calendar.createElement("table");this.table=table;table.cellSpacing=0;table.cellPadding=0;table.calendar=this;Calendar.addEvent(table,"mousedown",Calendar.tableMouseDown);var div=Calendar.createElement("div");this.element=div;div.className="calendar";if(this.isPopup){div.style.position="absolute";div.style.display="none";}div.appendChild(table);var thead=Calendar.createElement("thead",table);var cell=null;var row=null;var cal=this;var hh=function(text,cs,navtype){cell=Calendar.createElement("td",row);cell.colSpan=cs;cell.className="button";if(navtype!=0&&Math.abs(navtype)<=2)cell.className+=" nav";Calendar._add_evs(cell);cell.calendar=cal;cell.navtype=navtype;cell.innerHTML="<div unselectable='on'>"+text+"</div>";return cell;};row=Calendar.createElement("tr",thead);var title_length=6;(this.isPopup)&&--title_length;(this.weekNumbers)&&++title_length;hh("?",1,400).ttip=Calendar._TT["INFO"];this.title=hh("",title_length,300);this.title.className="title";if(this.isPopup){this.title.ttip=Calendar._TT["DRAG_TO_MOVE"];this.title.style.cursor="move";hh("&#x00d7;",1,200).ttip=Calendar._TT["CLOSE"];}row=Calendar.createElement("tr",thead);row.className="headrow";this._nav_py=hh("&#x00ab;",1,-2);this._nav_py.ttip=Calendar._TT["PREV_YEAR"];this._nav_pm=hh("&#x2039;",1,-1);this._nav_pm.ttip=Calendar._TT["PREV_MONTH"];this._nav_now=hh(Calendar._TT["TODAY"],this.weekNumbers?4:3,0);this._nav_now.ttip=Calendar._TT["GO_TODAY"];this._nav_nm=hh("&#x203a;",1,1);this._nav_nm.ttip=Calendar._TT["NEXT_MONTH"];this._nav_ny=hh("&#x00bb;",1,2);this._nav_ny.ttip=Calendar._TT["NEXT_YEAR"];row=Calendar.createElement("tr",thead);row.className="daynames";if(this.weekNumbers){cell=Calendar.createElement("td",row);cell.className="name wn";cell.innerHTML=Calendar._TT["WK"];}for(var i=7;i>0;--i){cell=Calendar.createElement("td",row);if(!i){cell.navtype=100;cell.calendar=this;Calendar._add_evs(cell);}}this.firstdayname=(this.weekNumbers)?row.firstChild.nextSibling:row.firstChild;this._displayWeekdays();var tbody=Calendar.createElement("tbody",table);this.tbody=tbody;for(i=6;i>0;--i){row=Calendar.createElement("tr",tbody);if(this.weekNumbers){cell=Calendar.createElement("td",row);}for(var j=7;j>0;--j){cell=Calendar.createElement("td",row);cell.calendar=this;Calendar._add_evs(cell);}}if(this.showsTime){row=Calendar.createElement("tr",tbody);row.className="time";cell=Calendar.createElement("td",row);cell.className="time";cell.colSpan=2;cell.innerHTML=Calendar._TT["TIME"]||"&nbsp;";cell=Calendar.createElement("td",row);cell.className="time";cell.colSpan=this.weekNumbers?4:3;(function(){function makeTimePart(className,init,range_start,range_end){var part=Calendar.createElement("span",cell);part.className=className;part.innerHTML=init;part.calendar=cal;part.ttip=Calendar._TT["TIME_PART"];part.navtype=50;part._range=[];if(typeof range_start!="number")part._range=range_start;else{for(var i=range_start;i<=range_end;++i){var txt;if(i<10&&range_end>=10)txt='0'+i;else txt=''+i;part._range[part._range.length]=txt;}}Calendar._add_evs(part);return part;};var hrs=cal.date.getHours();var mins=cal.date.getMinutes();var t12=!cal.time24;var pm=(hrs>12);if(t12&&pm)hrs-=12;var H=makeTimePart("hour",hrs,t12?1:0,t12?12:23);var span=Calendar.createElement("span",cell);span.innerHTML=":";span.className="colon";var M=makeTimePart("minute",mins,0,59);var AP=null;cell=Calendar.createElement("td",row);cell.className="time";cell.colSpan=2;if(t12)AP=makeTimePart("ampm",pm?"pm":"am",["am","pm"]);else cell.innerHTML="&nbsp;";cal.onSetTime=function(){var pm,hrs=this.date.getHours(),mins=this.date.getMinutes();if(t12){pm=(hrs>=12);if(pm)hrs-=12;if(hrs==0)hrs=12;AP.innerHTML=pm?"pm":"am";}H.innerHTML=(hrs<10)?("0"+hrs):hrs;M.innerHTML=(mins<10)?("0"+mins):mins;};cal.onUpdateTime=function(){var date=this.date;var h=parseInt(H.innerHTML,10);if(t12){if(/pm/i.test(AP.innerHTML)&&h<12)h+=12;else if(/am/i.test(AP.innerHTML)&&h==12)h=0;}var d=date.getDate();var m=date.getMonth();var y=date.getFullYear();date.setHours(h);date.setMinutes(parseInt(M.innerHTML,10));date.setFullYear(y);date.setMonth(m);date.setDate(d);this.dateClicked=false;this.callHandler();};})();}else{this.onSetTime=this.onUpdateTime=function(){};}var tfoot=Calendar.createElement("tfoot",table);row=Calendar.createElement("tr",tfoot);row.className="footrow";cell=hh(Calendar._TT["SEL_DATE"],this.weekNumbers?8:7,300);cell.className="ttip";if(this.isPopup){cell.ttip=Calendar._TT["DRAG_TO_MOVE"];cell.style.cursor="move";}this.tooltips=cell;div=Calendar.createElement("div",this.element);this.monthsCombo=div;div.className="combo";for(i=0;i<Calendar._MN.length;++i){var mn=Calendar.createElement("div");mn.className=Calendar.is_ie?"label-IEfix":"label";mn.month=i;mn.innerHTML=Calendar._SMN[i];div.appendChild(mn);}div=Calendar.createElement("div",this.element);this.yearsCombo=div;div.className="combo";for(i=12;i>0;--i){var yr=Calendar.createElement("div");yr.className=Calendar.is_ie?"label-IEfix":"label";div.appendChild(yr);}this._init(this.firstDayOfWeek,this.date);parent.appendChild(this.element);};Calendar._keyEvent=function(ev){var cal=window._dynarch_popupCalendar;if(!cal||cal.multiple)return false;(Calendar.is_ie)&&(ev=window.event);var act=(Calendar.is_ie||ev.type=="keypress"),K=ev.keyCode;if(ev.ctrlKey){switch(K){case 37:act&&Calendar.cellClick(cal._nav_pm);break;case 38:act&&Calendar.cellClick(cal._nav_py);break;case 39:act&&Calendar.cellClick(cal._nav_nm);break;case 40:act&&Calendar.cellClick(cal._nav_ny);break;default:return false;}}else switch(K){case 32:Calendar.cellClick(cal._nav_now);break;case 27:act&&cal.callCloseHandler();break;case 37:case 38:case 39:case 40:if(act){var prev,x,y,ne,el,step;prev=K==37||K==38;step=(K==37||K==39)?1:7;function setVars(){el=cal.currentDateEl;var p=el.pos;x=p&15;y=p>>4;ne=cal.ar_days[y][x];};setVars();function prevMonth(){var date=new Date(cal.date);date.setDate(date.getDate()-step);cal.setDate(date);};function nextMonth(){var date=new Date(cal.date);date.setDate(date.getDate()+step);cal.setDate(date);};while(1){switch(K){case 37:if(--x>=0)ne=cal.ar_days[y][x];else{x=6;K=38;continue;}break;case 38:if(--y>=0)ne=cal.ar_days[y][x];else{prevMonth();setVars();}break;case 39:if(++x<7)ne=cal.ar_days[y][x];else{x=0;K=40;continue;}break;case 40:if(++y<cal.ar_days.length)ne=cal.ar_days[y][x];else{nextMonth();setVars();}break;}break;}if(ne){if(!ne.disabled)Calendar.cellClick(ne);else if(prev)prevMonth();else nextMonth();}}break;case 13:if(act)Calendar.cellClick(cal.currentDateEl,ev);break;default:return false;}return Calendar.stopEvent(ev);};Calendar.prototype._init=function(firstDayOfWeek,date){var today=new Date(),TY=today.getFullYear(),TM=today.getMonth(),TD=today.getDate();this.table.style.visibility="hidden";var year=date.getFullYear();if(year<this.minYear){year=this.minYear;date.setFullYear(year);}else if(year>this.maxYear){year=this.maxYear;date.setFullYear(year);}this.firstDayOfWeek=firstDayOfWeek;this.date=new Date(date);var month=date.getMonth();var mday=date.getDate();var no_days=date.getMonthDays();date.setDate(1);var day1=(date.getDay()-this.firstDayOfWeek)%7;if(day1<0)day1+=7;date.setDate(-day1);date.setDate(date.getDate()+1);var row=this.tbody.firstChild;var MN=Calendar._SMN[month];var ar_days=this.ar_days=new Array();var weekend=Calendar._TT["WEEKEND"];var dates=this.multiple?(this.datesCells={}):null;for(var i=0;i<6;++i,row=row.nextSibling){var cell=row.firstChild;if(this.weekNumbers){cell.className="day wn";cell.innerHTML=date.getWeekNumber();cell=cell.nextSibling;}row.className="daysrow";var hasdays=false,iday,dpos=ar_days[i]=[];for(var j=0;j<7;++j,cell=cell.nextSibling,date.setDate(iday+1)){iday=date.getDate();var wday=date.getDay();cell.className="day";cell.pos=i<<4|j;dpos[j]=cell;var current_month=(date.getMonth()==month);if(!current_month){if(this.showsOtherMonths){cell.className+=" othermonth";cell.otherMonth=true;}else{cell.className="emptycell";cell.innerHTML="&nbsp;";cell.disabled=true;continue;}}else{cell.otherMonth=false;hasdays=true;}cell.disabled=false;cell.innerHTML=this.getDateText?this.getDateText(date,iday):iday;if(dates)dates[date.print("%Y%m%d")]=cell;if(this.getDateStatus){var status=this.getDateStatus(date,year,month,iday);if(this.getDateToolTip){var toolTip=this.getDateToolTip(date,year,month,iday);if(toolTip)cell.title=toolTip;}if(status===true){cell.className+=" disabled";cell.disabled=true;}else{if(/disabled/i.test(status))cell.disabled=true;cell.className+=" "+status;}}if(!cell.disabled){cell.caldate=new Date(date);cell.ttip="_";if(!this.multiple&&current_month&&iday==mday&&this.hiliteToday){cell.className+=" selected";this.currentDateEl=cell;}if(date.getFullYear()==TY&&date.getMonth()==TM&&iday==TD){cell.className+=" today";cell.ttip+=Calendar._TT["PART_TODAY"];}if(weekend.indexOf(wday.toString())!=-1)cell.className+=cell.otherMonth?" oweekend":" weekend";}}if(!(hasdays||this.showsOtherMonths))row.className="emptyrow";}this.title.innerHTML=Calendar._MN[month]+", "+year;this.onSetTime();this.table.style.visibility="visible";this._initMultipleDates();};Calendar.prototype._initMultipleDates=function(){if(this.multiple){for(var i in this.multiple){var cell=this.datesCells[i];var d=this.multiple[i];if(!d)continue;if(cell)cell.className+=" selected";}}};Calendar.prototype._toggleMultipleDate=function(date){if(this.multiple){var ds=date.print("%Y%m%d");var cell=this.datesCells[ds];if(cell){var d=this.multiple[ds];if(!d){Calendar.addClass(cell,"selected");this.multiple[ds]=date;}else{Calendar.removeClass(cell,"selected");delete this.multiple[ds];}}}};Calendar.prototype.setDateToolTipHandler=function(unaryFunction){this.getDateToolTip=unaryFunction;};Calendar.prototype.setDate=function(date){if(!date.equalsTo(this.date)){this._init(this.firstDayOfWeek,date);}};Calendar.prototype.refresh=function(){this._init(this.firstDayOfWeek,this.date);};Calendar.prototype.setFirstDayOfWeek=function(firstDayOfWeek){this._init(firstDayOfWeek,this.date);this._displayWeekdays();};Calendar.prototype.setDateStatusHandler=Calendar.prototype.setDisabledHandler=function(unaryFunction){this.getDateStatus=unaryFunction;};Calendar.prototype.setRange=function(a,z){this.minYear=a;this.maxYear=z;};Calendar.prototype.callHandler=function(){if(this.onSelected){this.onSelected(this,this.date.print(this.dateFormat));}};Calendar.prototype.callCloseHandler=function(){if(this.onClose){this.onClose(this);}this.hideShowCovered();};Calendar.prototype.destroy=function(){var el=this.element.parentNode;el.removeChild(this.element);Calendar._C=null;window._dynarch_popupCalendar=null;};Calendar.prototype.reparent=function(new_parent){var el=this.element;el.parentNode.removeChild(el);new_parent.appendChild(el);};Calendar._checkCalendar=function(ev){var calendar=window._dynarch_popupCalendar;if(!calendar){return false;}var el=Calendar.is_ie?Calendar.getElement(ev):Calendar.getTargetElement(ev);for(;el!=null&&el!=calendar.element;el=el.parentNode);if(el==null){window._dynarch_popupCalendar.callCloseHandler();return Calendar.stopEvent(ev);}};Calendar.prototype.show=function(){var rows=this.table.getElementsByTagName("tr");for(var i=rows.length;i>0;){var row=rows[--i];Calendar.removeClass(row,"rowhilite");var cells=row.getElementsByTagName("td");for(var j=cells.length;j>0;){var cell=cells[--j];Calendar.removeClass(cell,"hilite");Calendar.removeClass(cell,"active");}}this.element.style.display="block";this.hidden=false;if(this.isPopup){window._dynarch_popupCalendar=this;Calendar.addEvent(document,"keydown",Calendar._keyEvent);Calendar.addEvent(document,"keypress",Calendar._keyEvent);Calendar.addEvent(document,"mousedown",Calendar._checkCalendar);}this.hideShowCovered();};Calendar.prototype.hide=function(){if(this.isPopup){Calendar.removeEvent(document,"keydown",Calendar._keyEvent);Calendar.removeEvent(document,"keypress",Calendar._keyEvent);Calendar.removeEvent(document,"mousedown",Calendar._checkCalendar);}this.element.style.display="none";this.hidden=true;this.hideShowCovered();};Calendar.prototype.showAt=function(x,y){var s=this.element.style;s.left=x+"px";s.top=y+"px";this.show();};Calendar.prototype.showAtElement=function(el,opts){var self=this;var p=Calendar.getAbsolutePos(el);if(!opts||typeof opts!="string"){this.showAt(p.x,p.y+el.offsetHeight);return true;}function fixPosition(box){if(box.x<0)box.x=0;if(box.y<0)box.y=0;var cp=document.createElement("div");var s=cp.style;s.position="absolute";s.right=s.bottom=s.width=s.height="0px";document.body.appendChild(cp);var br=Calendar.getAbsolutePos(cp);document.body.removeChild(cp);if(Calendar.is_ie){br.y+=document.body.scrollTop;br.x+=document.body.scrollLeft;}else{br.y+=window.scrollY;br.x+=window.scrollX;}var tmp=box.x+box.width-br.x;if(tmp>0)box.x-=tmp;tmp=box.y+box.height-br.y;if(tmp>0)box.y-=tmp;};this.element.style.display="block";Calendar.continuation_for_the_fucking_khtml_browser=function(){var w=self.element.offsetWidth;var h=self.element.offsetHeight;self.element.style.display="none";var valign=opts.substr(0,1);var halign="l";if(opts.length>1){halign=opts.substr(1,1);}switch(valign){case "T":p.y-=h;break;case "B":p.y+=el.offsetHeight;break;case "C":p.y+=(el.offsetHeight-h)/2;break;case "t":p.y+=el.offsetHeight-h;break;case "b":break;}switch(halign){case "L":p.x-=w;break;case "R":p.x+=el.offsetWidth;break;case "C":p.x+=(el.offsetWidth-w)/2;break;case "l":p.x+=el.offsetWidth-w;break;case "r":break;}p.width=w;p.height=h+40;self.monthsCombo.style.display="none";fixPosition(p);self.showAt(p.x,p.y);};if(Calendar.is_khtml)setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()",10);else Calendar.continuation_for_the_fucking_khtml_browser();};Calendar.prototype.setDateFormat=function(str){this.dateFormat=str;};Calendar.prototype.setTtDateFormat=function(str){this.ttDateFormat=str;};Calendar.prototype.parseDate=function(str,fmt){if(!fmt)fmt=this.dateFormat;this.setDate(Date.parseDate(str,fmt));};Calendar.prototype.hideShowCovered=function(){if(!Calendar.is_ie&&!Calendar.is_opera)return;function getVisib(obj){var value=obj.style.visibility;if(!value){if(document.defaultView&&typeof(document.defaultView.getComputedStyle)=="function"){if(!Calendar.is_khtml)value=document.defaultView. getComputedStyle(obj,"").getPropertyValue("visibility");else value='';}else if(obj.currentStyle){value=obj.currentStyle.visibility;}else value='';}return value;};var tags=new Array("applet","iframe","select");var el=this.element;var p=Calendar.getAbsolutePos(el);var EX1=p.x;var EX2=el.offsetWidth+EX1;var EY1=p.y;var EY2=el.offsetHeight+EY1;for(var k=tags.length;k>0;){var ar=document.getElementsByTagName(tags[--k]);var cc=null;for(var i=ar.length;i>0;){cc=ar[--i];p=Calendar.getAbsolutePos(cc);var CX1=p.x;var CX2=cc.offsetWidth+CX1;var CY1=p.y;var CY2=cc.offsetHeight+CY1;if(this.hidden||(CX1>EX2)||(CX2<EX1)||(CY1>EY2)||(CY2<EY1)){if(!cc.__msh_save_visibility){cc.__msh_save_visibility=getVisib(cc);}cc.style.visibility=cc.__msh_save_visibility;}else{if(!cc.__msh_save_visibility){cc.__msh_save_visibility=getVisib(cc);}cc.style.visibility="hidden";}}}};Calendar.prototype._displayWeekdays=function(){var fdow=this.firstDayOfWeek;var cell=this.firstdayname;var weekend=Calendar._TT["WEEKEND"];for(var i=0;i<7;++i){cell.className="day name";var realday=(i+fdow)%7;if(i){cell.ttip=Calendar._TT["DAY_FIRST"].replace("%s",Calendar._DN[realday]);cell.navtype=100;cell.calendar=this;cell.fdow=realday;Calendar._add_evs(cell);}if(weekend.indexOf(realday.toString())!=-1){Calendar.addClass(cell,"weekend");}cell.innerHTML=Calendar._SDN[(i+fdow)%7];cell=cell.nextSibling;}};Calendar.prototype._hideCombos=function(){this.monthsCombo.style.display="none";this.yearsCombo.style.display="none";};Calendar.prototype._dragStart=function(ev){if(this.dragging){return;}this.dragging=true;var posX;var posY;if(Calendar.is_ie){posY=window.event.clientY+document.body.scrollTop;posX=window.event.clientX+document.body.scrollLeft;}else{posY=ev.clientY+window.scrollY;posX=ev.clientX+window.scrollX;}var st=this.element.style;this.xOffs=posX-parseInt(st.left);this.yOffs=posY-parseInt(st.top);with(Calendar){addEvent(document,"mousemove",calDragIt);addEvent(document,"mouseup",calDragEnd);}};Date._MD=new Array(31,28,31,30,31,30,31,31,30,31,30,31);Date.SECOND=1000;Date.MINUTE=60*Date.SECOND;Date.HOUR=60*Date.MINUTE;Date.DAY=24*Date.HOUR;Date.WEEK=7*Date.DAY;Date.parseDate=function(str,fmt){var today=new Date();var y=0;var m=-1;var d=0;var a=str.split(/\W+/);var b=fmt.match(/%./g);var i=0,j=0;var hr=0;var min=0;for(i=0;i<a.length;++i){if(!a[i])continue;switch(b[i]){case "%d":case "%e":d=parseInt(a[i],10);break;case "%m":m=parseInt(a[i],10)-1;break;case "%Y":case "%y":y=parseInt(a[i],10);(y<100)&&(y+=(y>29)?1900:2000);break;case "%b":case "%B":for(j=0;j<12;++j){if(Calendar._MN[j].substr(0,a[i].length).toLowerCase()==a[i].toLowerCase()){m=j;break;}}break;case "%H":case "%I":case "%k":case "%l":hr=parseInt(a[i],10);break;case "%P":case "%p":if(/pm/i.test(a[i])&&hr<12)hr+=12;else if(/am/i.test(a[i])&&hr>=12)hr-=12;break;case "%M":min=parseInt(a[i],10);break;}}if(isNaN(y))y=today.getFullYear();if(isNaN(m))m=today.getMonth();if(isNaN(d))d=today.getDate();if(isNaN(hr))hr=today.getHours();if(isNaN(min))min=today.getMinutes();if(y!=0&&m!=-1&&d!=0)return new Date(y,m,d,hr,min,0);y=0;m=-1;d=0;for(i=0;i<a.length;++i){if(a[i].search(/[a-zA-Z]+/)!=-1){var t=-1;for(j=0;j<12;++j){if(Calendar._MN[j].substr(0,a[i].length).toLowerCase()==a[i].toLowerCase()){t=j;break;}}if(t!=-1){if(m!=-1){d=m+1;}m=t;}}else if(parseInt(a[i],10)<=12&&m==-1){m=a[i]-1;}else if(parseInt(a[i],10)>31&&y==0){y=parseInt(a[i],10);(y<100)&&(y+=(y>29)?1900:2000);}else if(d==0){d=a[i];}}if(y==0)y=today.getFullYear();if(m!=-1&&d!=0)return new Date(y,m,d,hr,min,0);return today;};Date.prototype.getMonthDays=function(month){var year=this.getFullYear();if(typeof month=="undefined"){month=this.getMonth();}if(((0==(year%4))&&((0!=(year%100))||(0==(year%400))))&&month==1){return 29;}else{return Date._MD[month];}};Date.prototype.getDayOfYear=function(){var now=new Date(this.getFullYear(),this.getMonth(),this.getDate(),0,0,0);var then=new Date(this.getFullYear(),0,0,0,0,0);var time=now-then;return Math.floor(time/Date.DAY);};Date.prototype.getWeekNumber=function(){var d=new Date(this.getFullYear(),this.getMonth(),this.getDate(),0,0,0);var DoW=d.getDay();d.setDate(d.getDate()-(DoW+6)%7+3);var ms=d.valueOf();d.setMonth(0);d.setDate(4);return Math.round((ms-d.valueOf())/(7*864e5))+1;};Date.prototype.equalsTo=function(date){return((this.getFullYear()==date.getFullYear())&&(this.getMonth()==date.getMonth())&&(this.getDate()==date.getDate())&&(this.getHours()==date.getHours())&&(this.getMinutes()==date.getMinutes()));};Date.prototype.setDateOnly=function(date){var tmp=new Date(date);this.setDate(1);this.setFullYear(tmp.getFullYear());this.setMonth(tmp.getMonth());this.setDate(tmp.getDate());};Date.prototype.print=function(str){var m=this.getMonth();var d=this.getDate();var y=this.getFullYear();var wn=this.getWeekNumber();var w=this.getDay();var s={};var hr=this.getHours();var pm=(hr>=12);var ir=(pm)?(hr-12):hr;var dy=this.getDayOfYear();if(ir==0)ir=12;var min=this.getMinutes();var sec=this.getSeconds();s["%a"]=Calendar._SDN[w];s["%A"]=Calendar._DN[w];s["%b"]=Calendar._SMN[m];s["%B"]=Calendar._MN[m];s["%C"]=1+Math.floor(y/100);s["%d"]=(d<10)?("0"+d):d;s["%e"]=d;s["%H"]=(hr<10)?("0"+hr):hr;s["%I"]=(ir<10)?("0"+ir):ir;s["%j"]=(dy<100)?((dy<10)?("00"+dy):("0"+dy)):dy;s["%k"]=hr;s["%l"]=ir;s["%m"]=(m<9)?("0"+(1+m)):(1+m);s["%M"]=(min<10)?("0"+min):min;s["%n"]="\n";s["%p"]=pm?"PM":"AM";s["%P"]=pm?"pm":"am";s["%s"]=Math.floor(this.getTime()/1000);s["%S"]=(sec<10)?("0"+sec):sec;s["%t"]="\t";s["%U"]=s["%W"]=s["%V"]=(wn<10)?("0"+wn):wn;s["%u"]=w+1;s["%w"]=w;s["%y"]=(''+y).substr(2,2);s["%Y"]=y;s["%%"]="%";var re=/%./g;if(!Calendar.is_ie5&&!Calendar.is_khtml)return str.replace(re,function(par){return s[par]||par;});var a=str.match(re);for(var i=0;i<a.length;i++){var tmp=s[a[i]];if(tmp){re=new RegExp(a[i],'g');str=str.replace(re,tmp);}}return str;};Date.prototype.__msh_oldSetFullYear=Date.prototype.setFullYear;Date.prototype.setFullYear=function(y){var d=new Date(this);d.__msh_oldSetFullYear(y);if(d.getMonth()!=this.getMonth())this.setDate(28);this.__msh_oldSetFullYear(y);};window._dynarch_popupCalendar=null; \ No newline at end of file
diff --git a/WebContent/themes/default/jscalendar/dayinfo.html b/WebContent/themes/default/jscalendar/dayinfo.html
new file mode 100644
index 0000000000..bc415c878c
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/dayinfo.html
@@ -0,0 +1,109 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html> <head>
+<title>How to include additional info in day cells</title>
+<script type="text/javascript" src="calendar.js"></script>
+<script type="text/javascript" src="lang/calendar-en.js"></script>
+<script type="text/javascript" src="calendar-setup.js"></script>
+<script type="text/javascript">
+ // define info for dates in this table:
+ var dateInfo = {
+ "20050308" : "Mishoo's&nbsp;birthday",
+ "20050310" : "foo",
+ "20050315" : "bar",
+ "20050318" : "25$",
+ "20050324" : "60$"
+ };
+</script>
+<style type="text/css">
+ @import url(calendar-win2k-1.css);
+ .calendar .inf { font-size: 80%; color: #444; }
+ .calendar .wn { font-weight: bold; vertical-align: top; }
+</style>
+</head>
+
+<body>
+<h1>How to include additional info in day cells</h1>
+
+<div id="flatcal" style="float: right"></div>
+
+<script type="text/javascript">
+ function getDateText(date, d) {
+ var inf = dateInfo[date.print("%Y%m%d")];
+ if (!inf) {
+ return d + "<div class='inf'>&nbsp;</div>";
+ } else {
+ return d + "<div class='inf'>" + inf + "</div>";
+ }
+ };
+ function flatCallback(cal) {
+ if (cal.dateClicked) {
+ // do something here
+ window.status = "Selected: " + cal.date;
+ var inf = dateInfo[cal.date.print("%Y%m%d")];
+ if (inf) {
+ window.status += ". Additional info: " + inf;
+ }
+ }
+ };
+ Calendar.setup({
+ flat: "flatcal",
+ dateText: getDateText,
+ flatCallback: flatCallback
+ });
+</script>
+
+<p>The idea is simple:</p>
+
+<ol>
+ <li>
+ <p>Define a callback that takes two parameters like this:</p>
+ <pre>function getDateText(date, d)</pre>
+ <p>
+ This function will receive the date object as the first
+ parameter and the current date number (1..31) as the second (you
+ can get it as well by calling date.getDate() but since it's very
+ probably useful I thought I'd pass it too so that we can avoid a
+ function call).
+ </p>
+ <p>
+ This function <em>must</em> return the text to be inserted in
+ the cell of the passed date. That is, one should at least
+ "return d;".
+ </p>
+ </li>
+ <li>
+ Pass the above function as the "dateText" parameter to
+ Calendar.setup.
+ </li>
+</ol>
+
+<p>
+ The function could simply look like:
+</p>
+
+<pre
+> function getDateText(date, d) {
+ if (d == 12) {
+ return "12th";
+ } else if (d == 13) {
+ return "bad luck";
+ } /* ... etc ... */
+ }</pre>
+
+<p>
+ but it's easy to imagine that this approach sucks. For a better
+ way, see the source of this page and note the usage of an externally
+ defined "dateText" object which maps "date" to "date info", also
+ taking into account the year and month. This object can be easily
+ generated from a database, and the getDateText function becomes
+ extremely simple (and static).
+</p>
+
+<p>
+ Cheers!
+</p>
+
+<hr />
+<address><a href="http://dynarch.com/mishoo/">mishoo</a></address>
+<!-- hhmts start --> Last modified: Sat Mar 5 17:18:06 EET 2005 <!-- hhmts end -->
+</body> </html>
diff --git a/WebContent/themes/default/jscalendar/img.gif b/WebContent/themes/default/jscalendar/img.gif
new file mode 100644
index 0000000000..cd2c4a5217
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/img.gif
Binary files differ
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-af.js b/WebContent/themes/default/jscalendar/lang/calendar-af.js
new file mode 100644
index 0000000000..aeda58197b
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-af.js
@@ -0,0 +1,39 @@
+// ** I18N Afrikaans
+Calendar._DN = new Array
+("Sondag",
+ "Maandag",
+ "Dinsdag",
+ "Woensdag",
+ "Donderdag",
+ "Vrydag",
+ "Saterdag",
+ "Sondag");
+Calendar._MN = new Array
+("Januarie",
+ "Februarie",
+ "Maart",
+ "April",
+ "Mei",
+ "Junie",
+ "Julie",
+ "Augustus",
+ "September",
+ "Oktober",
+ "November",
+ "Desember");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["TOGGLE"] = "Verander eerste dag van die week";
+Calendar._TT["PREV_YEAR"] = "Vorige jaar (hou vir keuselys)";
+Calendar._TT["PREV_MONTH"] = "Vorige maand (hou vir keuselys)";
+Calendar._TT["GO_TODAY"] = "Gaan na vandag";
+Calendar._TT["NEXT_MONTH"] = "Volgende maand (hou vir keuselys)";
+Calendar._TT["NEXT_YEAR"] = "Volgende jaar (hou vir keuselys)";
+Calendar._TT["SEL_DATE"] = "Kies datum";
+Calendar._TT["DRAG_TO_MOVE"] = "Sleep om te skuif";
+Calendar._TT["PART_TODAY"] = " (vandag)";
+Calendar._TT["MON_FIRST"] = "Vertoon Maandag eerste";
+Calendar._TT["SUN_FIRST"] = "Display Sunday first";
+Calendar._TT["CLOSE"] = "Close";
+Calendar._TT["TODAY"] = "Today";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-al.js b/WebContent/themes/default/jscalendar/lang/calendar-al.js
new file mode 100644
index 0000000000..4f701cf72d
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-al.js
@@ -0,0 +1,101 @@
+// Calendar ALBANIAN language
+//author Rigels Gordani rige@hotmail.com
+
+// ditet
+Calendar._DN = new Array
+("E Diele",
+"E Hene",
+"E Marte",
+"E Merkure",
+"E Enjte",
+"E Premte",
+"E Shtune",
+"E Diele");
+
+//ditet shkurt
+Calendar._SDN = new Array
+("Die",
+"Hen",
+"Mar",
+"Mer",
+"Enj",
+"Pre",
+"Sht",
+"Die");
+
+// muajt
+Calendar._MN = new Array
+("Janar",
+"Shkurt",
+"Mars",
+"Prill",
+"Maj",
+"Qeshor",
+"Korrik",
+"Gusht",
+"Shtator",
+"Tetor",
+"Nentor",
+"Dhjetor");
+
+// muajte shkurt
+Calendar._SMN = new Array
+("Jan",
+"Shk",
+"Mar",
+"Pri",
+"Maj",
+"Qes",
+"Kor",
+"Gus",
+"Sht",
+"Tet",
+"Nen",
+"Dhj");
+
+// ndihmesa
+Calendar._TT = {};
+Calendar._TT["INFO"] = "Per kalendarin";
+
+Calendar._TT["ABOUT"] =
+"Zgjedhes i ores/dates ne DHTML \n" +
+"\n\n" +"Zgjedhja e Dates:\n" +
+"- Perdor butonat \xab, \xbb per te zgjedhur vitin\n" +
+"- Perdor butonat" + String.fromCharCode(0x2039) + ", " +
+String.fromCharCode(0x203a) +
+" per te zgjedhur muajin\n" +
+"- Mbani shtypur butonin e mousit per nje zgjedje me te shpejte.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Zgjedhja e kohes:\n" +
+"- Kliko tek ndonje nga pjeset e ores per ta rritur ate\n" +
+"- ose kliko me Shift per ta zvogeluar ate\n" +
+"- ose cliko dhe terhiq per zgjedhje me te shpejte.";
+
+Calendar._TT["PREV_YEAR"] = "Viti i shkuar (prit per menune)";
+Calendar._TT["PREV_MONTH"] = "Muaji i shkuar (prit per menune)";
+Calendar._TT["GO_TODAY"] = "Sot";
+Calendar._TT["NEXT_MONTH"] = "Muaji i ardhshem (prit per menune)";
+Calendar._TT["NEXT_YEAR"] = "Viti i ardhshem (prit per menune)";
+Calendar._TT["SEL_DATE"] = "Zgjidh daten";
+Calendar._TT["DRAG_TO_MOVE"] = "Terhiqe per te levizur";
+Calendar._TT["PART_TODAY"] = " (sot)";
+
+// "%s" eshte dita e pare e javes
+// %s do te zevendesohet me emrin e dite
+Calendar._TT["DAY_FIRST"] = "Trego te %s te paren";
+
+
+Calendar._TT["WEEKEND"] = "0,6";
+
+Calendar._TT["CLOSE"] = "Mbyll";
+Calendar._TT["TODAY"] = "Sot";
+Calendar._TT["TIME_PART"] = "Kliko me (Shift-)ose terhiqe per te ndryshuar
+vleren";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
+Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
+
+Calendar._TT["WK"] = "Java";
+Calendar._TT["TIME"] = "Koha:";
+
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-bg.js b/WebContent/themes/default/jscalendar/lang/calendar-bg.js
new file mode 100644
index 0000000000..4f4fd863e5
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-bg.js
@@ -0,0 +1,124 @@
+// ** I18N
+
+// Calendar BG language
+// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
+// Translator: Valentin Sheiretsky, <valio@valio.eu.org>
+// Encoding: Windows-1251
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible. We strongly believe that
+// Unicode is the answer to a real internationalized world. Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+Calendar._DN = new Array
+("Íåäåëÿ",
+ "Ïîíåäåëíèê",
+ "Âòîðíèê",
+ "Ñðÿäà",
+ "×åòâúðòúê",
+ "Ïåòúê",
+ "Ñúáîòà",
+ "Íåäåëÿ");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary. We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+// Calendar._SDN_len = N; // short day name length
+// Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+Calendar._SDN = new Array
+("Íåä",
+ "Ïîí",
+ "Âòî",
+ "Ñðÿ",
+ "×åò",
+ "Ïåò",
+ "Ñúá",
+ "Íåä");
+
+// full month names
+Calendar._MN = new Array
+("ßíóàðè",
+ "Ôåâðóàðè",
+ "Ìàðò",
+ "Àïðèë",
+ "Ìàé",
+ "Þíè",
+ "Þëè",
+ "Àâãóñò",
+ "Ñåïòåìâðè",
+ "Îêòîìâðè",
+ "Íîåìâðè",
+ "Äåêåìâðè");
+
+// short month names
+Calendar._SMN = new Array
+("ßíó",
+ "Ôåâ",
+ "Ìàð",
+ "Àïð",
+ "Ìàé",
+ "Þíè",
+ "Þëè",
+ "Àâã",
+ "Ñåï",
+ "Îêò",
+ "Íîå",
+ "Äåê");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "Èíôîðìàöèÿ çà êàëåíäàðà";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
+"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." +
+"\n\n" +
+"Date selection:\n" +
+"- Use the \xab, \xbb buttons to select year\n" +
+"- Use the " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " buttons to select month\n" +
+"- Hold mouse button on any of the above buttons for faster selection.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Time selection:\n" +
+"- Click on any of the time parts to increase it\n" +
+"- or Shift-click to decrease it\n" +
+"- or click and drag for faster selection.";
+
+Calendar._TT["PREV_YEAR"] = "Ïðåäíà ãîäèíà (çàäðúæòå çà ìåíþ)";
+Calendar._TT["PREV_MONTH"] = "Ïðåäåí ìåñåö (çàäðúæòå çà ìåíþ)";
+Calendar._TT["GO_TODAY"] = "Èçáåðåòå äíåñ";
+Calendar._TT["NEXT_MONTH"] = "Ñëåäâàù ìåñåö (çàäðúæòå çà ìåíþ)";
+Calendar._TT["NEXT_YEAR"] = "Ñëåäâàùà ãîäèíà (çàäðúæòå çà ìåíþ)";
+Calendar._TT["SEL_DATE"] = "Èçáåðåòå äàòà";
+Calendar._TT["DRAG_TO_MOVE"] = "Ïðåìåñòâàíå";
+Calendar._TT["PART_TODAY"] = " (äíåñ)";
+
+// the following is to inform that "%s" is to be the first day of week
+// %s will be replaced with the day name.
+Calendar._TT["DAY_FIRST"] = "%s êàòî ïúðâè äåí";
+
+// This may be locale-dependent. It specifies the week-end days, as an array
+// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1
+// means Monday, etc.
+Calendar._TT["WEEKEND"] = "0,6";
+
+Calendar._TT["CLOSE"] = "Çàòâîðåòå";
+Calendar._TT["TODAY"] = "Äíåñ";
+Calendar._TT["TIME_PART"] = "(Shift-)Click èëè drag çà äà ïðîìåíèòå ñòîéíîñòòà";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
+Calendar._TT["TT_DATE_FORMAT"] = "%A - %e %B %Y";
+
+Calendar._TT["WK"] = "Ñåäì";
+Calendar._TT["TIME"] = "×àñ:";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-big5-utf8.js b/WebContent/themes/default/jscalendar/lang/calendar-big5-utf8.js
new file mode 100644
index 0000000000..14e0d5ddee
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-big5-utf8.js
@@ -0,0 +1,123 @@
+// ** I18N
+
+// Calendar big5-utf8 language
+// Author: Gary Fu, <gary@garyfu.idv.tw>
+// Encoding: utf8
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible. We strongly believe that
+// Unicode is the answer to a real internationalized world. Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+Calendar._DN = new Array
+("星期日",
+ "星期一",
+ "星期二",
+ "星期三",
+ "星期四",
+ "星期五",
+ "星期六",
+ "星期日");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary. We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+// Calendar._SDN_len = N; // short day name length
+// Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+Calendar._SDN = new Array
+("æ—¥",
+ "一",
+ "二",
+ "三",
+ "å››",
+ "五",
+ "å…­",
+ "æ—¥");
+
+// full month names
+Calendar._MN = new Array
+("一月",
+ "二月",
+ "三月",
+ "四月",
+ "五月",
+ "六月",
+ "七月",
+ "八月",
+ "ä¹æœˆ",
+ "å月",
+ "å一月",
+ "å二月");
+
+// short month names
+Calendar._SMN = new Array
+("一月",
+ "二月",
+ "三月",
+ "四月",
+ "五月",
+ "六月",
+ "七月",
+ "八月",
+ "ä¹æœˆ",
+ "å月",
+ "å一月",
+ "å二月");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "關於";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
+"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." +
+"\n\n" +
+"日期é¸æ“‡æ–¹æ³•:\n" +
+"- 使用 \xab, \xbb 按鈕å¯é¸æ“‡å¹´ä»½\n" +
+"- 使用 " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " 按鈕å¯é¸æ“‡æœˆä»½\n" +
+"- 按ä½ä¸Šé¢çš„按鈕å¯ä»¥åŠ å¿«é¸å–";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"時間é¸æ“‡æ–¹æ³•:\n" +
+"- 點擊任何的時間部份å¯å¢žåŠ å…¶å€¼\n" +
+"- åŒæ™‚按Shiftéµå†é»žæ“Šå¯æ¸›å°‘其值\n" +
+"- 點擊並拖曳å¯åŠ å¿«æ”¹è®Šçš„值";
+
+Calendar._TT["PREV_YEAR"] = "上一年 (按ä½é¸å–®)";
+Calendar._TT["PREV_MONTH"] = "下一年 (按ä½é¸å–®)";
+Calendar._TT["GO_TODAY"] = "到今日";
+Calendar._TT["NEXT_MONTH"] = "上一月 (按ä½é¸å–®)";
+Calendar._TT["NEXT_YEAR"] = "下一月 (按ä½é¸å–®)";
+Calendar._TT["SEL_DATE"] = "é¸æ“‡æ—¥æœŸ";
+Calendar._TT["DRAG_TO_MOVE"] = "拖曳";
+Calendar._TT["PART_TODAY"] = " (今日)";
+
+// the following is to inform that "%s" is to be the first day of week
+// %s will be replaced with the day name.
+Calendar._TT["DAY_FIRST"] = "å°‡ %s 顯示在å‰";
+
+// This may be locale-dependent. It specifies the week-end days, as an array
+// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1
+// means Monday, etc.
+Calendar._TT["WEEKEND"] = "0,6";
+
+Calendar._TT["CLOSE"] = "關閉";
+Calendar._TT["TODAY"] = "今日";
+Calendar._TT["TIME_PART"] = "點擊or拖曳å¯æ”¹è®Šæ™‚é–“(åŒæ™‚按Shift為減)";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
+Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
+
+Calendar._TT["WK"] = "週";
+Calendar._TT["TIME"] = "Time:";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-big5.js b/WebContent/themes/default/jscalendar/lang/calendar-big5.js
new file mode 100644
index 0000000000..a58935873f
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-big5.js
@@ -0,0 +1,123 @@
+// ** I18N
+
+// Calendar big5 language
+// Author: Gary Fu, <gary@garyfu.idv.tw>
+// Encoding: big5
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible. We strongly believe that
+// Unicode is the answer to a real internationalized world. Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+Calendar._DN = new Array
+("¬P´Á¤é",
+ "¬P´Á¤@",
+ "¬P´Á¤G",
+ "¬P´Á¤T",
+ "¬P´Á¥|",
+ "¬P´Á¤­",
+ "¬P´Á¤»",
+ "¬P´Á¤é");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary. We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+// Calendar._SDN_len = N; // short day name length
+// Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+Calendar._SDN = new Array
+("¤é",
+ "¤@",
+ "¤G",
+ "¤T",
+ "¥|",
+ "¤­",
+ "¤»",
+ "¤é");
+
+// full month names
+Calendar._MN = new Array
+("¤@¤ë",
+ "¤G¤ë",
+ "¤T¤ë",
+ "¥|¤ë",
+ "¤­¤ë",
+ "¤»¤ë",
+ "¤C¤ë",
+ "¤K¤ë",
+ "¤E¤ë",
+ "¤Q¤ë",
+ "¤Q¤@¤ë",
+ "¤Q¤G¤ë");
+
+// short month names
+Calendar._SMN = new Array
+("¤@¤ë",
+ "¤G¤ë",
+ "¤T¤ë",
+ "¥|¤ë",
+ "¤­¤ë",
+ "¤»¤ë",
+ "¤C¤ë",
+ "¤K¤ë",
+ "¤E¤ë",
+ "¤Q¤ë",
+ "¤Q¤@¤ë",
+ "¤Q¤G¤ë");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "Ãö©ó";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
+"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." +
+"\n\n" +
+"¤é´Á¿ï¾Ü¤èªk:\n" +
+"- ¨Ï¥Î \xab, \xbb «ö¶s¥i¿ï¾Ü¦~¥÷\n" +
+"- ¨Ï¥Î " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " «ö¶s¥i¿ï¾Ü¤ë¥÷\n" +
+"- «ö¦í¤W­±ªº«ö¶s¥i¥H¥[§Ö¿ï¨ú";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"®É¶¡¿ï¾Ü¤èªk:\n" +
+"- ÂIÀ»¥ô¦óªº®É¶¡³¡¥÷¥i¼W¥[¨ä­È\n" +
+"- ¦P®É«öShiftÁä¦AÂIÀ»¥i´î¤Ö¨ä­È\n" +
+"- ÂIÀ»¨Ã©ì¦²¥i¥[§Ö§ïÅܪº­È";
+
+Calendar._TT["PREV_YEAR"] = "¤W¤@¦~ («ö¦í¿ï³æ)";
+Calendar._TT["PREV_MONTH"] = "¤U¤@¦~ («ö¦í¿ï³æ)";
+Calendar._TT["GO_TODAY"] = "¨ì¤µ¤é";
+Calendar._TT["NEXT_MONTH"] = "¤W¤@¤ë («ö¦í¿ï³æ)";
+Calendar._TT["NEXT_YEAR"] = "¤U¤@¤ë («ö¦í¿ï³æ)";
+Calendar._TT["SEL_DATE"] = "¿ï¾Ü¤é´Á";
+Calendar._TT["DRAG_TO_MOVE"] = "©ì¦²";
+Calendar._TT["PART_TODAY"] = " (¤µ¤é)";
+
+// the following is to inform that "%s" is to be the first day of week
+// %s will be replaced with the day name.
+Calendar._TT["DAY_FIRST"] = "±N %s Åã¥Ü¦b«e";
+
+// This may be locale-dependent. It specifies the week-end days, as an array
+// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1
+// means Monday, etc.
+Calendar._TT["WEEKEND"] = "0,6";
+
+Calendar._TT["CLOSE"] = "Ãö³¬";
+Calendar._TT["TODAY"] = "¤µ¤é";
+Calendar._TT["TIME_PART"] = "ÂIÀ»or©ì¦²¥i§ïÅܮɶ¡(¦P®É«öShift¬°´î)";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
+Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
+
+Calendar._TT["WK"] = "¶g";
+Calendar._TT["TIME"] = "Time:";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-br.js b/WebContent/themes/default/jscalendar/lang/calendar-br.js
new file mode 100644
index 0000000000..bfb074717c
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-br.js
@@ -0,0 +1,108 @@
+// ** I18N
+
+// Calendar pt-BR language
+// Author: Fernando Dourado, <fernando.dourado@ig.com.br>
+// Encoding: any
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible. We strongly believe that
+// Unicode is the answer to a real internationalized world. Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+Calendar._DN = new Array
+("Domingo",
+ "Segunda",
+ "Terça",
+ "Quarta",
+ "Quinta",
+ "Sexta",
+ "Sabádo",
+ "Domingo");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary. We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+// Calendar._SDN_len = N; // short day name length
+// Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+// [No changes using default values]
+
+// full month names
+Calendar._MN = new Array
+("Janeiro",
+ "Fevereiro",
+ "Março",
+ "Abril",
+ "Maio",
+ "Junho",
+ "Julho",
+ "Agosto",
+ "Setembro",
+ "Outubro",
+ "Novembro",
+ "Dezembro");
+
+// short month names
+// [No changes using default values]
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "Sobre o calendário";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
+"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." +
+"\n\n" +
+"Translate to portuguese Brazil (pt-BR) by Fernando Dourado (fernando.dourado@ig.com.br)\n" +
+"Tradução para o português Brasil (pt-BR) por Fernando Dourado (fernando.dourado@ig.com.br)" +
+"\n\n" +
+"Selecionar data:\n" +
+"- Use as teclas \xab, \xbb para selecionar o ano\n" +
+"- Use as teclas " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " para selecionar o mês\n" +
+"- Clique e segure com o mouse em qualquer botão para selecionar rapidamente.";
+
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Selecionar hora:\n" +
+"- Clique em qualquer uma das partes da hora para aumentar\n" +
+"- ou Shift-clique para diminuir\n" +
+"- ou clique e arraste para selecionar rapidamente.";
+
+Calendar._TT["PREV_YEAR"] = "Ano anterior (clique e segure para menu)";
+Calendar._TT["PREV_MONTH"] = "Mês anterior (clique e segure para menu)";
+Calendar._TT["GO_TODAY"] = "Ir para a data atual";
+Calendar._TT["NEXT_MONTH"] = "Próximo mês (clique e segure para menu)";
+Calendar._TT["NEXT_YEAR"] = "Próximo ano (clique e segure para menu)";
+Calendar._TT["SEL_DATE"] = "Selecione uma data";
+Calendar._TT["DRAG_TO_MOVE"] = "Clique e segure para mover";
+Calendar._TT["PART_TODAY"] = " (hoje)";
+
+// the following is to inform that "%s" is to be the first day of week
+// %s will be replaced with the day name.
+Calendar._TT["DAY_FIRST"] = "Exibir %s primeiro";
+
+// This may be locale-dependent. It specifies the week-end days, as an array
+// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1
+// means Monday, etc.
+Calendar._TT["WEEKEND"] = "0,6";
+
+Calendar._TT["CLOSE"] = "Fechar";
+Calendar._TT["TODAY"] = "Hoje";
+Calendar._TT["TIME_PART"] = "(Shift-)Clique ou arraste para mudar o valor";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%d/%m/%Y";
+Calendar._TT["TT_DATE_FORMAT"] = "%d de %B de %Y";
+
+Calendar._TT["WK"] = "sem";
+Calendar._TT["TIME"] = "Hora:";
+
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-ca.js b/WebContent/themes/default/jscalendar/lang/calendar-ca.js
new file mode 100644
index 0000000000..a2121bcb40
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-ca.js
@@ -0,0 +1,123 @@
+// ** I18N
+
+// Calendar CA language
+// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
+// Encoding: any
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible. We strongly believe that
+// Unicode is the answer to a real internationalized world. Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+Calendar._DN = new Array
+("Diumenge",
+ "Dilluns",
+ "Dimarts",
+ "Dimecres",
+ "Dijous",
+ "Divendres",
+ "Dissabte",
+ "Diumenge");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary. We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+// Calendar._SDN_len = N; // short day name length
+// Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+Calendar._SDN = new Array
+("Diu",
+ "Dil",
+ "Dmt",
+ "Dmc",
+ "Dij",
+ "Div",
+ "Dis",
+ "Diu");
+
+// full month names
+Calendar._MN = new Array
+("Gener",
+ "Febrer",
+ "Març",
+ "Abril",
+ "Maig",
+ "Juny",
+ "Juliol",
+ "Agost",
+ "Setembre",
+ "Octubre",
+ "Novembre",
+ "Desembre");
+
+// short month names
+Calendar._SMN = new Array
+("Gen",
+ "Feb",
+ "Mar",
+ "Abr",
+ "Mai",
+ "Jun",
+ "Jul",
+ "Ago",
+ "Set",
+ "Oct",
+ "Nov",
+ "Des");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "Sobre el calendari";
+
+Calendar._TT["ABOUT"] =
+"DHTML Selector de Data/Hora\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
+"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." +
+"\n\n" +
+"Sel.lecció de Dates:\n" +
+"- Fes servir els botons \xab, \xbb per sel.leccionar l'any\n" +
+"- Fes servir els botons " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " per se.lecciconar el mes\n" +
+"- Manté el ratolí apretat en qualsevol dels anteriors per sel.lecció ràpida.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Time selection:\n" +
+"- claca en qualsevol de les parts de la hora per augmentar-les\n" +
+"- o Shift-click per decrementar-la\n" +
+"- or click and arrastra per sel.lecció ràpida.";
+
+Calendar._TT["PREV_YEAR"] = "Any anterior (Mantenir per menu)";
+Calendar._TT["PREV_MONTH"] = "Mes anterior (Mantenir per menu)";
+Calendar._TT["GO_TODAY"] = "Anar a avui";
+Calendar._TT["NEXT_MONTH"] = "Mes següent (Mantenir per menu)";
+Calendar._TT["NEXT_YEAR"] = "Any següent (Mantenir per menu)";
+Calendar._TT["SEL_DATE"] = "Sel.leccionar data";
+Calendar._TT["DRAG_TO_MOVE"] = "Arrastrar per moure";
+Calendar._TT["PART_TODAY"] = " (avui)";
+
+// the following is to inform that "%s" is to be the first day of week
+// %s will be replaced with the day name.
+Calendar._TT["DAY_FIRST"] = "Mostra %s primer";
+
+// This may be locale-dependent. It specifies the week-end days, as an array
+// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1
+// means Monday, etc.
+Calendar._TT["WEEKEND"] = "0,6";
+
+Calendar._TT["CLOSE"] = "Tanca";
+Calendar._TT["TODAY"] = "Avui";
+Calendar._TT["TIME_PART"] = "(Shift-)Click a arrastra per canviar el valor";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
+Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
+
+Calendar._TT["WK"] = "st";
+Calendar._TT["TIME"] = "Hora:";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-cs-utf8.js b/WebContent/themes/default/jscalendar/lang/calendar-cs-utf8.js
new file mode 100644
index 0000000000..f6bbbeba14
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-cs-utf8.js
@@ -0,0 +1,65 @@
+/*
+ calendar-cs-win.js
+ language: Czech
+ encoding: windows-1250
+ author: Lubos Jerabek (xnet@seznam.cz)
+ Jan Uhlir (espinosa@centrum.cz)
+*/
+
+// ** I18N
+Calendar._DN = new Array('Neděle','Pondělí','Úterý','Středa','Čtvrtek','Pátek','Sobota','Neděle');
+Calendar._SDN = new Array('Ne','Po','Út','St','Čt','Pá','So','Ne');
+Calendar._MN = new Array('Leden','Únor','Březen','Duben','Květen','Červen','Červenec','Srpen','Září','Říjen','Listopad','Prosinec');
+Calendar._SMN = new Array('Led','Úno','Bře','Dub','Kvě','Črv','Čvc','Srp','Zář','Říj','Lis','Pro');
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "O komponentě kalendář";
+Calendar._TT["TOGGLE"] = "Změna prvního dne v týdnu";
+Calendar._TT["PREV_YEAR"] = "Předchozí rok (přidrž pro menu)";
+Calendar._TT["PREV_MONTH"] = "Předchozí měsíc (přidrž pro menu)";
+Calendar._TT["GO_TODAY"] = "Dnešní datum";
+Calendar._TT["NEXT_MONTH"] = "Další měsíc (přidrž pro menu)";
+Calendar._TT["NEXT_YEAR"] = "Další rok (přidrž pro menu)";
+Calendar._TT["SEL_DATE"] = "Vyber datum";
+Calendar._TT["DRAG_TO_MOVE"] = "Chyť a táhni, pro přesun";
+Calendar._TT["PART_TODAY"] = " (dnes)";
+Calendar._TT["MON_FIRST"] = "Ukaž jako první Pondělí";
+//Calendar._TT["SUN_FIRST"] = "Ukaž jako první Neděli";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
+"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." +
+"\n\n" +
+"Výběr datumu:\n" +
+"- Use the \xab, \xbb buttons to select year\n" +
+"- Použijte tlaÄítka " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " k výbÄ›ru mÄ›síce\n" +
+"- Podržte tlaÄítko myÅ¡i na jakémkoliv z tÄ›ch tlaÄítek pro rychlejší výbÄ›r.";
+
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"VýbÄ›r Äasu:\n" +
+"- KliknÄ›te na jakoukoliv z Äástí výbÄ›ru Äasu pro zvýšení.\n" +
+"- nebo Shift-click pro snížení\n" +
+"- nebo klikněte a táhněte pro rychlejší výběr.";
+
+// the following is to inform that "%s" is to be the first day of week
+// %s will be replaced with the day name.
+Calendar._TT["DAY_FIRST"] = "Zobraz %s první";
+
+// This may be locale-dependent. It specifies the week-end days, as an array
+// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1
+// means Monday, etc.
+Calendar._TT["WEEKEND"] = "0,6";
+
+Calendar._TT["CLOSE"] = "Zavřít";
+Calendar._TT["TODAY"] = "Dnes";
+Calendar._TT["TIME_PART"] = "(Shift-)Klikni nebo táhni pro změnu hodnoty";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "d.m.yy";
+Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
+
+Calendar._TT["WK"] = "wk";
+Calendar._TT["TIME"] = "ÄŒas:";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-cs-win.js b/WebContent/themes/default/jscalendar/lang/calendar-cs-win.js
new file mode 100644
index 0000000000..140dff318c
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-cs-win.js
@@ -0,0 +1,65 @@
+/*
+ calendar-cs-win.js
+ language: Czech
+ encoding: windows-1250
+ author: Lubos Jerabek (xnet@seznam.cz)
+ Jan Uhlir (espinosa@centrum.cz)
+*/
+
+// ** I18N
+Calendar._DN = new Array('Nedìle','Pondìlí','Úterý','Støeda','Ètvrtek','Pátek','Sobota','Nedìle');
+Calendar._SDN = new Array('Ne','Po','Út','St','Èt','Pá','So','Ne');
+Calendar._MN = new Array('Leden','Únor','Bøezen','Duben','Kvìten','Èerven','Èervenec','Srpen','Záøí','Øíjen','Listopad','Prosinec');
+Calendar._SMN = new Array('Led','Úno','Bøe','Dub','Kvì','Èrv','Èvc','Srp','Záø','Øíj','Lis','Pro');
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "O komponentì kalendáø";
+Calendar._TT["TOGGLE"] = "Zmìna prvního dne v týdnu";
+Calendar._TT["PREV_YEAR"] = "Pøedchozí rok (pøidrž pro menu)";
+Calendar._TT["PREV_MONTH"] = "Pøedchozí mìsíc (pøidrž pro menu)";
+Calendar._TT["GO_TODAY"] = "Dnešní datum";
+Calendar._TT["NEXT_MONTH"] = "Další mìsíc (pøidrž pro menu)";
+Calendar._TT["NEXT_YEAR"] = "Další rok (pøidrž pro menu)";
+Calendar._TT["SEL_DATE"] = "Vyber datum";
+Calendar._TT["DRAG_TO_MOVE"] = "Chy a táhni, pro pøesun";
+Calendar._TT["PART_TODAY"] = " (dnes)";
+Calendar._TT["MON_FIRST"] = "Ukaž jako první Pondìlí";
+//Calendar._TT["SUN_FIRST"] = "Ukaž jako první Nedìli";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
+"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." +
+"\n\n" +
+"Výbìr datumu:\n" +
+"- Use the \xab, \xbb buttons to select year\n" +
+"- Použijte tlaèítka " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " k výbìru mìsíce\n" +
+"- Podržte tlaèítko myši na jakémkoliv z tìch tlaèítek pro rychlejší výbìr.";
+
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Výbìr èasu:\n" +
+"- Kliknìte na jakoukoliv z èástí výbìru èasu pro zvýšení.\n" +
+"- nebo Shift-click pro snížení\n" +
+"- nebo kliknìte a táhnìte pro rychlejší výbìr.";
+
+// the following is to inform that "%s" is to be the first day of week
+// %s will be replaced with the day name.
+Calendar._TT["DAY_FIRST"] = "Zobraz %s první";
+
+// This may be locale-dependent. It specifies the week-end days, as an array
+// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1
+// means Monday, etc.
+Calendar._TT["WEEKEND"] = "0,6";
+
+Calendar._TT["CLOSE"] = "Zavøít";
+Calendar._TT["TODAY"] = "Dnes";
+Calendar._TT["TIME_PART"] = "(Shift-)Klikni nebo táhni pro zmìnu hodnoty";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "d.m.yy";
+Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
+
+Calendar._TT["WK"] = "wk";
+Calendar._TT["TIME"] = "Èas:";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-da.js b/WebContent/themes/default/jscalendar/lang/calendar-da.js
new file mode 100644
index 0000000000..a99b598f03
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-da.js
@@ -0,0 +1,123 @@
+// ** I18N
+
+// Calendar DA language
+// Author: Michael Thingmand Henriksen, <michael (a) thingmand dot dk>
+// Encoding: any
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible. We strongly believe that
+// Unicode is the answer to a real internationalized world. Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+Calendar._DN = new Array
+("Søndag",
+"Mandag",
+"Tirsdag",
+"Onsdag",
+"Torsdag",
+"Fredag",
+"Lørdag",
+"Søndag");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary. We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+// Calendar._SDN_len = N; // short day name length
+// Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+Calendar._SDN = new Array
+("Søn",
+"Man",
+"Tir",
+"Ons",
+"Tor",
+"Fre",
+"Lør",
+"Søn");
+
+// full month names
+Calendar._MN = new Array
+("Januar",
+"Februar",
+"Marts",
+"April",
+"Maj",
+"Juni",
+"Juli",
+"August",
+"September",
+"Oktober",
+"November",
+"December");
+
+// short month names
+Calendar._SMN = new Array
+("Jan",
+"Feb",
+"Mar",
+"Apr",
+"Maj",
+"Jun",
+"Jul",
+"Aug",
+"Sep",
+"Okt",
+"Nov",
+"Dec");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "Om Kalenderen";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"For den seneste version besøg: http://www.dynarch.com/projects/calendar/\n"; +
+"Distribueret under GNU LGPL. Se http://gnu.org/licenses/lgpl.html for detajler." +
+"\n\n" +
+"Valg af dato:\n" +
+"- Brug \xab, \xbb knapperne for at vælge år\n" +
+"- Brug " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " knapperne for at vælge måned\n" +
+"- Hold knappen på musen nede på knapperne ovenfor for hurtigere valg.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Valg af tid:\n" +
+"- Klik på en vilkårlig del for større værdi\n" +
+"- eller Shift-klik for for mindre værdi\n" +
+"- eller klik og træk for hurtigere valg.";
+
+Calendar._TT["PREV_YEAR"] = "Ét år tilbage (hold for menu)";
+Calendar._TT["PREV_MONTH"] = "Én måned tilbage (hold for menu)";
+Calendar._TT["GO_TODAY"] = "GÃ¥ til i dag";
+Calendar._TT["NEXT_MONTH"] = "Én måned frem (hold for menu)";
+Calendar._TT["NEXT_YEAR"] = "Ét år frem (hold for menu)";
+Calendar._TT["SEL_DATE"] = "Vælg dag";
+Calendar._TT["DRAG_TO_MOVE"] = "Træk vinduet";
+Calendar._TT["PART_TODAY"] = " (i dag)";
+
+// the following is to inform that "%s" is to be the first day of week
+// %s will be replaced with the day name.
+Calendar._TT["DAY_FIRST"] = "Vis %s først";
+
+// This may be locale-dependent. It specifies the week-end days, as an array
+// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1
+// means Monday, etc.
+Calendar._TT["WEEKEND"] = "0,6";
+
+Calendar._TT["CLOSE"] = "Luk";
+Calendar._TT["TODAY"] = "I dag";
+Calendar._TT["TIME_PART"] = "(Shift-)klik eller træk for at ændre værdi";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%d-%m-%Y";
+Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
+
+Calendar._TT["WK"] = "Uge";
+Calendar._TT["TIME"] = "Tid:";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-de.js b/WebContent/themes/default/jscalendar/lang/calendar-de.js
new file mode 100644
index 0000000000..4bc1137cc1
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-de.js
@@ -0,0 +1,124 @@
+// ** I18N
+
+// Calendar DE language
+// Author: Jack (tR), <jack@jtr.de>
+// Encoding: any
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible. We strongly believe that
+// Unicode is the answer to a real internationalized world. Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+Calendar._DN = new Array
+("Sonntag",
+ "Montag",
+ "Dienstag",
+ "Mittwoch",
+ "Donnerstag",
+ "Freitag",
+ "Samstag",
+ "Sonntag");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary. We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+// Calendar._SDN_len = N; // short day name length
+// Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+Calendar._SDN = new Array
+("So",
+ "Mo",
+ "Di",
+ "Mi",
+ "Do",
+ "Fr",
+ "Sa",
+ "So");
+
+// full month names
+Calendar._MN = new Array
+("Januar",
+ "Februar",
+ "M\u00e4rz",
+ "April",
+ "Mai",
+ "Juni",
+ "Juli",
+ "August",
+ "September",
+ "Oktober",
+ "November",
+ "Dezember");
+
+// short month names
+Calendar._SMN = new Array
+("Jan",
+ "Feb",
+ "M\u00e4r",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Dez");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "\u00DCber dieses Kalendarmodul";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this ;-)
+"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
+"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." +
+"\n\n" +
+"Datum ausw\u00e4hlen:\n" +
+"- Benutzen Sie die \xab, \xbb Buttons um das Jahr zu w\u00e4hlen\n" +
+"- Benutzen Sie die " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " Buttons um den Monat zu w\u00e4hlen\n" +
+"- F\u00fcr eine Schnellauswahl halten Sie die Maustaste \u00fcber diesen Buttons fest.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Zeit ausw\u00e4hlen:\n" +
+"- Klicken Sie auf die Teile der Uhrzeit, um diese zu erh\u00F6hen\n" +
+"- oder klicken Sie mit festgehaltener Shift-Taste um diese zu verringern\n" +
+"- oder klicken und festhalten f\u00fcr Schnellauswahl.";
+
+Calendar._TT["TOGGLE"] = "Ersten Tag der Woche w\u00e4hlen";
+Calendar._TT["PREV_YEAR"] = "Voriges Jahr (Festhalten f\u00fcr Schnellauswahl)";
+Calendar._TT["PREV_MONTH"] = "Voriger Monat (Festhalten f\u00fcr Schnellauswahl)";
+Calendar._TT["GO_TODAY"] = "Heute ausw\u00e4hlen";
+Calendar._TT["NEXT_MONTH"] = "N\u00e4chst. Monat (Festhalten f\u00fcr Schnellauswahl)";
+Calendar._TT["NEXT_YEAR"] = "N\u00e4chst. Jahr (Festhalten f\u00fcr Schnellauswahl)";
+Calendar._TT["SEL_DATE"] = "Datum ausw\u00e4hlen";
+Calendar._TT["DRAG_TO_MOVE"] = "Zum Bewegen festhalten";
+Calendar._TT["PART_TODAY"] = " (Heute)";
+
+// the following is to inform that "%s" is to be the first day of week
+// %s will be replaced with the day name.
+Calendar._TT["DAY_FIRST"] = "Woche beginnt mit %s ";
+
+// This may be locale-dependent. It specifies the week-end days, as an array
+// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1
+// means Monday, etc.
+Calendar._TT["WEEKEND"] = "0,6";
+
+Calendar._TT["CLOSE"] = "Schlie\u00dfen";
+Calendar._TT["TODAY"] = "Heute";
+Calendar._TT["TIME_PART"] = "(Shift-)Klick oder Festhalten und Ziehen um den Wert zu \u00e4ndern";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%d.%m.%Y";
+Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
+
+Calendar._TT["WK"] = "wk";
+Calendar._TT["TIME"] = "Zeit:";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-du.js b/WebContent/themes/default/jscalendar/lang/calendar-du.js
new file mode 100644
index 0000000000..2200448051
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-du.js
@@ -0,0 +1,45 @@
+// ** I18N
+Calendar._DN = new Array
+("Zondag",
+ "Maandag",
+ "Dinsdag",
+ "Woensdag",
+ "Donderdag",
+ "Vrijdag",
+ "Zaterdag",
+ "Zondag");
+Calendar._MN = new Array
+("Januari",
+ "Februari",
+ "Maart",
+ "April",
+ "Mei",
+ "Juni",
+ "Juli",
+ "Augustus",
+ "September",
+ "Oktober",
+ "November",
+ "December");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["TOGGLE"] = "Toggle startdag van de week";
+Calendar._TT["PREV_YEAR"] = "Vorig jaar (indrukken voor menu)";
+Calendar._TT["PREV_MONTH"] = "Vorige month (indrukken voor menu)";
+Calendar._TT["GO_TODAY"] = "Naar Vandaag";
+Calendar._TT["NEXT_MONTH"] = "Volgende Maand (indrukken voor menu)";
+Calendar._TT["NEXT_YEAR"] = "Volgend jaar (indrukken voor menu)";
+Calendar._TT["SEL_DATE"] = "Selecteer datum";
+Calendar._TT["DRAG_TO_MOVE"] = "Sleep om te verplaatsen";
+Calendar._TT["PART_TODAY"] = " (vandaag)";
+Calendar._TT["MON_FIRST"] = "Toon Maandag eerst";
+Calendar._TT["SUN_FIRST"] = "Toon Zondag eerst";
+Calendar._TT["CLOSE"] = "Sluiten";
+Calendar._TT["TODAY"] = "Vandaag";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "y-mm-dd";
+Calendar._TT["TT_DATE_FORMAT"] = "D, M d";
+
+Calendar._TT["WK"] = "wk";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-el.js b/WebContent/themes/default/jscalendar/lang/calendar-el.js
new file mode 100644
index 0000000000..fee5575eab
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-el.js
@@ -0,0 +1,89 @@
+// ** I18N
+Calendar._DN = new Array
+("ΚυÏιακή",
+ "ΔευτέÏα",
+ "ΤÏίτη",
+ "ΤετάÏτη",
+ "Πέμπτη",
+ "ΠαÏασκευή",
+ "Σάββατο",
+ "ΚυÏιακή");
+
+Calendar._SDN = new Array
+("Κυ",
+ "Δε",
+ "TÏ",
+ "Τε",
+ "Πε",
+ "Πα",
+ "Σα",
+ "Κυ");
+
+Calendar._MN = new Array
+("ΙανουάÏιος",
+ "ΦεβÏουάÏιος",
+ "ΜάÏτιος",
+ "ΑπÏίλιος",
+ "Μάϊος",
+ "ΙοÏνιος",
+ "ΙοÏλιος",
+ "ΑÏγουστος",
+ "ΣεπτέμβÏιος",
+ "ΟκτώβÏιος",
+ "ÎοέμβÏιος",
+ "ΔεκέμβÏιος");
+
+Calendar._SMN = new Array
+("Ιαν",
+ "Φεβ",
+ "ΜαÏ",
+ "ΑπÏ",
+ "Μαι",
+ "Ιουν",
+ "Ιουλ",
+ "Αυγ",
+ "Σεπ",
+ "Οκτ",
+ "Îοε",
+ "Δεκ");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "Για το ημεÏολόγιο";
+
+Calendar._TT["ABOUT"] =
+"Επιλογέας ημεÏομηνίας/ÏŽÏας σε DHTML\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"Για τελευταία έκδοση: http://www.dynarch.com/projects/calendar/\n" +
+"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." +
+"\n\n" +
+"Επιλογή ημεÏομηνίας:\n" +
+"- ΧÏησιμοποιείστε τα κουμπιά \xab, \xbb για επιλογή έτους\n" +
+"- ΧÏησιμοποιείστε τα κουμπιά " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " για επιλογή μήνα\n" +
+"- ΚÏατήστε κουμπί Ï€Î¿Î½Ï„Î¹ÎºÎ¿Ï Ï€Î±Ï„Î·Î¼Î­Î½Î¿ στα παÏαπάνω κουμπιά για πιο γÏήγοÏη επιλογή.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Επιλογή ÏŽÏας:\n" +
+"- Κάντε κλικ σε ένα από τα μέÏη της ÏŽÏας για αÏξηση\n" +
+"- ή Shift-κλικ για μείωση\n" +
+"- ή κλικ και μετακίνηση για πιο γÏήγοÏη επιλογή.";
+Calendar._TT["TOGGLE"] = "ΜπάÏα Ï€Ïώτης ημέÏας της εβδομάδας";
+Calendar._TT["PREV_YEAR"] = "ΠÏοηγ. έτος (κÏατήστε για το μενοÏ)";
+Calendar._TT["PREV_MONTH"] = "ΠÏοηγ. μήνας (κÏατήστε για το μενοÏ)";
+Calendar._TT["GO_TODAY"] = "ΣήμεÏα";
+Calendar._TT["NEXT_MONTH"] = "Επόμενος μήνας (κÏατήστε για το μενοÏ)";
+Calendar._TT["NEXT_YEAR"] = "Επόμενο έτος (κÏατήστε για το μενοÏ)";
+Calendar._TT["SEL_DATE"] = "Επιλέξτε ημεÏομηνία";
+Calendar._TT["DRAG_TO_MOVE"] = "ΣÏÏτε για να μετακινήσετε";
+Calendar._TT["PART_TODAY"] = " (σήμεÏα)";
+Calendar._TT["MON_FIRST"] = "Εμφάνιση ΔευτέÏας Ï€Ïώτα";
+Calendar._TT["SUN_FIRST"] = "Εμφάνιση ΚυÏιακής Ï€Ïώτα";
+Calendar._TT["CLOSE"] = "Κλείσιμο";
+Calendar._TT["TODAY"] = "ΣήμεÏα";
+Calendar._TT["TIME_PART"] = "(Shift-)κλικ ή μετακίνηση για αλλαγή";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "dd-mm-y";
+Calendar._TT["TT_DATE_FORMAT"] = "D, d M";
+
+Calendar._TT["WK"] = "εβδ";
+
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-en.js b/WebContent/themes/default/jscalendar/lang/calendar-en.js
new file mode 100644
index 0000000000..0dbde793d8
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-en.js
@@ -0,0 +1,127 @@
+// ** I18N
+
+// Calendar EN language
+// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
+// Encoding: any
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible. We strongly believe that
+// Unicode is the answer to a real internationalized world. Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+Calendar._DN = new Array
+("Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday",
+ "Sunday");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary. We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+// Calendar._SDN_len = N; // short day name length
+// Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+Calendar._SDN = new Array
+("Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat",
+ "Sun");
+
+// First day of the week. "0" means display Sunday first, "1" means display
+// Monday first, etc.
+Calendar._FD = 0;
+
+// full month names
+Calendar._MN = new Array
+("January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December");
+
+// short month names
+Calendar._SMN = new Array
+("Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "About the calendar";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
+"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." +
+"\n\n" +
+"Date selection:\n" +
+"- Use the \xab, \xbb buttons to select year\n" +
+"- Use the " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " buttons to select month\n" +
+"- Hold mouse button on any of the above buttons for faster selection.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Time selection:\n" +
+"- Click on any of the time parts to increase it\n" +
+"- or Shift-click to decrease it\n" +
+"- or click and drag for faster selection.";
+
+Calendar._TT["PREV_YEAR"] = "Prev. year (hold for menu)";
+Calendar._TT["PREV_MONTH"] = "Prev. month (hold for menu)";
+Calendar._TT["GO_TODAY"] = "Go Today";
+Calendar._TT["NEXT_MONTH"] = "Next month (hold for menu)";
+Calendar._TT["NEXT_YEAR"] = "Next year (hold for menu)";
+Calendar._TT["SEL_DATE"] = "Select date";
+Calendar._TT["DRAG_TO_MOVE"] = "Drag to move";
+Calendar._TT["PART_TODAY"] = " (today)";
+
+// the following is to inform that "%s" is to be the first day of week
+// %s will be replaced with the day name.
+Calendar._TT["DAY_FIRST"] = "Display %s first";
+
+// This may be locale-dependent. It specifies the week-end days, as an array
+// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1
+// means Monday, etc.
+Calendar._TT["WEEKEND"] = "0,6";
+
+Calendar._TT["CLOSE"] = "Close";
+Calendar._TT["TODAY"] = "Today";
+Calendar._TT["TIME_PART"] = "(Shift-)Click or drag to change value";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
+Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
+
+Calendar._TT["WK"] = "wk";
+Calendar._TT["TIME"] = "Time:";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-es.js b/WebContent/themes/default/jscalendar/lang/calendar-es.js
new file mode 100644
index 0000000000..19c1b30bdc
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-es.js
@@ -0,0 +1,129 @@
+// ** I18N
+
+// Calendar ES (spanish) language
+// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
+// Updater: Servilio Afre Puentes <servilios@yahoo.com>
+// Updated: 2004-06-03
+// Encoding: utf-8
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible. We strongly believe that
+// Unicode is the answer to a real internationalized world. Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+Calendar._DN = new Array
+("Domingo",
+ "Lunes",
+ "Martes",
+ "Miércoles",
+ "Jueves",
+ "Viernes",
+ "Sábado",
+ "Domingo");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary. We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+// Calendar._SDN_len = N; // short day name length
+// Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+Calendar._SDN = new Array
+("Dom",
+ "Lun",
+ "Mar",
+ "Mié",
+ "Jue",
+ "Vie",
+ "Sáb",
+ "Dom");
+
+// First day of the week. "0" means display Sunday first, "1" means display
+// Monday first, etc.
+Calendar._FD = 1;
+
+// full month names
+Calendar._MN = new Array
+("Enero",
+ "Febrero",
+ "Marzo",
+ "Abril",
+ "Mayo",
+ "Junio",
+ "Julio",
+ "Agosto",
+ "Septiembre",
+ "Octubre",
+ "Noviembre",
+ "Diciembre");
+
+// short month names
+Calendar._SMN = new Array
+("Ene",
+ "Feb",
+ "Mar",
+ "Abr",
+ "May",
+ "Jun",
+ "Jul",
+ "Ago",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dic");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "Acerca del calendario";
+
+Calendar._TT["ABOUT"] =
+"Selector DHTML de Fecha/Hora\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"Para conseguir la última versión visite: http://www.dynarch.com/projects/calendar/\n" +
+"Distribuido bajo licencia GNU LGPL. Visite http://gnu.org/licenses/lgpl.html para más detalles." +
+"\n\n" +
+"Selección de fecha:\n" +
+"- Use los botones \xab, \xbb para seleccionar el año\n" +
+"- Use los botones " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " para seleccionar el mes\n" +
+"- Mantenga pulsado el ratón en cualquiera de estos botones para una selección rápida.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Selección de hora:\n" +
+"- Pulse en cualquiera de las partes de la hora para incrementarla\n" +
+"- o pulse las mayúsculas mientras hace clic para decrementarla\n" +
+"- o haga clic y arrastre el ratón para una selección más rápida.";
+
+Calendar._TT["PREV_YEAR"] = "Año anterior (mantener para menú)";
+Calendar._TT["PREV_MONTH"] = "Mes anterior (mantener para menú)";
+Calendar._TT["GO_TODAY"] = "Ir a hoy";
+Calendar._TT["NEXT_MONTH"] = "Mes siguiente (mantener para menú)";
+Calendar._TT["NEXT_YEAR"] = "Año siguiente (mantener para menú)";
+Calendar._TT["SEL_DATE"] = "Seleccionar fecha";
+Calendar._TT["DRAG_TO_MOVE"] = "Arrastrar para mover";
+Calendar._TT["PART_TODAY"] = " (hoy)";
+
+// the following is to inform that "%s" is to be the first day of week
+// %s will be replaced with the day name.
+Calendar._TT["DAY_FIRST"] = "Hacer %s primer día de la semana";
+
+// This may be locale-dependent. It specifies the week-end days, as an array
+// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1
+// means Monday, etc.
+Calendar._TT["WEEKEND"] = "0,6";
+
+Calendar._TT["CLOSE"] = "Cerrar";
+Calendar._TT["TODAY"] = "Hoy";
+Calendar._TT["TIME_PART"] = "(Mayúscula-)Clic o arrastre para cambiar valor";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%d/%m/%Y";
+Calendar._TT["TT_DATE_FORMAT"] = "%A, %e de %B de %Y";
+
+Calendar._TT["WK"] = "sem";
+Calendar._TT["TIME"] = "Hora:";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-fi.js b/WebContent/themes/default/jscalendar/lang/calendar-fi.js
new file mode 100644
index 0000000000..58899e7770
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-fi.js
@@ -0,0 +1,109 @@
+// ** I18N
+
+// Calendar FI language (Finnish, Suomi)
+// Author: Jarno K?yhk?, <gambler@phnet.fi>
+// Updated: 20060206 Marc Englund / IT Mill
+// Encoding: UTF-8
+// Distributed under the same terms as the calendar itself.
+
+// full day names
+Calendar._DN = new Array
+("Sunnuntai",
+ "Maanantai",
+ "Tiistai",
+ "Keskiviikko",
+ "Torstai",
+ "Perjantai",
+ "Lauantai",
+ "Sunnuntai");
+
+// short day names
+Calendar._SDN = new Array
+("Su",
+ "Ma",
+ "Ti",
+ "Ke",
+ "To",
+ "Pe",
+ "La",
+ "Su");
+
+// full month names
+Calendar._MN = new Array
+("Tammikuu",
+ "Helmikuu",
+ "Maaliskuu",
+ "Huhtikuu",
+ "Toukokuu",
+ "Kesäkuu",
+ "Heinäkuu",
+ "Elokuu",
+ "Syyskuu",
+ "Lokakuu",
+ "Marraskuu",
+ "Joulukuu");
+
+// short month names
+Calendar._SMN = new Array
+("Tam",
+ "Hel",
+ "Maa",
+ "Huh",
+ "Tou",
+ "Kes",
+ "Hei",
+ "Elo",
+ "Syy",
+ "Lok",
+ "Mar",
+ "Jou");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "Tietoja kalenterista";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"Uusin versio osoitteessa: http://www.dynarch.com/projects/calendar/\n" +
+"Julkaistu GNU LGPL lisenssin alaisuudessa. Lisätietoja osoitteessa http://gnu.org/licenses/lgpl.html" +
+"\n\n" +
+"Päivämäärä valinta:\n" +
+"- Käytä \xab, \xbb painikkeita valitaksesi vuosi\n" +
+"- Käytä " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " painikkeita valitaksesi kuukausi\n" +
+"- Pitämällä hiiren painiketta minkä tahansa yllä olevan painikkeen kohdalla, saat näkyviin valikon nopeampaan siirtymiseen.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Ajan valinta:\n" +
+"- Klikkaa kellonajan numeroita lisätäksesi aikaa\n" +
+"- tai pitämällä Shift-näppäintä pohjassa saat aikaa taaksepäin\n" +
+"- tai klikkaa ja pidä hiiren painike pohjassa sekä liikuta hiirtä muuttaaksesi aikaa nopeasti eteen- ja taaksepäin.";
+
+Calendar._TT["PREV_YEAR"] = "Edell. vuosi (paina hetki, näet valikon)";
+Calendar._TT["PREV_MONTH"] = "Edell. kuukausi (paina hetki, näet valikon)";
+Calendar._TT["GO_TODAY"] = "Siirry tähän päivään";
+Calendar._TT["NEXT_MONTH"] = "Seur. kuukausi (paina hetki, näet valikon)";
+Calendar._TT["NEXT_YEAR"] = "Seur. vuosi (paina hetki, näet valikon)";
+Calendar._TT["SEL_DATE"] = "Valitse päivämäärä";
+Calendar._TT["DRAG_TO_MOVE"] = "Siirrä kalenterin paikkaa";
+Calendar._TT["PART_TODAY"] = " (tänään)";
+Calendar._TT["MON_FIRST"] = "Näytä maanantai ensimmäisenä";
+Calendar._TT["SUN_FIRST"] = "Näytä sunnuntai ensimmäisenä";
+Calendar._TT["CLOSE"] = "Sulje";
+Calendar._TT["TODAY"] = "Tänään";
+Calendar._TT["TIME_PART"] = "(Shift-) Klikkaa tai liikuta muuttaaksesi aikaa";
+
+// the following is to inform that "%s" is to be the first day of week
+// %s will be replaced with the day name.
+Calendar._TT["DAY_FIRST"] = "Näytä %s ensimmäisenä";
+
+// This may be locale-dependent. It specifies the week-end days, as an array
+// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1
+// means Monday, etc.
+Calendar._TT["WEEKEND"] = "0,6";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%d.%m.%Y";
+Calendar._TT["TT_DATE_FORMAT"] = "%d.%m.%Y";
+
+Calendar._TT["WK"] = "Vko";
+Calendar._TT["TIME"] = "Aika:";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-fr.js b/WebContent/themes/default/jscalendar/lang/calendar-fr.js
new file mode 100644
index 0000000000..2a9e0b20bb
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-fr.js
@@ -0,0 +1,125 @@
+// ** I18N
+
+// Calendar EN language
+// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
+// Encoding: any
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible. We strongly believe that
+// Unicode is the answer to a real internationalized world. Also please
+// include your contact information in the header, as can be seen above.
+
+// Translator: David Duret, <pilgrim@mala-template.net> from previous french version
+
+// full day names
+Calendar._DN = new Array
+("Dimanche",
+ "Lundi",
+ "Mardi",
+ "Mercredi",
+ "Jeudi",
+ "Vendredi",
+ "Samedi",
+ "Dimanche");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary. We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+// Calendar._SDN_len = N; // short day name length
+// Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+Calendar._SDN = new Array
+("Dim",
+ "Lun",
+ "Mar",
+ "Mar",
+ "Jeu",
+ "Ven",
+ "Sam",
+ "Dim");
+
+// full month names
+Calendar._MN = new Array
+("Janvier",
+ "Février",
+ "Mars",
+ "Avril",
+ "Mai",
+ "Juin",
+ "Juillet",
+ "Août",
+ "Septembre",
+ "Octobre",
+ "Novembre",
+ "Décembre");
+
+// short month names
+Calendar._SMN = new Array
+("Jan",
+ "Fev",
+ "Mar",
+ "Avr",
+ "Mai",
+ "Juin",
+ "Juil",
+ "Aout",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "A propos du calendrier";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Heure Selecteur\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"Pour la derniere version visitez : http://www.dynarch.com/projects/calendar/\n" +
+"Distribué par GNU LGPL. Voir http://gnu.org/licenses/lgpl.html pour les details." +
+"\n\n" +
+"Selection de la date :\n" +
+"- Utiliser les bouttons \xab, \xbb pour selectionner l\'annee\n" +
+"- Utiliser les bouttons " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " pour selectionner les mois\n" +
+"- Garder la souris sur n'importe quels boutons pour une selection plus rapide";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Selection de l\'heure :\n" +
+"- Cliquer sur heures ou minutes pour incrementer\n" +
+"- ou Maj-clic pour decrementer\n" +
+"- ou clic et glisser-deplacer pour une selection plus rapide";
+
+Calendar._TT["PREV_YEAR"] = "Année préc. (maintenir pour menu)";
+Calendar._TT["PREV_MONTH"] = "Mois préc. (maintenir pour menu)";
+Calendar._TT["GO_TODAY"] = "Atteindre la date du jour";
+Calendar._TT["NEXT_MONTH"] = "Mois suiv. (maintenir pour menu)";
+Calendar._TT["NEXT_YEAR"] = "Année suiv. (maintenir pour menu)";
+Calendar._TT["SEL_DATE"] = "Sélectionner une date";
+Calendar._TT["DRAG_TO_MOVE"] = "Déplacer";
+Calendar._TT["PART_TODAY"] = " (Aujourd'hui)";
+
+// the following is to inform that "%s" is to be the first day of week
+// %s will be replaced with the day name.
+Calendar._TT["DAY_FIRST"] = "Afficher %s en premier";
+
+// This may be locale-dependent. It specifies the week-end days, as an array
+// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1
+// means Monday, etc.
+Calendar._TT["WEEKEND"] = "0,6";
+
+Calendar._TT["CLOSE"] = "Fermer";
+Calendar._TT["TODAY"] = "Aujourd'hui";
+Calendar._TT["TIME_PART"] = "(Maj-)Clic ou glisser pour modifier la valeur";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%d/%m/%Y";
+Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
+
+Calendar._TT["WK"] = "Sem.";
+Calendar._TT["TIME"] = "Heure :";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-he-utf8.js b/WebContent/themes/default/jscalendar/lang/calendar-he-utf8.js
new file mode 100644
index 0000000000..7861217bae
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-he-utf8.js
@@ -0,0 +1,123 @@
+// ** I18N
+
+// Calendar EN language
+// Author: Idan Sofer, <idan@idanso.dyndns.org>
+// Encoding: UTF-8
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible. We strongly believe that
+// Unicode is the answer to a real internationalized world. Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+Calendar._DN = new Array
+("ר×שון",
+ "שני",
+ "שלישי",
+ "רביעי",
+ "חמישי",
+ "שישי",
+ "שבת",
+ "ר×שון");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary. We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+// Calendar._SDN_len = N; // short day name length
+// Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+Calendar._SDN = new Array
+("×",
+ "ב",
+ "×’",
+ "ד",
+ "×”",
+ "ו",
+ "ש",
+ "×");
+
+// full month names
+Calendar._MN = new Array
+("ינו×ר",
+ "פברו×ר",
+ "מרץ",
+ "×פריל",
+ "מ××™",
+ "יוני",
+ "יולי",
+ "×וגוסט",
+ "ספטמבר",
+ "×וקטובר",
+ "נובמבר",
+ "דצמבר");
+
+// short month names
+Calendar._SMN = new Array
+("×™× ×",
+ "פבר",
+ "מרץ",
+ "×פר",
+ "מ××™",
+ "יונ",
+ "יול",
+ "×וג",
+ "ספט",
+ "×וק",
+ "נוב",
+ "דצמ");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "×ודות השנתון";
+
+Calendar._TT["ABOUT"] =
+"בחרן ת×ריך/שעה DHTML\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"×”×’×™×¨×¡× ×”×חרונה זמינה ב: http://www.dynarch.com/projects/calendar/\n" +
+"מופץ תחת זיכיון ×” GNU LGPL. עיין ב http://gnu.org/licenses/lgpl.html ×œ×¤×¨×˜×™× × ×•×¡×¤×™×." +
+"\n\n" +
+בחירת ת×ריך:\n" +
+"- השתמש ×‘×›×¤×ª×•×¨×™× \xab, \xbb לבחירת שנה\n" +
+"- השתמש ×‘×›×¤×ª×•×¨×™× " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " לבחירת חודש\n" +
+"- החזק העכבר לחוץ מעל ×”×›×¤×ª×•×¨×™× ×”×ž×•×–×›×¨×™× ×œ×¢×™×œ לבחירה מהירה יותר.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"בחירת זמן:\n" +
+"- לחץ על כל ×חד מחלקי הזמן כדי להוסיף\n" +
+"- ×ו shift בשילוב ×¢× ×œ×—×™×¦×” כדי להחסיר\n" +
+"- ×ו לחץ וגרור לפעולה מהירה יותר.";
+
+Calendar._TT["PREV_YEAR"] = "שנה קודמת - החזק לקבלת תפריט";
+Calendar._TT["PREV_MONTH"] = "חודש ×§×•×“× - החזק לקבלת תפריט";
+Calendar._TT["GO_TODAY"] = "עבור להיו×";
+Calendar._TT["NEXT_MONTH"] = "חודש ×”×‘× - החזק לתפריט";
+Calendar._TT["NEXT_YEAR"] = "שנה הב××” - החזק לתפריט";
+Calendar._TT["SEL_DATE"] = "בחר ת×ריך";
+Calendar._TT["DRAG_TO_MOVE"] = "גרור להזזה";
+Calendar._TT["PART_TODAY"] = " )היו×(";
+
+// the following is to inform that "%s" is to be the first day of week
+// %s will be replaced with the day name.
+Calendar._TT["DAY_FIRST"] = "הצג %s קוד×";
+
+// This may be locale-dependent. It specifies the week-end days, as an array
+// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1
+// means Monday, etc.
+Calendar._TT["WEEKEND"] = "6";
+
+Calendar._TT["CLOSE"] = "סגור";
+Calendar._TT["TODAY"] = "היו×";
+Calendar._TT["TIME_PART"] = "(שיפט-)לחץ וגרור כדי לשנות ערך";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
+Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
+
+Calendar._TT["WK"] = "wk";
+Calendar._TT["TIME"] = "שעה::";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-hr-utf8.js b/WebContent/themes/default/jscalendar/lang/calendar-hr-utf8.js
new file mode 100644
index 0000000000..baf01b179c
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-hr-utf8.js
@@ -0,0 +1,49 @@
+/* Croatian language file for the DHTML Calendar version 0.9.2
+* Author Krunoslav Zubrinic <krunoslav.zubrinic@vip.hr>, June 2003.
+* Feel free to use this script under the terms of the GNU Lesser General
+* Public License, as long as you do not remove or alter this notice.
+*/
+Calendar._DN = new Array
+("Nedjelja",
+ "Ponedjeljak",
+ "Utorak",
+ "Srijeda",
+ "ÄŒetvrtak",
+ "Petak",
+ "Subota",
+ "Nedjelja");
+Calendar._MN = new Array
+("SijeÄanj",
+ "VeljaÄa",
+ "Ožujak",
+ "Travanj",
+ "Svibanj",
+ "Lipanj",
+ "Srpanj",
+ "Kolovoz",
+ "Rujan",
+ "Listopad",
+ "Studeni",
+ "Prosinac");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["TOGGLE"] = "Promjeni dan s kojim poÄinje tjedan";
+Calendar._TT["PREV_YEAR"] = "Prethodna godina (dugi pritisak za meni)";
+Calendar._TT["PREV_MONTH"] = "Prethodni mjesec (dugi pritisak za meni)";
+Calendar._TT["GO_TODAY"] = "Idi na tekući dan";
+Calendar._TT["NEXT_MONTH"] = "Slijedeći mjesec (dugi pritisak za meni)";
+Calendar._TT["NEXT_YEAR"] = "Slijedeća godina (dugi pritisak za meni)";
+Calendar._TT["SEL_DATE"] = "Izaberite datum";
+Calendar._TT["DRAG_TO_MOVE"] = "Pritisni i povuci za promjenu pozicije";
+Calendar._TT["PART_TODAY"] = " (today)";
+Calendar._TT["MON_FIRST"] = "Prikaži ponedjeljak kao prvi dan";
+Calendar._TT["SUN_FIRST"] = "Prikaži nedjelju kao prvi dan";
+Calendar._TT["CLOSE"] = "Zatvori";
+Calendar._TT["TODAY"] = "Danas";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "dd-mm-y";
+Calendar._TT["TT_DATE_FORMAT"] = "DD, dd.mm.y";
+
+Calendar._TT["WK"] = "Tje"; \ No newline at end of file
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-hr.js b/WebContent/themes/default/jscalendar/lang/calendar-hr.js
new file mode 100644
index 0000000000..6c27f60c4f
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-hr.js
Binary files differ
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-hu.js b/WebContent/themes/default/jscalendar/lang/calendar-hu.js
new file mode 100644
index 0000000000..f5bf057ecf
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-hu.js
@@ -0,0 +1,124 @@
+// ** I18N
+
+// Calendar HU language
+// Author: ???
+// Modifier: KARASZI Istvan, <jscalendar@spam.raszi.hu>
+// Encoding: any
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible. We strongly believe that
+// Unicode is the answer to a real internationalized world. Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+Calendar._DN = new Array
+("Vasárnap",
+ "Hétfõ",
+ "Kedd",
+ "Szerda",
+ "Csütörtök",
+ "Péntek",
+ "Szombat",
+ "Vasárnap");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary. We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+// Calendar._SDN_len = N; // short day name length
+// Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+Calendar._SDN = new Array
+("v",
+ "h",
+ "k",
+ "sze",
+ "cs",
+ "p",
+ "szo",
+ "v");
+
+// full month names
+Calendar._MN = new Array
+("január",
+ "február",
+ "március",
+ "április",
+ "május",
+ "június",
+ "július",
+ "augusztus",
+ "szeptember",
+ "október",
+ "november",
+ "december");
+
+// short month names
+Calendar._SMN = new Array
+("jan",
+ "feb",
+ "már",
+ "ápr",
+ "máj",
+ "jún",
+ "júl",
+ "aug",
+ "sze",
+ "okt",
+ "nov",
+ "dec");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "A kalendáriumról";
+
+Calendar._TT["ABOUT"] =
+"DHTML dátum/idõ kiválasztó\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"a legfrissebb verzió megtalálható: http://www.dynarch.com/projects/calendar/\n" +
+"GNU LGPL alatt terjesztve. Lásd a http://gnu.org/licenses/lgpl.html oldalt a részletekhez." +
+"\n\n" +
+"Dátum választás:\n" +
+"- használja a \xab, \xbb gombokat az év kiválasztásához\n" +
+"- használja a " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " gombokat a hónap kiválasztásához\n" +
+"- tartsa lenyomva az egérgombot a gyors választáshoz.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Idõ választás:\n" +
+"- kattintva növelheti az idõt\n" +
+"- shift-tel kattintva csökkentheti\n" +
+"- lenyomva tartva és húzva gyorsabban kiválaszthatja.";
+
+Calendar._TT["PREV_YEAR"] = "Elõzõ év (tartsa nyomva a menühöz)";
+Calendar._TT["PREV_MONTH"] = "Elõzõ hónap (tartsa nyomva a menühöz)";
+Calendar._TT["GO_TODAY"] = "Mai napra ugrás";
+Calendar._TT["NEXT_MONTH"] = "Köv. hónap (tartsa nyomva a menühöz)";
+Calendar._TT["NEXT_YEAR"] = "Köv. év (tartsa nyomva a menühöz)";
+Calendar._TT["SEL_DATE"] = "Válasszon dátumot";
+Calendar._TT["DRAG_TO_MOVE"] = "Húzza a mozgatáshoz";
+Calendar._TT["PART_TODAY"] = " (ma)";
+
+// the following is to inform that "%s" is to be the first day of week
+// %s will be replaced with the day name.
+Calendar._TT["DAY_FIRST"] = "%s legyen a hét elsõ napja";
+
+// This may be locale-dependent. It specifies the week-end days, as an array
+// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1
+// means Monday, etc.
+Calendar._TT["WEEKEND"] = "0,6";
+
+Calendar._TT["CLOSE"] = "Bezár";
+Calendar._TT["TODAY"] = "Ma";
+Calendar._TT["TIME_PART"] = "(Shift-)Klikk vagy húzás az érték változtatásához";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
+Calendar._TT["TT_DATE_FORMAT"] = "%b %e, %a";
+
+Calendar._TT["WK"] = "hét";
+Calendar._TT["TIME"] = "idõ:";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-it.js b/WebContent/themes/default/jscalendar/lang/calendar-it.js
new file mode 100644
index 0000000000..7f84cde01f
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-it.js
@@ -0,0 +1,124 @@
+// ** I18N
+
+// Calendar EN language
+// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
+// Translator: Fabio Di Bernardini, <altraqua@email.it>
+// Encoding: any
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible. We strongly believe that
+// Unicode is the answer to a real internationalized world. Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+Calendar._DN = new Array
+("Domenica",
+ "Lunedì",
+ "Martedì",
+ "Mercoledì",
+ "Giovedì",
+ "Venerdì",
+ "Sabato",
+ "Domenica");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary. We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+// Calendar._SDN_len = N; // short day name length
+// Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+Calendar._SDN = new Array
+("Dom",
+ "Lun",
+ "Mar",
+ "Mer",
+ "Gio",
+ "Ven",
+ "Sab",
+ "Dom");
+
+// full month names
+Calendar._MN = new Array
+("Gennaio",
+ "Febbraio",
+ "Marzo",
+ "Aprile",
+ "Maggio",
+ "Giugno",
+ "Luglio",
+ "Augosto",
+ "Settembre",
+ "Ottobre",
+ "Novembre",
+ "Dicembre");
+
+// short month names
+Calendar._SMN = new Array
+("Gen",
+ "Feb",
+ "Mar",
+ "Apr",
+ "Mag",
+ "Giu",
+ "Lug",
+ "Ago",
+ "Set",
+ "Ott",
+ "Nov",
+ "Dic");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "Informazioni sul calendario";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"Per gli aggiornamenti: http://www.dynarch.com/projects/calendar/\n" +
+"Distribuito sotto licenza GNU LGPL. Vedi http://gnu.org/licenses/lgpl.html per i dettagli." +
+"\n\n" +
+"Selezione data:\n" +
+"- Usa \xab, \xbb per selezionare l'anno\n" +
+"- Usa " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " per i mesi\n" +
+"- Tieni premuto a lungo il mouse per accedere alle funzioni di selezione veloce.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Selezione orario:\n" +
+"- Clicca sul numero per incrementarlo\n" +
+"- o Shift+click per decrementarlo\n" +
+"- o click e sinistra o destra per variarlo.";
+
+Calendar._TT["PREV_YEAR"] = "Anno prec.(clicca a lungo per il menù)";
+Calendar._TT["PREV_MONTH"] = "Mese prec. (clicca a lungo per il menù)";
+Calendar._TT["GO_TODAY"] = "Oggi";
+Calendar._TT["NEXT_MONTH"] = "Pross. mese (clicca a lungo per il menù)";
+Calendar._TT["NEXT_YEAR"] = "Pross. anno (clicca a lungo per il menù)";
+Calendar._TT["SEL_DATE"] = "Seleziona data";
+Calendar._TT["DRAG_TO_MOVE"] = "Trascina per spostarlo";
+Calendar._TT["PART_TODAY"] = " (oggi)";
+
+// the following is to inform that "%s" is to be the first day of week
+// %s will be replaced with the day name.
+Calendar._TT["DAY_FIRST"] = "Mostra prima %s";
+
+// This may be locale-dependent. It specifies the week-end days, as an array
+// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1
+// means Monday, etc.
+Calendar._TT["WEEKEND"] = "0,6";
+
+Calendar._TT["CLOSE"] = "Chiudi";
+Calendar._TT["TODAY"] = "Oggi";
+Calendar._TT["TIME_PART"] = "(Shift-)Click o trascina per cambiare il valore";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%d-%m-%Y";
+Calendar._TT["TT_DATE_FORMAT"] = "%a:%b:%e";
+
+Calendar._TT["WK"] = "set";
+Calendar._TT["TIME"] = "Ora:";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-jp.js b/WebContent/themes/default/jscalendar/lang/calendar-jp.js
new file mode 100644
index 0000000000..3bca7ebf60
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-jp.js
@@ -0,0 +1,45 @@
+// ** I18N
+Calendar._DN = new Array
+("“ú",
+ "ŒŽ",
+ "‰Î",
+ "…",
+ "–Ø",
+ "‹à",
+ "“y",
+ "“ú");
+Calendar._MN = new Array
+("1ŒŽ",
+ "2ŒŽ",
+ "3ŒŽ",
+ "4ŒŽ",
+ "5ŒŽ",
+ "6ŒŽ",
+ "7ŒŽ",
+ "8ŒŽ",
+ "9ŒŽ",
+ "10ŒŽ",
+ "11ŒŽ",
+ "12ŒŽ");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["TOGGLE"] = "T‚Ìʼn‚Ì—j“ú‚ðØ‚è‘Ö‚¦";
+Calendar._TT["PREV_YEAR"] = "‘O”N";
+Calendar._TT["PREV_MONTH"] = "‘OŒŽ";
+Calendar._TT["GO_TODAY"] = "¡“ú";
+Calendar._TT["NEXT_MONTH"] = "—‚ŒŽ";
+Calendar._TT["NEXT_YEAR"] = "—‚”N";
+Calendar._TT["SEL_DATE"] = "“ú•t‘I‘ð";
+Calendar._TT["DRAG_TO_MOVE"] = "ƒEƒBƒ“ƒhƒE‚̈ړ®";
+Calendar._TT["PART_TODAY"] = " (¡“ú)";
+Calendar._TT["MON_FIRST"] = "ŒŽ—j“ú‚ð擪‚É";
+Calendar._TT["SUN_FIRST"] = "“ú—j“ú‚ð擪‚É";
+Calendar._TT["CLOSE"] = "•Â‚¶‚é";
+Calendar._TT["TODAY"] = "¡“ú";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "y-mm-dd";
+Calendar._TT["TT_DATE_FORMAT"] = "%mŒŽ %d“ú (%a)";
+
+Calendar._TT["WK"] = "T";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-ko-utf8.js b/WebContent/themes/default/jscalendar/lang/calendar-ko-utf8.js
new file mode 100644
index 0000000000..035dd748d3
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-ko-utf8.js
@@ -0,0 +1,120 @@
+// ** I18N
+
+// Calendar EN language
+// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
+// Translation: Yourim Yi <yyi@yourim.net>
+// Encoding: EUC-KR
+// lang : ko
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible. We strongly believe that
+// Unicode is the answer to a real internationalized world. Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+
+Calendar._DN = new Array
+("ì¼ìš”ì¼",
+ "월요ì¼",
+ "화요ì¼",
+ "수요ì¼",
+ "목요ì¼",
+ "금요ì¼",
+ "토요ì¼",
+ "ì¼ìš”ì¼");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary. We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+// Calendar._SDN_len = N; // short day name length
+// Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+Calendar._SDN = new Array
+("ì¼",
+ "ì›”",
+ "í™”",
+ "수",
+ "목",
+ "금",
+ "토",
+ "ì¼");
+
+// full month names
+Calendar._MN = new Array
+("1ì›”",
+ "2ì›”",
+ "3ì›”",
+ "4ì›”",
+ "5ì›”",
+ "6ì›”",
+ "7ì›”",
+ "8ì›”",
+ "9ì›”",
+ "10ì›”",
+ "11ì›”",
+ "12ì›”");
+
+// short month names
+Calendar._SMN = new Array
+("1",
+ "2",
+ "3",
+ "4",
+ "5",
+ "6",
+ "7",
+ "8",
+ "9",
+ "10",
+ "11",
+ "12");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "calendar ì— ëŒ€í•´ì„œ";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"\n"+
+"최신 ë²„ì „ì„ ë°›ìœ¼ì‹œë ¤ë©´ http://www.dynarch.com/projects/calendar/ ì— ë°©ë¬¸í•˜ì„¸ìš”\n" +
+"\n"+
+"GNU LGPL ë¼ì´ì„¼ìŠ¤ë¡œ ë°°í¬ë©ë‹ˆë‹¤. \n"+
+"ë¼ì´ì„¼ìŠ¤ì— 대한 ìžì„¸í•œ ë‚´ìš©ì€ http://gnu.org/licenses/lgpl.html ì„ ì½ìœ¼ì„¸ìš”." +
+"\n\n" +
+"날짜 ì„ íƒ:\n" +
+"- ì—°ë„를 ì„ íƒí•˜ë ¤ë©´ \xab, \xbb ë²„íŠ¼ì„ ì‚¬ìš©í•©ë‹ˆë‹¤\n" +
+"- ë‹¬ì„ ì„ íƒí•˜ë ¤ë©´ " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " ë²„íŠ¼ì„ ëˆ„ë¥´ì„¸ìš”\n" +
+"- ê³„ì† ëˆ„ë¥´ê³  있으면 위 ê°’ë“¤ì„ ë¹ ë¥´ê²Œ ì„ íƒí•˜ì‹¤ 수 있습니다.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"시간 ì„ íƒ:\n" +
+"- 마우스로 누르면 ì‹œê°„ì´ ì¦ê°€í•©ë‹ˆë‹¤\n" +
+"- Shift 키와 함께 누르면 ê°ì†Œí•©ë‹ˆë‹¤\n" +
+"- 누른 ìƒíƒœì—ì„œ 마우스를 움ì§ì´ë©´ 좀 ë” ë¹ ë¥´ê²Œ ê°’ì´ ë³€í•©ë‹ˆë‹¤.\n";
+
+Calendar._TT["PREV_YEAR"] = "지난 í•´ (길게 누르면 목ë¡)";
+Calendar._TT["PREV_MONTH"] = "지난 달 (길게 누르면 목ë¡)";
+Calendar._TT["GO_TODAY"] = "오늘 날짜로";
+Calendar._TT["NEXT_MONTH"] = "ë‹¤ìŒ ë‹¬ (길게 누르면 목ë¡)";
+Calendar._TT["NEXT_YEAR"] = "ë‹¤ìŒ í•´ (길게 누르면 목ë¡)";
+Calendar._TT["SEL_DATE"] = "날짜를 ì„ íƒí•˜ì„¸ìš”";
+Calendar._TT["DRAG_TO_MOVE"] = "마우스 드래그로 ì´ë™ 하세요";
+Calendar._TT["PART_TODAY"] = " (오늘)";
+Calendar._TT["MON_FIRST"] = "월요ì¼ì„ í•œ ì£¼ì˜ ì‹œìž‘ ìš”ì¼ë¡œ";
+Calendar._TT["SUN_FIRST"] = "ì¼ìš”ì¼ì„ í•œ ì£¼ì˜ ì‹œìž‘ ìš”ì¼ë¡œ";
+Calendar._TT["CLOSE"] = "닫기";
+Calendar._TT["TODAY"] = "오늘";
+Calendar._TT["TIME_PART"] = "(Shift-)í´ë¦­ ë˜ëŠ” 드래그 하세요";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
+Calendar._TT["TT_DATE_FORMAT"] = "%b/%e [%a]";
+
+Calendar._TT["WK"] = "주";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-ko.js b/WebContent/themes/default/jscalendar/lang/calendar-ko.js
new file mode 100644
index 0000000000..8cddf58645
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-ko.js
@@ -0,0 +1,120 @@
+// ** I18N
+
+// Calendar EN language
+// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
+// Translation: Yourim Yi <yyi@yourim.net>
+// Encoding: EUC-KR
+// lang : ko
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible. We strongly believe that
+// Unicode is the answer to a real internationalized world. Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+
+Calendar._DN = new Array
+("ÀÏ¿äÀÏ",
+ "¿ù¿äÀÏ",
+ "È­¿äÀÏ",
+ "¼ö¿äÀÏ",
+ "¸ñ¿äÀÏ",
+ "±Ý¿äÀÏ",
+ "Åä¿äÀÏ",
+ "ÀÏ¿äÀÏ");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary. We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+// Calendar._SDN_len = N; // short day name length
+// Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+Calendar._SDN = new Array
+("ÀÏ",
+ "¿ù",
+ "È­",
+ "¼ö",
+ "¸ñ",
+ "±Ý",
+ "Åä",
+ "ÀÏ");
+
+// full month names
+Calendar._MN = new Array
+("1¿ù",
+ "2¿ù",
+ "3¿ù",
+ "4¿ù",
+ "5¿ù",
+ "6¿ù",
+ "7¿ù",
+ "8¿ù",
+ "9¿ù",
+ "10¿ù",
+ "11¿ù",
+ "12¿ù");
+
+// short month names
+Calendar._SMN = new Array
+("1",
+ "2",
+ "3",
+ "4",
+ "5",
+ "6",
+ "7",
+ "8",
+ "9",
+ "10",
+ "11",
+ "12");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "calendar ¿¡ ´ëÇؼ­";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"\n"+
+"ÃֽŠ¹öÀüÀ» ¹ÞÀ¸½Ã·Á¸é http://www.dynarch.com/projects/calendar/ ¿¡ ¹æ¹®Çϼ¼¿ä\n" +
+"\n"+
+"GNU LGPL ¶óÀ̼¾½º·Î ¹èÆ÷µË´Ï´Ù. \n"+
+"¶óÀ̼¾½º¿¡ ´ëÇÑ ÀÚ¼¼ÇÑ ³»¿ëÀº http://gnu.org/licenses/lgpl.html À» ÀÐÀ¸¼¼¿ä." +
+"\n\n" +
+"³¯Â¥ ¼±ÅÃ:\n" +
+"- ¿¬µµ¸¦ ¼±ÅÃÇÏ·Á¸é \xab, \xbb ¹öÆ°À» »ç¿ëÇÕ´Ï´Ù\n" +
+"- ´ÞÀ» ¼±ÅÃÇÏ·Á¸é " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " ¹öÆ°À» ´©¸£¼¼¿ä\n" +
+"- °è¼Ó ´©¸£°í ÀÖÀ¸¸é À§ °ªµéÀ» ºü¸£°Ô ¼±ÅÃÇÏ½Ç ¼ö ÀÖ½À´Ï´Ù.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"½Ã°£ ¼±ÅÃ:\n" +
+"- ¸¶¿ì½º·Î ´©¸£¸é ½Ã°£ÀÌ Áõ°¡ÇÕ´Ï´Ù\n" +
+"- Shift Å°¿Í ÇÔ²² ´©¸£¸é °¨¼ÒÇÕ´Ï´Ù\n" +
+"- ´©¸¥ »óÅ¿¡¼­ ¸¶¿ì½º¸¦ ¿òÁ÷À̸é Á» ´õ ºü¸£°Ô °ªÀÌ º¯ÇÕ´Ï´Ù.\n";
+
+Calendar._TT["PREV_YEAR"] = "Áö³­ ÇØ (±æ°Ô ´©¸£¸é ¸ñ·Ï)";
+Calendar._TT["PREV_MONTH"] = "Áö³­ ´Þ (±æ°Ô ´©¸£¸é ¸ñ·Ï)";
+Calendar._TT["GO_TODAY"] = "¿À´Ã ³¯Â¥·Î";
+Calendar._TT["NEXT_MONTH"] = "´ÙÀ½ ´Þ (±æ°Ô ´©¸£¸é ¸ñ·Ï)";
+Calendar._TT["NEXT_YEAR"] = "´ÙÀ½ ÇØ (±æ°Ô ´©¸£¸é ¸ñ·Ï)";
+Calendar._TT["SEL_DATE"] = "³¯Â¥¸¦ ¼±ÅÃÇϼ¼¿ä";
+Calendar._TT["DRAG_TO_MOVE"] = "¸¶¿ì½º µå·¡±×·Î À̵¿ Çϼ¼¿ä";
+Calendar._TT["PART_TODAY"] = " (¿À´Ã)";
+Calendar._TT["MON_FIRST"] = "¿ù¿äÀÏÀ» ÇÑ ÁÖÀÇ ½ÃÀÛ ¿äÀÏ·Î";
+Calendar._TT["SUN_FIRST"] = "ÀÏ¿äÀÏÀ» ÇÑ ÁÖÀÇ ½ÃÀÛ ¿äÀÏ·Î";
+Calendar._TT["CLOSE"] = "´Ý±â";
+Calendar._TT["TODAY"] = "¿À´Ã";
+Calendar._TT["TIME_PART"] = "(Shift-)Ŭ¸¯ ¶Ç´Â µå·¡±× Çϼ¼¿ä";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
+Calendar._TT["TT_DATE_FORMAT"] = "%b/%e [%a]";
+
+Calendar._TT["WK"] = "ÁÖ";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-lt-utf8.js b/WebContent/themes/default/jscalendar/lang/calendar-lt-utf8.js
new file mode 100644
index 0000000000..d39653be27
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-lt-utf8.js
@@ -0,0 +1,114 @@
+// ** I18N
+
+// Calendar LT language
+// Author: Martynas Majeris, <martynas@solmetra.lt>
+// Encoding: UTF-8
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible. We strongly believe that
+// Unicode is the answer to a real internationalized world. Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+Calendar._DN = new Array
+("Sekmadienis",
+ "Pirmadienis",
+ "Antradienis",
+ "TreÄiadienis",
+ "Ketvirtadienis",
+ "Pentadienis",
+ "Šeštadienis",
+ "Sekmadienis");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary. We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+// Calendar._SDN_len = N; // short day name length
+// Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+Calendar._SDN = new Array
+("Sek",
+ "Pir",
+ "Ant",
+ "Tre",
+ "Ket",
+ "Pen",
+ "Šeš",
+ "Sek");
+
+// full month names
+Calendar._MN = new Array
+("Sausis",
+ "Vasaris",
+ "Kovas",
+ "Balandis",
+ "Gegužė",
+ "Birželis",
+ "Liepa",
+ "Rugpjūtis",
+ "RugsÄ—jis",
+ "Spalis",
+ "Lapkritis",
+ "Gruodis");
+
+// short month names
+Calendar._SMN = new Array
+("Sau",
+ "Vas",
+ "Kov",
+ "Bal",
+ "Geg",
+ "Bir",
+ "Lie",
+ "Rgp",
+ "Rgs",
+ "Spa",
+ "Lap",
+ "Gru");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "Apie kalendorių";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"NaujausiÄ… versijÄ… rasite: http://www.dynarch.com/projects/calendar/\n" +
+"Platinamas pagal GNU LGPL licencijÄ…. Aplankykite http://gnu.org/licenses/lgpl.html" +
+"\n\n" +
+"Datos pasirinkimas:\n" +
+"- Metų pasirinkimas: \xab, \xbb\n" +
+"- MÄ—nesio pasirinkimas: " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + "\n" +
+"- Nuspauskite ir laikykite pelės klavišą greitesniam pasirinkimui.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Laiko pasirinkimas:\n" +
+"- Spustelkite ant valandų arba minuÄių - skaiÄius padidÄ—s vienetu.\n" +
+"- Jei spausite kartu su Shift, skaiÄius sumažės.\n" +
+"- Greitam pasirinkimui spustelkite ir pajudinkite pelÄ™.";
+
+Calendar._TT["PREV_YEAR"] = "Ankstesni metai (laikykite, jei norite meniu)";
+Calendar._TT["PREV_MONTH"] = "Ankstesnis mÄ—nuo (laikykite, jei norite meniu)";
+Calendar._TT["GO_TODAY"] = "Pasirinkti Å¡iandienÄ…";
+Calendar._TT["NEXT_MONTH"] = "Kitas mÄ—nuo (laikykite, jei norite meniu)";
+Calendar._TT["NEXT_YEAR"] = "Kiti metai (laikykite, jei norite meniu)";
+Calendar._TT["SEL_DATE"] = "Pasirinkite datÄ…";
+Calendar._TT["DRAG_TO_MOVE"] = "Tempkite";
+Calendar._TT["PART_TODAY"] = " (Å¡iandien)";
+Calendar._TT["MON_FIRST"] = "Pirma savaitÄ—s diena - pirmadienis";
+Calendar._TT["SUN_FIRST"] = "Pirma savaitÄ—s diena - sekmadienis";
+Calendar._TT["CLOSE"] = "Uždaryti";
+Calendar._TT["TODAY"] = "Å iandien";
+Calendar._TT["TIME_PART"] = "Spustelkite arba tempkite jei norite pakeisti";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
+Calendar._TT["TT_DATE_FORMAT"] = "%A, %Y-%m-%d";
+
+Calendar._TT["WK"] = "sav";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-lt.js b/WebContent/themes/default/jscalendar/lang/calendar-lt.js
new file mode 100644
index 0000000000..43b93d6810
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-lt.js
@@ -0,0 +1,114 @@
+// ** I18N
+
+// Calendar LT language
+// Author: Martynas Majeris, <martynas@solmetra.lt>
+// Encoding: Windows-1257
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible. We strongly believe that
+// Unicode is the answer to a real internationalized world. Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+Calendar._DN = new Array
+("Sekmadienis",
+ "Pirmadienis",
+ "Antradienis",
+ "Treèiadienis",
+ "Ketvirtadienis",
+ "Pentadienis",
+ "Ðeðtadienis",
+ "Sekmadienis");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary. We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+// Calendar._SDN_len = N; // short day name length
+// Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+Calendar._SDN = new Array
+("Sek",
+ "Pir",
+ "Ant",
+ "Tre",
+ "Ket",
+ "Pen",
+ "Ðeð",
+ "Sek");
+
+// full month names
+Calendar._MN = new Array
+("Sausis",
+ "Vasaris",
+ "Kovas",
+ "Balandis",
+ "Geguþë",
+ "Birþelis",
+ "Liepa",
+ "Rugpjûtis",
+ "Rugsëjis",
+ "Spalis",
+ "Lapkritis",
+ "Gruodis");
+
+// short month names
+Calendar._SMN = new Array
+("Sau",
+ "Vas",
+ "Kov",
+ "Bal",
+ "Geg",
+ "Bir",
+ "Lie",
+ "Rgp",
+ "Rgs",
+ "Spa",
+ "Lap",
+ "Gru");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "Apie kalendoriø";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"Naujausià versijà rasite: http://www.dynarch.com/projects/calendar/\n" +
+"Platinamas pagal GNU LGPL licencijà. Aplankykite http://gnu.org/licenses/lgpl.html" +
+"\n\n" +
+"Datos pasirinkimas:\n" +
+"- Metø pasirinkimas: \xab, \xbb\n" +
+"- Mënesio pasirinkimas: " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + "\n" +
+"- Nuspauskite ir laikykite pelës klaviðà greitesniam pasirinkimui.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Laiko pasirinkimas:\n" +
+"- Spustelkite ant valandø arba minuèiø - skaièus padidës vienetu.\n" +
+"- Jei spausite kartu su Shift, skaièius sumaþës.\n" +
+"- Greitam pasirinkimui spustelkite ir pajudinkite pelæ.";
+
+Calendar._TT["PREV_YEAR"] = "Ankstesni metai (laikykite, jei norite meniu)";
+Calendar._TT["PREV_MONTH"] = "Ankstesnis mënuo (laikykite, jei norite meniu)";
+Calendar._TT["GO_TODAY"] = "Pasirinkti ðiandienà";
+Calendar._TT["NEXT_MONTH"] = "Kitas mënuo (laikykite, jei norite meniu)";
+Calendar._TT["NEXT_YEAR"] = "Kiti metai (laikykite, jei norite meniu)";
+Calendar._TT["SEL_DATE"] = "Pasirinkite datà";
+Calendar._TT["DRAG_TO_MOVE"] = "Tempkite";
+Calendar._TT["PART_TODAY"] = " (ðiandien)";
+Calendar._TT["MON_FIRST"] = "Pirma savaitës diena - pirmadienis";
+Calendar._TT["SUN_FIRST"] = "Pirma savaitës diena - sekmadienis";
+Calendar._TT["CLOSE"] = "Uþdaryti";
+Calendar._TT["TODAY"] = "Ðiandien";
+Calendar._TT["TIME_PART"] = "Spustelkite arba tempkite jei norite pakeisti";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
+Calendar._TT["TT_DATE_FORMAT"] = "%A, %Y-%m-%d";
+
+Calendar._TT["WK"] = "sav";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-lv.js b/WebContent/themes/default/jscalendar/lang/calendar-lv.js
new file mode 100644
index 0000000000..407699d36d
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-lv.js
@@ -0,0 +1,123 @@
+// ** I18N
+
+// Calendar LV language
+// Author: Juris Valdovskis, <juris@dc.lv>
+// Encoding: cp1257
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible. We strongly believe that
+// Unicode is the answer to a real internationalized world. Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+Calendar._DN = new Array
+("Svçtdiena",
+ "Pirmdiena",
+ "Otrdiena",
+ "Treðdiena",
+ "Ceturdiena",
+ "Piektdiena",
+ "Sestdiena",
+ "Svçtdiena");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary. We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+// Calendar._SDN_len = N; // short day name length
+// Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+Calendar._SDN = new Array
+("Sv",
+ "Pr",
+ "Ot",
+ "Tr",
+ "Ce",
+ "Pk",
+ "Se",
+ "Sv");
+
+// full month names
+Calendar._MN = new Array
+("Janvâris",
+ "Februâris",
+ "Marts",
+ "Aprîlis",
+ "Maijs",
+ "Jûnijs",
+ "Jûlijs",
+ "Augusts",
+ "Septembris",
+ "Oktobris",
+ "Novembris",
+ "Decembris");
+
+// short month names
+Calendar._SMN = new Array
+("Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "Mai",
+ "Jûn",
+ "Jûl",
+ "Aug",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Dec");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "Par kalendâru";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
+"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." +
+"\n\n" +
+"Datuma izvçle:\n" +
+"- Izmanto \xab, \xbb pogas, lai izvçlçtos gadu\n" +
+"- Izmanto " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + "pogas, lai izvçlçtos mçnesi\n" +
+"- Turi nospiestu peles pogu uz jebkuru no augstâk minçtajâm pogâm, lai paâtrinâtu izvçli.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Laika izvçle:\n" +
+"- Uzklikðíini uz jebkuru no laika daïâm, lai palielinâtu to\n" +
+"- vai Shift-klikðíis, lai samazinâtu to\n" +
+"- vai noklikðíini un velc uz attiecîgo virzienu lai mainîtu âtrâk.";
+
+Calendar._TT["PREV_YEAR"] = "Iepr. gads (turi izvçlnei)";
+Calendar._TT["PREV_MONTH"] = "Iepr. mçnesis (turi izvçlnei)";
+Calendar._TT["GO_TODAY"] = "Ðodien";
+Calendar._TT["NEXT_MONTH"] = "Nâkoðais mçnesis (turi izvçlnei)";
+Calendar._TT["NEXT_YEAR"] = "Nâkoðais gads (turi izvçlnei)";
+Calendar._TT["SEL_DATE"] = "Izvçlies datumu";
+Calendar._TT["DRAG_TO_MOVE"] = "Velc, lai pârvietotu";
+Calendar._TT["PART_TODAY"] = " (ðodien)";
+
+// the following is to inform that "%s" is to be the first day of week
+// %s will be replaced with the day name.
+Calendar._TT["DAY_FIRST"] = "Attçlot %s kâ pirmo";
+
+// This may be locale-dependent. It specifies the week-end days, as an array
+// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1
+// means Monday, etc.
+Calendar._TT["WEEKEND"] = "1,7";
+
+Calendar._TT["CLOSE"] = "Aizvçrt";
+Calendar._TT["TODAY"] = "Ðodien";
+Calendar._TT["TIME_PART"] = "(Shift-)Klikðíis vai pârvieto, lai mainîtu";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%d-%m-%Y";
+Calendar._TT["TT_DATE_FORMAT"] = "%a, %e %b";
+
+Calendar._TT["WK"] = "wk";
+Calendar._TT["TIME"] = "Laiks:";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-nl.js b/WebContent/themes/default/jscalendar/lang/calendar-nl.js
new file mode 100644
index 0000000000..a1dea94bdb
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-nl.js
@@ -0,0 +1,73 @@
+// ** I18N
+Calendar._DN = new Array
+("Zondag",
+ "Maandag",
+ "Dinsdag",
+ "Woensdag",
+ "Donderdag",
+ "Vrijdag",
+ "Zaterdag",
+ "Zondag");
+
+Calendar._SDN_len = 2;
+
+Calendar._MN = new Array
+("Januari",
+ "Februari",
+ "Maart",
+ "April",
+ "Mei",
+ "Juni",
+ "Juli",
+ "Augustus",
+ "September",
+ "Oktober",
+ "November",
+ "December");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "Info";
+
+Calendar._TT["ABOUT"] =
+"DHTML Datum/Tijd Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" +
+"Ga voor de meest recente versie naar: http://www.dynarch.com/projects/calendar/\n" +
+"Verspreid onder de GNU LGPL. Zie http://gnu.org/licenses/lgpl.html voor details." +
+"\n\n" +
+"Datum selectie:\n" +
+"- Gebruik de \xab \xbb knoppen om een jaar te selecteren\n" +
+"- Gebruik de " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " knoppen om een maand te selecteren\n" +
+"- Houd de muis ingedrukt op de genoemde knoppen voor een snellere selectie.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Tijd selectie:\n" +
+"- Klik op een willekeurig onderdeel van het tijd gedeelte om het te verhogen\n" +
+"- of Shift-klik om het te verlagen\n" +
+"- of klik en sleep voor een snellere selectie.";
+
+//Calendar._TT["TOGGLE"] = "Selecteer de eerste week-dag";
+Calendar._TT["PREV_YEAR"] = "Vorig jaar (ingedrukt voor menu)";
+Calendar._TT["PREV_MONTH"] = "Vorige maand (ingedrukt voor menu)";
+Calendar._TT["GO_TODAY"] = "Ga naar Vandaag";
+Calendar._TT["NEXT_MONTH"] = "Volgende maand (ingedrukt voor menu)";
+Calendar._TT["NEXT_YEAR"] = "Volgend jaar (ingedrukt voor menu)";
+Calendar._TT["SEL_DATE"] = "Selecteer datum";
+Calendar._TT["DRAG_TO_MOVE"] = "Klik en sleep om te verplaatsen";
+Calendar._TT["PART_TODAY"] = " (vandaag)";
+//Calendar._TT["MON_FIRST"] = "Toon Maandag eerst";
+//Calendar._TT["SUN_FIRST"] = "Toon Zondag eerst";
+
+Calendar._TT["DAY_FIRST"] = "Toon %s eerst";
+
+Calendar._TT["WEEKEND"] = "0,6";
+
+Calendar._TT["CLOSE"] = "Sluiten";
+Calendar._TT["TODAY"] = "(vandaag)";
+Calendar._TT["TIME_PART"] = "(Shift-)Klik of sleep om de waarde te veranderen";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%d-%m-%Y";
+Calendar._TT["TT_DATE_FORMAT"] = "%a, %e %b %Y";
+
+Calendar._TT["WK"] = "wk";
+Calendar._TT["TIME"] = "Tijd:"; \ No newline at end of file
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-no.js b/WebContent/themes/default/jscalendar/lang/calendar-no.js
new file mode 100644
index 0000000000..d9297d179a
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-no.js
@@ -0,0 +1,114 @@
+// ** I18N
+
+// Calendar NO language
+// Author: Daniel Holmen, <daniel.holmen@ciber.no>
+// Encoding: UTF-8
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible. We strongly believe that
+// Unicode is the answer to a real internationalized world. Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+Calendar._DN = new Array
+("Søndag",
+ "Mandag",
+ "Tirsdag",
+ "Onsdag",
+ "Torsdag",
+ "Fredag",
+ "Lørdag",
+ "Søndag");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary. We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+// Calendar._SDN_len = N; // short day name length
+// Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+Calendar._SDN = new Array
+("Søn",
+ "Man",
+ "Tir",
+ "Ons",
+ "Tor",
+ "Fre",
+ "Lør",
+ "Søn");
+
+// full month names
+Calendar._MN = new Array
+("Januar",
+ "Februar",
+ "Mars",
+ "April",
+ "Mai",
+ "Juni",
+ "Juli",
+ "August",
+ "September",
+ "Oktober",
+ "November",
+ "Desember");
+
+// short month names
+Calendar._SMN = new Array
+("Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "Mai",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Des");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "Om kalenderen";
+
+Calendar._TT["ABOUT"] =
+"DHTML Dato-/Tidsvelger\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"For nyeste versjon, gå til: http://www.dynarch.com/projects/calendar/\n" +
+"Distribuert under GNU LGPL. Se http://gnu.org/licenses/lgpl.html for detaljer." +
+"\n\n" +
+"Datovalg:\n" +
+"- Bruk knappene \xab og \xbb for å velge år\n" +
+"- Bruk knappene " + String.fromCharCode(0x2039) + " og " + String.fromCharCode(0x203a) + " for å velge måned\n" +
+"- Hold inne musknappen eller knappene over for raskere valg.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Tidsvalg:\n" +
+"- Klikk på en av tidsdelene for å øke den\n" +
+"- eller Shift-klikk for å senke verdien\n" +
+"- eller klikk-og-dra for raskere valg..";
+
+Calendar._TT["PREV_YEAR"] = "Forrige. år (hold for meny)";
+Calendar._TT["PREV_MONTH"] = "Forrige. måned (hold for meny)";
+Calendar._TT["GO_TODAY"] = "GÃ¥ til idag";
+Calendar._TT["NEXT_MONTH"] = "Neste måned (hold for meny)";
+Calendar._TT["NEXT_YEAR"] = "Neste år (hold for meny)";
+Calendar._TT["SEL_DATE"] = "Velg dato";
+Calendar._TT["DRAG_TO_MOVE"] = "Dra for å flytte";
+Calendar._TT["PART_TODAY"] = " (idag)";
+Calendar._TT["MON_FIRST"] = "Vis mandag først";
+Calendar._TT["SUN_FIRST"] = "Vis søndag først";
+Calendar._TT["CLOSE"] = "Lukk";
+Calendar._TT["TODAY"] = "Idag";
+Calendar._TT["TIME_PART"] = "(Shift-)Klikk eller dra for å endre verdi";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%d.%m.%Y";
+Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
+
+Calendar._TT["WK"] = "uke"; \ No newline at end of file
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-pl-utf8.js b/WebContent/themes/default/jscalendar/lang/calendar-pl-utf8.js
new file mode 100644
index 0000000000..6b8ca67aa2
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-pl-utf8.js
@@ -0,0 +1,93 @@
+// ** I18N
+
+// Calendar PL language
+// Author: Dariusz Pietrzak, <eyck@ghost.anime.pl>
+// Author: Janusz Piwowarski, <jpiw@go2.pl>
+// Encoding: utf-8
+// Distributed under the same terms as the calendar itself.
+
+Calendar._DN = new Array
+("Niedziela",
+ "Poniedziałek",
+ "Wtorek",
+ "Åšroda",
+ "Czwartek",
+ "PiÄ…tek",
+ "Sobota",
+ "Niedziela");
+Calendar._SDN = new Array
+("Nie",
+ "Pn",
+ "Wt",
+ "Åšr",
+ "Cz",
+ "Pt",
+ "So",
+ "Nie");
+Calendar._MN = new Array
+("Styczeń",
+ "Luty",
+ "Marzec",
+ "Kwiecień",
+ "Maj",
+ "Czerwiec",
+ "Lipiec",
+ "Sierpień",
+ "Wrzesień",
+ "Październik",
+ "Listopad",
+ "Grudzień");
+Calendar._SMN = new Array
+("Sty",
+ "Lut",
+ "Mar",
+ "Kwi",
+ "Maj",
+ "Cze",
+ "Lip",
+ "Sie",
+ "Wrz",
+ "Paź",
+ "Lis",
+ "Gru");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "O kalendarzu";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"Aby pobrać najnowszą wersję, odwiedź: http://www.dynarch.com/projects/calendar/\n" +
+"Dostępny na licencji GNU LGPL. Zobacz szczegóły na http://gnu.org/licenses/lgpl.html." +
+"\n\n" +
+"Wybór daty:\n" +
+"- Użyj przycisków \xab, \xbb by wybrać rok\n" +
+"- Użyj przycisków " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " by wybrać miesiąc\n" +
+"- Przytrzymaj klawisz myszy nad jednym z powyższych przycisków dla szybszego wyboru.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Wybór czasu:\n" +
+"- Kliknij na jednym z pól czasu by zwiększyć jego wartość\n" +
+"- lub kliknij trzymając Shift by zmiejszyć jego wartość\n" +
+"- lub kliknij i przeciÄ…gnij dla szybszego wyboru.";
+
+//Calendar._TT["TOGGLE"] = "Zmień pierwszy dzień tygodnia";
+Calendar._TT["PREV_YEAR"] = "Poprzedni rok (przytrzymaj dla menu)";
+Calendar._TT["PREV_MONTH"] = "Poprzedni miesiÄ…c (przytrzymaj dla menu)";
+Calendar._TT["GO_TODAY"] = "Idź do dzisiaj";
+Calendar._TT["NEXT_MONTH"] = "Następny miesiąc (przytrzymaj dla menu)";
+Calendar._TT["NEXT_YEAR"] = "Następny rok (przytrzymaj dla menu)";
+Calendar._TT["SEL_DATE"] = "Wybierz datÄ™";
+Calendar._TT["DRAG_TO_MOVE"] = "Przeciągnij by przesunąć";
+Calendar._TT["PART_TODAY"] = " (dzisiaj)";
+Calendar._TT["MON_FIRST"] = "Wyświetl poniedziałek jako pierwszy";
+Calendar._TT["SUN_FIRST"] = "Wyświetl niedzielę jako pierwszą";
+Calendar._TT["CLOSE"] = "Zamknij";
+Calendar._TT["TODAY"] = "Dzisiaj";
+Calendar._TT["TIME_PART"] = "(Shift-)Kliknij lub przeciągnij by zmienić wartość";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
+Calendar._TT["TT_DATE_FORMAT"] = "%e %B, %A";
+
+Calendar._TT["WK"] = "ty";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-pl.js b/WebContent/themes/default/jscalendar/lang/calendar-pl.js
new file mode 100644
index 0000000000..76e0551ab6
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-pl.js
@@ -0,0 +1,56 @@
+// ** I18N
+// Calendar PL language
+// Author: Artur Filipiak, <imagen@poczta.fm>
+// January, 2004
+// Encoding: UTF-8
+Calendar._DN = new Array
+("Niedziela", "Poniedziałek", "Wtorek", "Środa", "Czwartek", "Piątek", "Sobota", "Niedziela");
+
+Calendar._SDN = new Array
+("N", "Pn", "Wt", "Åšr", "Cz", "Pt", "So", "N");
+
+Calendar._MN = new Array
+("Styczeń", "Luty", "Marzec", "Kwiecień", "Maj", "Czerwiec", "Lipiec", "Sierpień", "Wrzesień", "Październik", "Listopad", "Grudzień");
+
+Calendar._SMN = new Array
+("Sty", "Lut", "Mar", "Kwi", "Maj", "Cze", "Lip", "Sie", "Wrz", "Paź", "Lis", "Gru");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "O kalendarzu";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
+"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." +
+"\n\n" +
+"Wybór daty:\n" +
+"- aby wybrać rok użyj przycisków \xab, \xbb\n" +
+"- aby wybrać miesiąc użyj przycisków " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + "\n" +
+"- aby przyspieszyć wybór przytrzymaj wciśnięty przycisk myszy nad ww. przyciskami.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Wybór czasu:\n" +
+"- aby zwiększyć wartość kliknij na dowolnym elemencie selekcji czasu\n" +
+"- aby zmniejszyć wartość użyj dodatkowo klawisza Shift\n" +
+"- możesz również poruszać myszkę w lewo i prawo wraz z wciśniętym lewym klawiszem.";
+
+Calendar._TT["PREV_YEAR"] = "Poprz. rok (przytrzymaj dla menu)";
+Calendar._TT["PREV_MONTH"] = "Poprz. miesiÄ…c (przytrzymaj dla menu)";
+Calendar._TT["GO_TODAY"] = "Pokaż dziś";
+Calendar._TT["NEXT_MONTH"] = "Nast. miesiÄ…c (przytrzymaj dla menu)";
+Calendar._TT["NEXT_YEAR"] = "Nast. rok (przytrzymaj dla menu)";
+Calendar._TT["SEL_DATE"] = "Wybierz datÄ™";
+Calendar._TT["DRAG_TO_MOVE"] = "Przesuń okienko";
+Calendar._TT["PART_TODAY"] = " (dziÅ›)";
+Calendar._TT["MON_FIRST"] = "Pokaż Poniedziałek jako pierwszy";
+Calendar._TT["SUN_FIRST"] = "Pokaż Niedzielę jako pierwszą";
+Calendar._TT["CLOSE"] = "Zamknij";
+Calendar._TT["TODAY"] = "DziÅ›";
+Calendar._TT["TIME_PART"] = "(Shift-)klik | drag, aby zmienić wartość";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%Y.%m.%d";
+Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
+
+Calendar._TT["WK"] = "wk"; \ No newline at end of file
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-pt.js b/WebContent/themes/default/jscalendar/lang/calendar-pt.js
new file mode 100644
index 0000000000..deee8a19ed
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-pt.js
@@ -0,0 +1,123 @@
+// ** I18N
+
+// Calendar pt_BR language
+// Author: Adalberto Machado, <betosm@terra.com.br>
+// Encoding: any
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible. We strongly believe that
+// Unicode is the answer to a real internationalized world. Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+Calendar._DN = new Array
+("Domingo",
+ "Segunda",
+ "Terca",
+ "Quarta",
+ "Quinta",
+ "Sexta",
+ "Sabado",
+ "Domingo");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary. We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+// Calendar._SDN_len = N; // short day name length
+// Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+Calendar._SDN = new Array
+("Dom",
+ "Seg",
+ "Ter",
+ "Qua",
+ "Qui",
+ "Sex",
+ "Sab",
+ "Dom");
+
+// full month names
+Calendar._MN = new Array
+("Janeiro",
+ "Fevereiro",
+ "Marco",
+ "Abril",
+ "Maio",
+ "Junho",
+ "Julho",
+ "Agosto",
+ "Setembro",
+ "Outubro",
+ "Novembro",
+ "Dezembro");
+
+// short month names
+Calendar._SMN = new Array
+("Jan",
+ "Fev",
+ "Mar",
+ "Abr",
+ "Mai",
+ "Jun",
+ "Jul",
+ "Ago",
+ "Set",
+ "Out",
+ "Nov",
+ "Dez");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "Sobre o calendario";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"Ultima versao visite: http://www.dynarch.com/projects/calendar/\n" +
+"Distribuido sobre GNU LGPL. Veja http://gnu.org/licenses/lgpl.html para detalhes." +
+"\n\n" +
+"Selecao de data:\n" +
+"- Use os botoes \xab, \xbb para selecionar o ano\n" +
+"- Use os botoes " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " para selecionar o mes\n" +
+"- Segure o botao do mouse em qualquer um desses botoes para selecao rapida.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Selecao de hora:\n" +
+"- Clique em qualquer parte da hora para incrementar\n" +
+"- ou Shift-click para decrementar\n" +
+"- ou clique e segure para selecao rapida.";
+
+Calendar._TT["PREV_YEAR"] = "Ant. ano (segure para menu)";
+Calendar._TT["PREV_MONTH"] = "Ant. mes (segure para menu)";
+Calendar._TT["GO_TODAY"] = "Hoje";
+Calendar._TT["NEXT_MONTH"] = "Prox. mes (segure para menu)";
+Calendar._TT["NEXT_YEAR"] = "Prox. ano (segure para menu)";
+Calendar._TT["SEL_DATE"] = "Selecione a data";
+Calendar._TT["DRAG_TO_MOVE"] = "Arraste para mover";
+Calendar._TT["PART_TODAY"] = " (hoje)";
+
+// the following is to inform that "%s" is to be the first day of week
+// %s will be replaced with the day name.
+Calendar._TT["DAY_FIRST"] = "Mostre %s primeiro";
+
+// This may be locale-dependent. It specifies the week-end days, as an array
+// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1
+// means Monday, etc.
+Calendar._TT["WEEKEND"] = "0,6";
+
+Calendar._TT["CLOSE"] = "Fechar";
+Calendar._TT["TODAY"] = "Hoje";
+Calendar._TT["TIME_PART"] = "(Shift-)Click ou arraste para mudar valor";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%d/%m/%Y";
+Calendar._TT["TT_DATE_FORMAT"] = "%a, %e %b";
+
+Calendar._TT["WK"] = "sm";
+Calendar._TT["TIME"] = "Hora:";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-ro.js b/WebContent/themes/default/jscalendar/lang/calendar-ro.js
new file mode 100644
index 0000000000..116e358ba2
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-ro.js
@@ -0,0 +1,66 @@
+// ** I18N
+Calendar._DN = new Array
+("Duminică",
+ "Luni",
+ "Marţi",
+ "Miercuri",
+ "Joi",
+ "Vineri",
+ "Sâmbătă",
+ "Duminică");
+Calendar._SDN_len = 2;
+Calendar._MN = new Array
+("Ianuarie",
+ "Februarie",
+ "Martie",
+ "Aprilie",
+ "Mai",
+ "Iunie",
+ "Iulie",
+ "August",
+ "Septembrie",
+ "Octombrie",
+ "Noiembrie",
+ "Decembrie");
+
+// tooltips
+Calendar._TT = {};
+
+Calendar._TT["INFO"] = "Despre calendar";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"Pentru ultima versiune vizitaţi: http://www.dynarch.com/projects/calendar/\n" +
+"Distribuit sub GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." +
+"\n\n" +
+"Selecţia datei:\n" +
+"- Folosiţi butoanele \xab, \xbb pentru a selecta anul\n" +
+"- Folosiţi butoanele " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " pentru a selecta luna\n" +
+"- Tineţi butonul mouse-ului apăsat pentru selecţie mai rapidă.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Selecţia orei:\n" +
+"- Click pe ora sau minut pentru a mări valoarea cu 1\n" +
+"- Sau Shift-Click pentru a micÅŸora valoarea cu 1\n" +
+"- Sau Click ÅŸi drag pentru a selecta mai repede.";
+
+Calendar._TT["PREV_YEAR"] = "Anul precedent (lung pt menu)";
+Calendar._TT["PREV_MONTH"] = "Luna precedentă (lung pt menu)";
+Calendar._TT["GO_TODAY"] = "Data de azi";
+Calendar._TT["NEXT_MONTH"] = "Luna următoare (lung pt menu)";
+Calendar._TT["NEXT_YEAR"] = "Anul următor (lung pt menu)";
+Calendar._TT["SEL_DATE"] = "Selectează data";
+Calendar._TT["DRAG_TO_MOVE"] = "Trage pentru a miÅŸca";
+Calendar._TT["PART_TODAY"] = " (astăzi)";
+Calendar._TT["DAY_FIRST"] = "Afişează %s prima zi";
+Calendar._TT["WEEKEND"] = "0,6";
+Calendar._TT["CLOSE"] = "ÃŽnchide";
+Calendar._TT["TODAY"] = "Astăzi";
+Calendar._TT["TIME_PART"] = "(Shift-)Click sau drag pentru a selecta";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%d-%m-%Y";
+Calendar._TT["TT_DATE_FORMAT"] = "%A, %d %B";
+
+Calendar._TT["WK"] = "spt";
+Calendar._TT["TIME"] = "Ora:";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-ru.js b/WebContent/themes/default/jscalendar/lang/calendar-ru.js
new file mode 100644
index 0000000000..9f75a6a432
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-ru.js
@@ -0,0 +1,123 @@
+// ** I18N
+
+// Calendar RU language
+// Translation: Sly Golovanov, http://golovanov.net, <sly@golovanov.net>
+// Encoding: any
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible. We strongly believe that
+// Unicode is the answer to a real internationalized world. Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+Calendar._DN = new Array
+("воÑкреÑенье",
+ "понедельник",
+ "вторник",
+ "Ñреда",
+ "четверг",
+ "пÑтница",
+ "Ñуббота",
+ "воÑкреÑенье");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary. We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+// Calendar._SDN_len = N; // short day name length
+// Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+Calendar._SDN = new Array
+("вÑк",
+ "пон",
+ "втр",
+ "Ñрд",
+ "чет",
+ "пÑÑ‚",
+ "Ñуб",
+ "вÑк");
+
+// full month names
+Calendar._MN = new Array
+("Ñнварь",
+ "февраль",
+ "март",
+ "апрель",
+ "май",
+ "июнь",
+ "июль",
+ "авгуÑÑ‚",
+ "ÑентÑбрь",
+ "октÑбрь",
+ "ноÑбрь",
+ "декабрь");
+
+// short month names
+Calendar._SMN = new Array
+("Ñнв",
+ "фев",
+ "мар",
+ "апр",
+ "май",
+ "июн",
+ "июл",
+ "авг",
+ "Ñен",
+ "окт",
+ "ноÑ",
+ "дек");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "О календаре...";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
+"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." +
+"\n\n" +
+"Как выбрать дату:\n" +
+"- При помощи кнопок \xab, \xbb можно выбрать год\n" +
+"- При помощи кнопок " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " можно выбрать меÑÑц\n" +
+"- Подержите Ñти кнопки нажатыми, чтобы поÑвилоÑÑŒ меню быÑтрого выбора.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Как выбрать времÑ:\n" +
+"- При клике на чаÑах или минутах они увеличиваютÑÑ\n" +
+"- при клике Ñ Ð½Ð°Ð¶Ð°Ñ‚Ð¾Ð¹ клавишей Shift они уменьшаютÑÑ\n" +
+"- еÑли нажать и двигать мышкой влево/вправо, они будут менÑÑ‚ÑŒÑÑ Ð±Ñ‹Ñтрее.";
+
+Calendar._TT["PREV_YEAR"] = "Ðа год назад (удерживать Ð´Ð»Ñ Ð¼ÐµÐ½ÑŽ)";
+Calendar._TT["PREV_MONTH"] = "Ðа меÑÑц назад (удерживать Ð´Ð»Ñ Ð¼ÐµÐ½ÑŽ)";
+Calendar._TT["GO_TODAY"] = "СегоднÑ";
+Calendar._TT["NEXT_MONTH"] = "Ðа меÑÑц вперед (удерживать Ð´Ð»Ñ Ð¼ÐµÐ½ÑŽ)";
+Calendar._TT["NEXT_YEAR"] = "Ðа год вперед (удерживать Ð´Ð»Ñ Ð¼ÐµÐ½ÑŽ)";
+Calendar._TT["SEL_DATE"] = "Выберите дату";
+Calendar._TT["DRAG_TO_MOVE"] = "ПеретаÑкивайте мышкой";
+Calendar._TT["PART_TODAY"] = " (ÑегоднÑ)";
+
+// the following is to inform that "%s" is to be the first day of week
+// %s will be replaced with the day name.
+Calendar._TT["DAY_FIRST"] = "Первый день недели будет %s";
+
+// This may be locale-dependent. It specifies the week-end days, as an array
+// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1
+// means Monday, etc.
+Calendar._TT["WEEKEND"] = "0,6";
+
+Calendar._TT["CLOSE"] = "Закрыть";
+Calendar._TT["TODAY"] = "СегоднÑ";
+Calendar._TT["TIME_PART"] = "(Shift-)клик или нажать и двигать";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
+Calendar._TT["TT_DATE_FORMAT"] = "%e %b, %a";
+
+Calendar._TT["WK"] = "нед";
+Calendar._TT["TIME"] = "ВремÑ:";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-ru_win_.js b/WebContent/themes/default/jscalendar/lang/calendar-ru_win_.js
new file mode 100644
index 0000000000..de455afa08
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-ru_win_.js
@@ -0,0 +1,123 @@
+// ** I18N
+
+// Calendar RU language
+// Translation: Sly Golovanov, http://golovanov.net, <sly@golovanov.net>
+// Encoding: any
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible. We strongly believe that
+// Unicode is the answer to a real internationalized world. Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+Calendar._DN = new Array
+("âîñêðåñåíüå",
+ "ïîíåäåëüíèê",
+ "âòîðíèê",
+ "ñðåäà",
+ "÷åòâåðã",
+ "ïÿòíèöà",
+ "ñóááîòà",
+ "âîñêðåñåíüå");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary. We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+// Calendar._SDN_len = N; // short day name length
+// Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+Calendar._SDN = new Array
+("âñê",
+ "ïîí",
+ "âòð",
+ "ñðä",
+ "÷åò",
+ "ïÿò",
+ "ñóá",
+ "âñê");
+
+// full month names
+Calendar._MN = new Array
+("ÿíâàðü",
+ "ôåâðàëü",
+ "ìàðò",
+ "àïðåëü",
+ "ìàé",
+ "èþíü",
+ "èþëü",
+ "àâãóñò",
+ "ñåíòÿáðü",
+ "îêòÿáðü",
+ "íîÿáðü",
+ "äåêàáðü");
+
+// short month names
+Calendar._SMN = new Array
+("ÿíâ",
+ "ôåâ",
+ "ìàð",
+ "àïð",
+ "ìàé",
+ "èþí",
+ "èþë",
+ "àâã",
+ "ñåí",
+ "îêò",
+ "íîÿ",
+ "äåê");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "Î êàëåíäàðå...";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
+"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." +
+"\n\n" +
+"Êàê âûáðàòü äàòó:\n" +
+"- Ïðè ïîìîùè êíîïîê \xab, \xbb ìîæíî âûáðàòü ãîä\n" +
+"- Ïðè ïîìîùè êíîïîê " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " ìîæíî âûáðàòü ìåñÿö\n" +
+"- Ïîäåðæèòå ýòè êíîïêè íàæàòûìè, ÷òîáû ïîÿâèëîñü ìåíþ áûñòðîãî âûáîðà.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Êàê âûáðàòü âðåìÿ:\n" +
+"- Ïðè êëèêå íà ÷àñàõ èëè ìèíóòàõ îíè óâåëè÷èâàþòñÿ\n" +
+"- ïðè êëèêå ñ íàæàòîé êëàâèøåé Shift îíè óìåíüøàþòñÿ\n" +
+"- åñëè íàæàòü è äâèãàòü ìûøêîé âëåâî/âïðàâî, îíè áóäóò ìåíÿòüñÿ áûñòðåå.";
+
+Calendar._TT["PREV_YEAR"] = "Íà ãîä íàçàä (óäåðæèâàòü äëÿ ìåíþ)";
+Calendar._TT["PREV_MONTH"] = "Íà ìåñÿö íàçàä (óäåðæèâàòü äëÿ ìåíþ)";
+Calendar._TT["GO_TODAY"] = "Ñåãîäíÿ";
+Calendar._TT["NEXT_MONTH"] = "Íà ìåñÿö âïåðåä (óäåðæèâàòü äëÿ ìåíþ)";
+Calendar._TT["NEXT_YEAR"] = "Íà ãîä âïåðåä (óäåðæèâàòü äëÿ ìåíþ)";
+Calendar._TT["SEL_DATE"] = "Âûáåðèòå äàòó";
+Calendar._TT["DRAG_TO_MOVE"] = "Ïåðåòàñêèâàéòå ìûøêîé";
+Calendar._TT["PART_TODAY"] = " (ñåãîäíÿ)";
+
+// the following is to inform that "%s" is to be the first day of week
+// %s will be replaced with the day name.
+Calendar._TT["DAY_FIRST"] = "Ïåðâûé äåíü íåäåëè áóäåò %s";
+
+// This may be locale-dependent. It specifies the week-end days, as an array
+// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1
+// means Monday, etc.
+Calendar._TT["WEEKEND"] = "0,6";
+
+Calendar._TT["CLOSE"] = "Çàêðûòü";
+Calendar._TT["TODAY"] = "Ñåãîäíÿ";
+Calendar._TT["TIME_PART"] = "(Shift-)êëèê èëè íàæàòü è äâèãàòü";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
+Calendar._TT["TT_DATE_FORMAT"] = "%e %b, %a";
+
+Calendar._TT["WK"] = "íåä";
+Calendar._TT["TIME"] = "Âðåìÿ:";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-si.js b/WebContent/themes/default/jscalendar/lang/calendar-si.js
new file mode 100644
index 0000000000..100c522e4d
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-si.js
@@ -0,0 +1,94 @@
+/* Slovenian language file for the DHTML Calendar version 0.9.2
+* Author David Milost <mercy@volja.net>, January 2004.
+* Feel free to use this script under the terms of the GNU Lesser General
+* Public License, as long as you do not remove or alter this notice.
+*/
+ // full day names
+Calendar._DN = new Array
+("Nedelja",
+ "Ponedeljek",
+ "Torek",
+ "Sreda",
+ "ÄŒetrtek",
+ "Petek",
+ "Sobota",
+ "Nedelja");
+ // short day names
+ Calendar._SDN = new Array
+("Ned",
+ "Pon",
+ "Tor",
+ "Sre",
+ "ÄŒet",
+ "Pet",
+ "Sob",
+ "Ned");
+// short month names
+Calendar._SMN = new Array
+("Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "Maj",
+ "Jun",
+ "Jul",
+ "Avg",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Dec");
+ // full month names
+Calendar._MN = new Array
+("Januar",
+ "Februar",
+ "Marec",
+ "April",
+ "Maj",
+ "Junij",
+ "Julij",
+ "Avgust",
+ "September",
+ "Oktober",
+ "November",
+ "December");
+
+// tooltips
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "O koledarju";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"Za zadnjo verzijo pojdine na naslov: http://www.dynarch.com/projects/calendar/\n" +
+"Distribuirano pod GNU LGPL. Poglejte http://gnu.org/licenses/lgpl.html za podrobnosti." +
+"\n\n" +
+"Izbor datuma:\n" +
+"- Uporabite \xab, \xbb gumbe za izbor leta\n" +
+"- Uporabite " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " gumbe za izbor meseca\n" +
+"- Zadržite klik na kateremkoli od zgornjih gumbov za hiter izbor.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Izbor ćasa:\n" +
+"- Kliknite na katerikoli del ćasa za poveć. le-tega\n" +
+"- ali Shift-click za zmanj. le-tega\n" +
+"- ali kliknite in povlecite za hiter izbor.";
+
+Calendar._TT["TOGGLE"] = "Spremeni dan s katerim se prićne teden";
+Calendar._TT["PREV_YEAR"] = "Predhodnje leto (dolg klik za meni)";
+Calendar._TT["PREV_MONTH"] = "Predhodnji mesec (dolg klik za meni)";
+Calendar._TT["GO_TODAY"] = "Pojdi na tekoći dan";
+Calendar._TT["NEXT_MONTH"] = "Naslednji mesec (dolg klik za meni)";
+Calendar._TT["NEXT_YEAR"] = "Naslednje leto (dolg klik za meni)";
+Calendar._TT["SEL_DATE"] = "Izberite datum";
+Calendar._TT["DRAG_TO_MOVE"] = "Pritisni in povleci za spremembo pozicije";
+Calendar._TT["PART_TODAY"] = " (danes)";
+Calendar._TT["MON_FIRST"] = "Prikaži ponedeljek kot prvi dan";
+Calendar._TT["SUN_FIRST"] = "Prikaži nedeljo kot prvi dan";
+Calendar._TT["CLOSE"] = "Zapri";
+Calendar._TT["TODAY"] = "Danes";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
+Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
+
+Calendar._TT["WK"] = "Ted"; \ No newline at end of file
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-sk.js b/WebContent/themes/default/jscalendar/lang/calendar-sk.js
new file mode 100644
index 0000000000..4fe6a3c8bb
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-sk.js
@@ -0,0 +1,99 @@
+// ** I18N
+
+// Calendar SK language
+// Author: Peter Valach (pvalach@gmx.net)
+// Encoding: utf-8
+// Last update: 2003/10/29
+// Distributed under the same terms as the calendar itself.
+
+// full day names
+Calendar._DN = new Array
+("NedeÄľa",
+ "Pondelok",
+ "Utorok",
+ "Streda",
+ "Ĺ tvrtok",
+ "Piatok",
+ "Sobota",
+ "NedeÄľa");
+
+// short day names
+Calendar._SDN = new Array
+("Ned",
+ "Pon",
+ "Uto",
+ "Str",
+ "Ĺ tv",
+ "Pia",
+ "Sob",
+ "Ned");
+
+// full month names
+Calendar._MN = new Array
+("Január",
+ "Február",
+ "Marec",
+ "AprĂ­l",
+ "Máj",
+ "JÄ‚ÅŸn",
+ "JÄ‚ÅŸl",
+ "August",
+ "September",
+ "OktĂłber",
+ "November",
+ "December");
+
+// short month names
+Calendar._SMN = new Array
+("Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "Máj",
+ "JÄ‚ÅŸn",
+ "JÄ‚ÅŸl",
+ "Aug",
+ "Sep",
+ "Okt",
+ "Nov",
+ "Dec");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "O kalendári";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" +
+"Poslednú verziu nájdete na: http://www.dynarch.com/projects/calendar/\n" +
+"Distribuované pod GNU LGPL. Viď http://gnu.org/licenses/lgpl.html pre detaily." +
+"\n\n" +
+"VÄ‚Ëber dátumu:\n" +
+"- PouĹľite tlaÄŤidlá \xab, \xbb pre vÄ‚Ëber roku\n" +
+"- PouĹľite tlaÄŤidlá " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " pre vÄ‚Ëber mesiaca\n" +
+"- Ak ktorĂ©koÄľvek z tÄ‚Ëchto tlaÄŤidiel podržíte dlhšie, zobrazĂ­ sa rÄ‚Ëchly vÄ‚Ëber.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"VÄ‚Ëber ÄŤasu:\n" +
+"- Kliknutie na niektorÄ‚ÅŸ poloĹľku ÄŤasu ju zvÄ‚Ëši\n" +
+"- Shift-klik ju znĂ­Ĺľi\n" +
+"- Ak podržíte tlačítko stlačené, posúvaním meníte hodnotu.";
+
+Calendar._TT["PREV_YEAR"] = "PredošlÄ‚Ë rok (podrĹľte pre menu)";
+Calendar._TT["PREV_MONTH"] = "PredošlÄ‚Ë mesiac (podrĹľte pre menu)";
+Calendar._TT["GO_TODAY"] = "Prejsť na dnešok";
+Calendar._TT["NEXT_MONTH"] = "Nasl. mesiac (podrĹľte pre menu)";
+Calendar._TT["NEXT_YEAR"] = "Nasl. rok (podrĹľte pre menu)";
+Calendar._TT["SEL_DATE"] = "Zvoľte dátum";
+Calendar._TT["DRAG_TO_MOVE"] = "PodrĹľanĂ­m tlaÄŤĂ­tka zmenĂ­te polohu";
+Calendar._TT["PART_TODAY"] = " (dnes)";
+Calendar._TT["MON_FIRST"] = "ZobraziĹĄ pondelok ako prvÄ‚Ë";
+Calendar._TT["SUN_FIRST"] = "ZobraziĹĄ nedeÄľu ako prvĂş";
+Calendar._TT["CLOSE"] = "ZavrieĹĄ";
+Calendar._TT["TODAY"] = "Dnes";
+Calendar._TT["TIME_PART"] = "(Shift-)klik/ĹĄahanie zmenĂ­ hodnotu";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "$d. %m. %Y";
+Calendar._TT["TT_DATE_FORMAT"] = "%a, %e. %b";
+
+Calendar._TT["WK"] = "tÄ‚ËĹľ";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-sp.js b/WebContent/themes/default/jscalendar/lang/calendar-sp.js
new file mode 100644
index 0000000000..239d1b3be9
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-sp.js
@@ -0,0 +1,110 @@
+// ** I18N
+
+// Calendar SP language
+// Author: Rafael Velasco <rvu_at_idecnet_dot_com>
+// Encoding: any
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible. We strongly believe that
+// Unicode is the answer to a real internationalized world. Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+Calendar._DN = new Array
+("Domingo",
+ "Lunes",
+ "Martes",
+ "Miercoles",
+ "Jueves",
+ "Viernes",
+ "Sabado",
+ "Domingo");
+
+Calendar._SDN = new Array
+("Dom",
+ "Lun",
+ "Mar",
+ "Mie",
+ "Jue",
+ "Vie",
+ "Sab",
+ "Dom");
+
+// full month names
+Calendar._MN = new Array
+("Enero",
+ "Febrero",
+ "Marzo",
+ "Abril",
+ "Mayo",
+ "Junio",
+ "Julio",
+ "Agosto",
+ "Septiembre",
+ "Octubre",
+ "Noviembre",
+ "Diciembre");
+
+// short month names
+Calendar._SMN = new Array
+("Ene",
+ "Feb",
+ "Mar",
+ "Abr",
+ "May",
+ "Jun",
+ "Jul",
+ "Ago",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dic");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "Información del Calendario";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"Nuevas versiones en: http://www.dynarch.com/projects/calendar/\n" +
+"Distribuida bajo licencia GNU LGPL. Para detalles vea http://gnu.org/licenses/lgpl.html ." +
+"\n\n" +
+"Selección de Fechas:\n" +
+"- Use \xab, \xbb para seleccionar el año\n" +
+"- Use " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " para seleccionar el mes\n" +
+"- Mantenga presionado el botón del ratón en cualquiera de las opciones superiores para un acceso rapido .";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Selección del Reloj:\n" +
+"- Seleccione la hora para cambiar el reloj\n" +
+"- o presione Shift-click para disminuirlo\n" +
+"- o presione click y arrastre del ratón para una selección rapida.";
+
+Calendar._TT["PREV_YEAR"] = "Año anterior (Presione para menu)";
+Calendar._TT["PREV_MONTH"] = "Mes Anterior (Presione para menu)";
+Calendar._TT["GO_TODAY"] = "Ir a Hoy";
+Calendar._TT["NEXT_MONTH"] = "Mes Siguiente (Presione para menu)";
+Calendar._TT["NEXT_YEAR"] = "Año Siguiente (Presione para menu)";
+Calendar._TT["SEL_DATE"] = "Seleccione fecha";
+Calendar._TT["DRAG_TO_MOVE"] = "Arrastre y mueva";
+Calendar._TT["PART_TODAY"] = " (Hoy)";
+
+// the following is to inform that "%s" is to be the first day of week
+// %s will be replaced with the day name.
+Calendar._TT["DAY_FIRST"] = "Mostrar %s primero";
+
+// This may be locale-dependent. It specifies the week-end days, as an array
+// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1
+// means Monday, etc.
+Calendar._TT["WEEKEND"] = "0,6";
+
+Calendar._TT["CLOSE"] = "Cerrar";
+Calendar._TT["TODAY"] = "Hoy";
+Calendar._TT["TIME_PART"] = "(Shift-)Click o arrastra para cambar el valor";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%dd-%mm-%yy";
+Calendar._TT["TT_DATE_FORMAT"] = "%A, %e de %B de %Y";
+
+Calendar._TT["WK"] = "Sm";
+Calendar._TT["TIME"] = "Hora:";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-sv.js b/WebContent/themes/default/jscalendar/lang/calendar-sv.js
new file mode 100644
index 0000000000..55015b3f99
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-sv.js
@@ -0,0 +1,113 @@
+// ** I18N
+
+// Calendar SV language (Swedish, svenska)
+// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
+// Translation team: <sv@li.org>
+// Translator: Leonard Norrgård <leonard.norrgard@refactor.fi>
+// Last translator: Leonard Norrgård <leonard.norrgard@refactor.fi>
+// Encoding: iso-latin-1
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible. We strongly believe that
+// Unicode is the answer to a real internationalized world. Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+Calendar._DN = new Array
+("söndag",
+ "måndag",
+ "tisdag",
+ "onsdag",
+ "torsdag",
+ "fredag",
+ "lördag",
+ "söndag");
+
+Calendar._SDN = new Array
+("Sö",
+ "MÃ¥",
+ "Ti",
+ "On",
+ "To",
+ "Fr",
+ "Lö",
+ "Sö");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary. We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+// Calendar._SDN_len = N; // short day name length
+// Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+Calendar._SDN_len = 2;
+Calendar._SMN_len = 3;
+
+// full month names
+Calendar._MN = new Array
+("januari",
+ "februari",
+ "mars",
+ "april",
+ "maj",
+ "juni",
+ "juli",
+ "augusti",
+ "september",
+ "oktober",
+ "november",
+ "december");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "Om kalendern";
+
+Calendar._TT["ABOUT"] =
+"DHTML Datum/tid-väljare\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"För senaste version gå till: http://www.dynarch.com/projects/calendar/\n" +
+"Distribueras under GNU LGPL. Se http://gnu.org/licenses/lgpl.html för detaljer." +
+"\n\n" +
+"Val av datum:\n" +
+"- Använd knapparna \xab, \xbb för att välja år\n" +
+"- Använd knapparna " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " för att välja månad\n" +
+"- Håll musknappen nedtryckt på någon av ovanstående knappar för snabbare val.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Val av tid:\n" +
+"- Klicka på en del av tiden för att öka den delen\n" +
+"- eller skift-klicka för att minska den\n" +
+"- eller klicka och drag för snabbare val.";
+
+Calendar._TT["PREV_YEAR"] = "Föregående år (håll för meny)";
+Calendar._TT["PREV_MONTH"] = "Föregående månad (håll för meny)";
+Calendar._TT["GO_TODAY"] = "GÃ¥ till dagens datum";
+Calendar._TT["NEXT_MONTH"] = "Följande månad (håll för meny)";
+Calendar._TT["NEXT_YEAR"] = "Följande år (håll för meny)";
+Calendar._TT["SEL_DATE"] = "Välj datum";
+Calendar._TT["DRAG_TO_MOVE"] = "Drag för att flytta";
+Calendar._TT["PART_TODAY"] = " (idag)";
+Calendar._TT["MON_FIRST"] = "Visa måndag först";
+Calendar._TT["SUN_FIRST"] = "Visa söndag först";
+Calendar._TT["CLOSE"] = "Stäng";
+Calendar._TT["TODAY"] = "Idag";
+Calendar._TT["TIME_PART"] = "(Skift-)klicka eller drag för att ändra tid";
+
+// the following is to inform that "%s" is to be the first day of week
+// %s will be replaced with the day name.
+Calendar._TT["DAY_FIRST"] = "Visa %s först";
+
+// This may be locale-dependent. It specifies the week-end days, as an array
+// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1
+// means Monday, etc.
+Calendar._TT["WEEKEND"] = "0,6";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
+Calendar._TT["TT_DATE_FORMAT"] = "%A %d %b %Y";
+
+Calendar._TT["WK"] = "vecka";
+Calendar._TT["TIME"] = "Tid:";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-tr.js b/WebContent/themes/default/jscalendar/lang/calendar-tr.js
new file mode 100644
index 0000000000..f2c906c46c
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-tr.js
@@ -0,0 +1,58 @@
+//////////////////////////////////////////////////////////////////////////////////////////////
+// Turkish Translation by Nuri AKMAN
+// Location: Ankara/TURKEY
+// e-mail : nuriakman@hotmail.com
+// Date : April, 9 2003
+//
+// Note: if Turkish Characters does not shown on you screen
+// please include falowing line your html code:
+//
+// <meta http-equiv="Content-Type" content="text/html; charset=windows-1254">
+//
+//////////////////////////////////////////////////////////////////////////////////////////////
+
+// ** I18N
+Calendar._DN = new Array
+("Pazar",
+ "Pazartesi",
+ "Salý",
+ "Çarþamba",
+ "Perþembe",
+ "Cuma",
+ "Cumartesi",
+ "Pazar");
+Calendar._MN = new Array
+("Ocak",
+ "Þubat",
+ "Mart",
+ "Nisan",
+ "Mayýs",
+ "Haziran",
+ "Temmuz",
+ "Aðustos",
+ "Eylül",
+ "Ekim",
+ "Kasým",
+ "Aralýk");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["TOGGLE"] = "Haftanýn ilk gününü kaydýr";
+Calendar._TT["PREV_YEAR"] = "Önceki Yýl (Menü için basýlý tutunuz)";
+Calendar._TT["PREV_MONTH"] = "Önceki Ay (Menü için basýlý tutunuz)";
+Calendar._TT["GO_TODAY"] = "Bugün'e git";
+Calendar._TT["NEXT_MONTH"] = "Sonraki Ay (Menü için basýlý tutunuz)";
+Calendar._TT["NEXT_YEAR"] = "Sonraki Yýl (Menü için basýlý tutunuz)";
+Calendar._TT["SEL_DATE"] = "Tarih seçiniz";
+Calendar._TT["DRAG_TO_MOVE"] = "Taþýmak için sürükleyiniz";
+Calendar._TT["PART_TODAY"] = " (bugün)";
+Calendar._TT["MON_FIRST"] = "Takvim Pazartesi gününden baþlasýn";
+Calendar._TT["SUN_FIRST"] = "Takvim Pazar gününden baþlasýn";
+Calendar._TT["CLOSE"] = "Kapat";
+Calendar._TT["TODAY"] = "Bugün";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "dd-mm-y";
+Calendar._TT["TT_DATE_FORMAT"] = "d MM y, DD";
+
+Calendar._TT["WK"] = "Hafta";
diff --git a/WebContent/themes/default/jscalendar/lang/calendar-zh.js b/WebContent/themes/default/jscalendar/lang/calendar-zh.js
new file mode 100644
index 0000000000..4a0feb6b73
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/calendar-zh.js
@@ -0,0 +1,119 @@
+// ** I18N
+
+// Calendar ZH language
+// Author: muziq, <muziq@sina.com>
+// Encoding: GB2312 or GBK
+// Distributed under the same terms as the calendar itself.
+
+// full day names
+Calendar._DN = new Array
+("ÐÇÆÚÈÕ",
+ "ÐÇÆÚÒ»",
+ "ÐÇÆÚ¶þ",
+ "ÐÇÆÚÈý",
+ "ÐÇÆÚËÄ",
+ "ÐÇÆÚÎå",
+ "ÐÇÆÚÁù",
+ "ÐÇÆÚÈÕ");
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary. We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+// Calendar._SDN_len = N; // short day name length
+// Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+Calendar._SDN = new Array
+("ÈÕ",
+ "Ò»",
+ "¶þ",
+ "Èý",
+ "ËÄ",
+ "Îå",
+ "Áù",
+ "ÈÕ");
+
+// full month names
+Calendar._MN = new Array
+("Ò»ÔÂ",
+ "¶þÔÂ",
+ "ÈýÔÂ",
+ "ËÄÔÂ",
+ "ÎåÔÂ",
+ "ÁùÔÂ",
+ "ÆßÔÂ",
+ "°ËÔÂ",
+ "¾ÅÔÂ",
+ "Ê®ÔÂ",
+ "ʮһÔÂ",
+ "Ê®¶þÔÂ");
+
+// short month names
+Calendar._SMN = new Array
+("Ò»ÔÂ",
+ "¶þÔÂ",
+ "ÈýÔÂ",
+ "ËÄÔÂ",
+ "ÎåÔÂ",
+ "ÁùÔÂ",
+ "ÆßÔÂ",
+ "°ËÔÂ",
+ "¾ÅÔÂ",
+ "Ê®ÔÂ",
+ "ʮһÔÂ",
+ "Ê®¶þÔÂ");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "°ïÖú";
+
+Calendar._TT["ABOUT"] =
+"DHTML Date/Time Selector\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"For latest version visit: http://www.dynarch.com/projects/calendar/\n" +
+"Distributed under GNU LGPL. See http://gnu.org/licenses/lgpl.html for details." +
+"\n\n" +
+"Ñ¡ÔñÈÕÆÚ:\n" +
+"- µã»÷ \xab, \xbb °´Å¥Ñ¡ÔñÄê·Ý\n" +
+"- µã»÷ " + String.fromCharCode(0x2039) + ", " + String.fromCharCode(0x203a) + " °´Å¥Ñ¡ÔñÔ·Ý\n" +
+"- ³¤°´ÒÔÉÏ°´Å¥¿É´Ó²Ëµ¥ÖпìËÙÑ¡ÔñÄê·Ý»òÔ·Ý";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"Ñ¡Ôñʱ¼ä:\n" +
+"- µã»÷Сʱ»ò·ÖÖÓ¿Éʹ¸ÄÊýÖµ¼ÓÒ»\n" +
+"- °´×¡Shift¼üµã»÷Сʱ»ò·ÖÖÓ¿Éʹ¸ÄÊýÖµ¼õÒ»\n" +
+"- µã»÷Í϶¯Êó±ê¿É½øÐпìËÙÑ¡Ôñ";
+
+Calendar._TT["PREV_YEAR"] = "ÉÏÒ»Äê (°´×¡³ö²Ëµ¥)";
+Calendar._TT["PREV_MONTH"] = "ÉÏÒ»Ô (°´×¡³ö²Ëµ¥)";
+Calendar._TT["GO_TODAY"] = "תµ½½ñÈÕ";
+Calendar._TT["NEXT_MONTH"] = "ÏÂÒ»Ô (°´×¡³ö²Ëµ¥)";
+Calendar._TT["NEXT_YEAR"] = "ÏÂÒ»Äê (°´×¡³ö²Ëµ¥)";
+Calendar._TT["SEL_DATE"] = "Ñ¡ÔñÈÕÆÚ";
+Calendar._TT["DRAG_TO_MOVE"] = "Í϶¯";
+Calendar._TT["PART_TODAY"] = " (½ñÈÕ)";
+
+// the following is to inform that "%s" is to be the first day of week
+// %s will be replaced with the day name.
+Calendar._TT["DAY_FIRST"] = "×î×ó±ßÏÔʾ%s";
+
+// This may be locale-dependent. It specifies the week-end days, as an array
+// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1
+// means Monday, etc.
+Calendar._TT["WEEKEND"] = "0,6";
+
+Calendar._TT["CLOSE"] = "¹Ø±Õ";
+Calendar._TT["TODAY"] = "½ñÈÕ";
+Calendar._TT["TIME_PART"] = "(Shift-)µã»÷Êó±ê»òÍ϶¯¸Ä±äÖµ";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
+Calendar._TT["TT_DATE_FORMAT"] = "%A, %b %eÈÕ";
+
+Calendar._TT["WK"] = "ÖÜ";
+Calendar._TT["TIME"] = "ʱ¼ä:";
diff --git a/WebContent/themes/default/jscalendar/lang/cn_utf8.js b/WebContent/themes/default/jscalendar/lang/cn_utf8.js
new file mode 100644
index 0000000000..de61b4618d
--- /dev/null
+++ b/WebContent/themes/default/jscalendar/lang/cn_utf8.js
@@ -0,0 +1,123 @@
+// ** I18N
+
+// Calendar EN language
+// Author: Mihai Bazon, <mishoo@infoiasi.ro>
+// Encoding: any
+// Translator : Niko <nikoused@gmail.com>
+// Distributed under the same terms as the calendar itself.
+
+// For translators: please use UTF-8 if possible. We strongly believe that
+// Unicode is the answer to a real internationalized world. Also please
+// include your contact information in the header, as can be seen above.
+
+// full day names
+Calendar._DN = new Array
+("\u5468\u65e5",//\u5468\u65e5
+ "\u5468\u4e00",//\u5468\u4e00
+ "\u5468\u4e8c",//\u5468\u4e8c
+ "\u5468\u4e09",//\u5468\u4e09
+ "\u5468\u56db",//\u5468\u56db
+ "\u5468\u4e94",//\u5468\u4e94
+ "\u5468\u516d",//\u5468\u516d
+ "\u5468\u65e5");//\u5468\u65e5
+
+// Please note that the following array of short day names (and the same goes
+// for short month names, _SMN) isn't absolutely necessary. We give it here
+// for exemplification on how one can customize the short day names, but if
+// they are simply the first N letters of the full name you can simply say:
+//
+// Calendar._SDN_len = N; // short day name length
+// Calendar._SMN_len = N; // short month name length
+//
+// If N = 3 then this is not needed either since we assume a value of 3 if not
+// present, to be compatible with translation files that were written before
+// this feature.
+
+// short day names
+Calendar._SDN = new Array
+("\u5468\u65e5",
+ "\u5468\u4e00",
+ "\u5468\u4e8c",
+ "\u5468\u4e09",
+ "\u5468\u56db",
+ "\u5468\u4e94",
+ "\u5468\u516d",
+ "\u5468\u65e5");
+
+// full month names
+Calendar._MN = new Array
+("\u4e00\u6708",
+ "\u4e8c\u6708",
+ "\u4e09\u6708",
+ "\u56db\u6708",
+ "\u4e94\u6708",
+ "\u516d\u6708",
+ "\u4e03\u6708",
+ "\u516b\u6708",
+ "\u4e5d\u6708",
+ "\u5341\u6708",
+ "\u5341\u4e00\u6708",
+ "\u5341\u4e8c\u6708");
+
+// short month names
+Calendar._SMN = new Array
+("\u4e00\u6708",
+ "\u4e8c\u6708",
+ "\u4e09\u6708",
+ "\u56db\u6708",
+ "\u4e94\u6708",
+ "\u516d\u6708",
+ "\u4e03\u6708",
+ "\u516b\u6708",
+ "\u4e5d\u6708",
+ "\u5341\u6708",
+ "\u5341\u4e00\u6708",
+ "\u5341\u4e8c\u6708");
+
+// tooltips
+Calendar._TT = {};
+Calendar._TT["INFO"] = "\u5173\u4e8e";
+
+Calendar._TT["ABOUT"] =
+" DHTML \u65e5\u8d77/\u65f6\u95f4\u9009\u62e9\u63a7\u4ef6\n" +
+"(c) dynarch.com 2002-2005 / Author: Mihai Bazon\n" + // don't translate this this ;-)
+"For latest version visit: \u6700\u65b0\u7248\u672c\u8bf7\u767b\u9646http://www.dynarch.com/projects/calendar/\u5bdf\u770b\n" +
+"\u9075\u5faaGNU LGPL. \u7ec6\u8282\u53c2\u9605 http://gnu.org/licenses/lgpl.html" +
+"\n\n" +
+"\u65e5\u671f\u9009\u62e9:\n" +
+"- \u70b9\u51fb\xab(\xbb)\u6309\u94ae\u9009\u62e9\u4e0a(\u4e0b)\u4e00\u5e74\u5ea6.\n" +
+"- \u70b9\u51fb" + String.fromCharCode(0x2039) + "(" + String.fromCharCode(0x203a) + ")\u6309\u94ae\u9009\u62e9\u4e0a(\u4e0b)\u4e2a\u6708\u4efd.\n" +
+"- \u957f\u65f6\u95f4\u6309\u7740\u6309\u94ae\u5c06\u51fa\u73b0\u66f4\u591a\u9009\u62e9\u9879.";
+Calendar._TT["ABOUT_TIME"] = "\n\n" +
+"\u65f6\u95f4\u9009\u62e9:\n" +
+"-\u5728\u65f6\u95f4\u90e8\u5206(\u5206\u6216\u8005\u79d2)\u4e0a\u5355\u51fb\u9f20\u6807\u5de6\u952e\u6765\u589e\u52a0\u5f53\u524d\u65f6\u95f4\u90e8\u5206(\u5206\u6216\u8005\u79d2)\n" +
+"-\u5728\u65f6\u95f4\u90e8\u5206(\u5206\u6216\u8005\u79d2)\u4e0a\u6309\u4f4fShift\u952e\u540e\u5355\u51fb\u9f20\u6807\u5de6\u952e\u6765\u51cf\u5c11\u5f53\u524d\u65f6\u95f4\u90e8\u5206(\u5206\u6216\u8005\u79d2).";
+
+Calendar._TT["PREV_YEAR"] = "\u4e0a\u4e00\u5e74";
+Calendar._TT["PREV_MONTH"] = "\u4e0a\u4e2a\u6708";
+Calendar._TT["GO_TODAY"] = "\u5230\u4eca\u5929";
+Calendar._TT["NEXT_MONTH"] = "\u4e0b\u4e2a\u6708";
+Calendar._TT["NEXT_YEAR"] = "\u4e0b\u4e00\u5e74";
+Calendar._TT["SEL_DATE"] = "\u9009\u62e9\u65e5\u671f";
+Calendar._TT["DRAG_TO_MOVE"] = "\u62d6\u52a8";
+Calendar._TT["PART_TODAY"] = " (\u4eca\u5929)";
+
+// the following is to inform that "%s" is to be the first day of week
+// %s will be replaced with the day name.
+Calendar._TT["DAY_FIRST"] = "%s\u4e3a\u8fd9\u5468\u7684\u7b2c\u4e00\u5929";
+
+// This may be locale-dependent. It specifies the week-end days, as an array
+// of comma-separated numbers. The numbers are from 0 to 6: 0 means Sunday, 1
+// means Monday, etc.
+Calendar._TT["WEEKEND"] = "0,6";
+
+Calendar._TT["CLOSE"] = "\u5173\u95ed";
+Calendar._TT["TODAY"] = "\u4eca\u5929";
+Calendar._TT["TIME_PART"] = "(\u6309\u7740Shift\u952e)\u5355\u51fb\u6216\u62d6\u52a8\u6539\u53d8\u503c";
+
+// date formats
+Calendar._TT["DEF_DATE_FORMAT"] = "%Y-%m-%d";
+Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e\u65e5";
+
+Calendar._TT["WK"] = "\u5468";
+Calendar._TT["TIME"] = "\u65f6\u95f4:";
diff --git a/WebContent/themes/default/theme.css b/WebContent/themes/default/theme.css
new file mode 100644
index 0000000000..985efac13b
--- /dev/null
+++ b/WebContent/themes/default/theme.css
@@ -0,0 +1,803 @@
+/**
+* Various styles for debug mode
+*/
+.uidl {
+ z-index: 1001;
+ text-indent: 18px;
+ border: 1px dashed red;
+ font-weight: normal;
+ white-space: nowrap;
+ cursor: hand;
+ cursor: pointer;
+}
+
+.minimized {
+ overflow: hidden;
+ width: 5px;
+ height: 5px;
+ z-index: 1000;
+ float: left;
+}
+
+
+
+/**
+* Common attribute classes
+*/
+.abs { position: absolute; }
+.right { float: right; }
+.nobr { white-space: nowrap; }
+.inline { display: inline; }
+.hidden { display: none; }
+.pad {
+ padding: 3px 7px 3px 10px;
+}
+.padnr {
+ padding: 4px 0 4px 10px;
+}
+
+/**
+* Background used in various headers
+*/
+.bg {
+ background-image: url(img/bg1.gif);
+ background-repeat: repeat-x;
+ background-color: white;
+}
+
+
+
+
+
+
+
+
+
+
+
+.disabled {
+ color: #999999;
+ opacity: 0.5;
+ filter: alpha(opacity=50);
+}
+.disabled .caption {
+ color: #999999;
+}
+.disabled .border .caption {
+ color:#999999;
+}
+.disabled * {
+ color:#999999;
+}
+
+.caption {
+ font-weight:bold;
+ color: black;
+ white-space:nowrap;
+ /*height: 16px;*/
+}
+.caption .error {
+ /*width: 16px;
+ height: 16px;*/
+ padding-left:5px;
+}
+
+.content {
+ padding:5px;
+}
+
+.clickable {
+ cursor:hand;
+ cursor:pointer;
+}
+
+
+/*.over {
+ border: 1px solid #eeeeee;
+}
+.over .border {
+ border: 1px solid #9999ee;
+ margin-left:-1px;
+}*/
+
+/*
+.over.outset {
+ border: 1px solid #eeeeee !important;
+ border: inherit;
+}*/
+
+.border {
+ border: 1px solid #aaaaaa;
+}
+
+.border.error {
+ border-color: #ee6666;
+}
+
+IMG.overlay {
+ position: absolute;
+ z-index: 5;
+}
+IMG.error {
+ width: 11px;
+ height: 16px;
+}
+
+.inset {
+ border-top: 2px solid #eeeeee;
+ border-left: 2px solid #eeeeee;
+}
+
+.outset {
+ border-bottom: 2px solid #eeeeee;
+ border-right: 2px solid #eeeeee;
+}
+
+.odd {
+ background-color:#f1f1f1;
+}
+
+
+.selectable {
+ color:white;
+ background:#0075d9;
+}
+.selected {
+ background-color:#c6e5fa;
+}
+
+/* Popup */
+.popup {
+ font-weight: normal;
+ position: absolute;
+ z-index: 10000;
+ background: #f5f5fa;
+}
+.popup TD {
+ padding: 0px;
+ border: 0px;
+ margin: 0px;
+}
+.popup .icon {
+ vertical-align: middle;
+ display: inline;
+ /*width: auto;
+ height: auto;*/
+}
+.popup .error {
+ border: 1px solid red;
+}
+.popup.hide {
+ display: none;
+}/*
+.popup.hide .border {
+ display: inline;
+ border: none;
+}
+.popup.hide .icon {
+ display: inline;
+ /*width: 16px;
+ height: 16px;
+}
+.popup.hide .content {
+ display: none;
+}
+.popup.hide .error {
+ display: none;
+}*/
+
+
+
+.item {
+ border: 1px solid #e9e9ef;
+ border-top: 1px solid white;
+ white-space: nowrap;
+}
+.item.over {
+ border: 1px solid #9999ee;
+ background-color: white;
+ background-image: url('img/bg1.gif');
+ background-repeat: repeat-x;
+}
+.item .icon {
+ width:16px;
+ height:16px;
+}
+
+
+
+
+
+/**
+* Icons
+*/
+
+.icon {
+ vertical-align:bottom;
+ width:32px;
+ height:32px;
+}
+.icon-mini {
+ width:14px;
+ height:11px;
+ display:-moz-inline-box;
+ display:inline-block;
+ vertical-align:top;
+}
+.icon.error {
+ background:url(img/icon/error.gif) no-repeat top right;
+}
+.icon-mini.error {
+ background:url(img/icon/error-mini.gif) no-repeat;
+}
+.icon.info {
+ background:url(img/icon/info.gif) no-repeat;
+}
+.icon-mini.info {
+ background:url(img/icon/info-mini.gif) no-repeat top right;
+}
+
+
+/* COMPONENTS */
+
+
+/**
+* Layouts
+*/
+.gridlayout TABLE TD {
+ text-align: left;
+ vertical-align: top;
+}
+
+.orderedlayout TABLE {
+ /* TODO works in FF not IE */
+ Xwidth: 100%;
+}
+
+
+/**
+* Button
+*/
+
+/* Button-style */
+.button {
+ margin-left:-5px;
+}
+.button .icon-mini {
+ padding-left:5px;
+}
+.btn {
+ float:left;
+ padding:5px 12px 0 0;
+ height:23px;
+ color:#fff;
+ background:url(img/button/btn-bg.gif) repeat-x;
+}
+
+.over .btn {
+ background:url(img/button/btn-bg.gif) repeat-x bottom left;
+ border:none;
+}
+.btn-left, .btn-right {
+ width:16px;
+ height:28px;
+ float:left;
+ background:url(img/button/btn-left.gif) no-repeat;
+}
+.btn-right {
+ background:url(img/button/btn-right.gif) no-repeat;
+}
+.over .btn-left {
+ background:url(img/button/btn-left.gif) no-repeat bottom left;
+}
+.over .btn-right {
+ background:url(img/button/btn-right.gif) no-repeat bottom left;
+}
+.btn .caption {
+ color:#fff;
+}
+.btn .popup, .btn .popup .caption {
+ color:#494949;
+}
+.button.over {
+ border:none;
+}
+.button.over .btn .caption {
+ color:#fff;
+}
+
+/* Link-style */
+.button-link .caption {
+ color:#6db201;
+ text-decoration:underline;
+}
+.button-link.over .caption {
+ color:#2a7acc;
+}
+.button-link .popup, .button-link .popup .caption, .button-link.over .caption .popup .content {
+ color:#494949;
+ text-decoration:none;
+}
+
+
+
+/**
+* Link
+*/
+.link {
+
+}
+.link.over {
+ background:none;
+}
+.link .caption {
+ color:#6db201;
+ text-decoration:underline;
+}
+.link.over .caption {
+ color:#2a7acc;
+}
+.link .description {
+ font-size:0.9em;
+}
+.link .popup .caption, .link .popup .content {
+ color:#494949;
+ text-decoration:none;
+}
+
+
+
+
+/**
+* Tabsheet
+*/
+/*
+.tabs {
+ padding-left: 0px !important;
+ padding-left: 1px;
+ padding-top: 5px;
+ padding-bottom: 3px !important;
+ padding-bottom: 2px;
+ white-space: nowrap;
+}
+.tab, .tab-on {
+ border-right: 2px solid #eeeeee;
+ border-bottom: none;
+}
+.tab-on {
+ position: relative;
+ top: 1px;
+}
+.tab .caption {
+ background-image: url('img/bg1.gif');
+ background-repeat: repeat-x;
+ border-bottom: none;
+}
+.tab .over {
+ /*border: 1px solid #9999ee;
+ border-bottom: none;
+}
+.tab-on .caption {
+ border-bottom: 1px solid white;
+ border-bottom: none;
+ background-color: white;
+}
+*/
+
+
+.node {
+ border: 1px solid white;
+ white-space: nowrap;
+ padding-bottom: 2px;
+}
+.nodes {
+ padding-left: 16px;
+}
+.node .caption {
+ vertical-align: top;
+ font-weight: normal;
+}
+
+.node.over {
+ /*border: 1px solid #9999ee;
+ background-image: url('img/bg1.gif');
+ background-repeat: repeat-x;
+ background-color: white;*/
+}
+.node.over .caption {
+ /*color: blue;*/
+}
+.node .icon {
+ width:16px;
+ height:16px;
+}
+
+/**
+* Panel
+*/
+
+/* Normal style */
+.panel {
+ margin:14px 9px 14px 0;
+}
+.panel .top {
+ height:35px;
+}
+.panel .top .left {
+ background:transparent url(img/panel/top-left.gif) no-repeat;
+ margin-right:19px;
+ height:35px;
+}
+.panel .top .right {
+ background:transparent url(img/panel/top-right.gif) no-repeat right top;
+ margin-left:-19px;
+ width:19px;
+ height:35px;
+ float:right;
+ display:inline;
+}
+.panel .middle {
+ background:#f8f8f8 url(img/panel/middle.gif) repeat-x;
+ border-left:solid 2px #ededed;
+ border-right:solid 2px #ededed;
+ padding:12px 19px 12px 19px;
+ overflow:auto;
+}
+.panel .bottom {
+ height:21px;
+}
+.panel .bottom .left {
+ background:url(img/panel/bottom-left.gif) no-repeat;
+ margin-right:19px;
+ height:21px;
+
+}
+.panel .bottom .right {
+ background:url(img/panel/bottom-right.gif) no-repeat right top;
+ width:19px;
+ height:21px;
+ float:right;
+}
+/* FIX IE6 (5.5) leaves a four pixel gap between left and right div's */
+* html .panel .bottom .right {
+ position:relative;
+ left:-4px;
+}
+.panel .top .left .title {
+ padding:8px 19px 3px 19px;
+ height:22px;
+ margin-right:-19px;
+ border-bottom:solid 1px #dedede;
+}
+.panel .top .left .title .caption {
+ font-family:'Trebuchet MS', Tahoma, Arial, Helvetica, sans-serif;
+ color:#0076c9;
+ font-style:italic;
+ font-weight:bold;
+ font-size:12pt;
+ letter-spacing:-0.04em;
+ white-space:nowrap;
+}
+
+
+/* Light style */
+.panel-light {
+ margin:20px 9px 20px 0;
+}
+.panel-light .top {
+ height:31px;
+ overflow:hidden;
+}
+.panel-light .top .left {
+ background:transparent url(img/panel/top-left-light.gif) no-repeat;
+ margin-right:19px;
+ height:31px;
+}
+.panel-light .top .right {
+ background:transparent url(img/panel/top-right-light.gif) no-repeat right top;
+ margin-left:-19px;
+ width:19px;
+ height:31px;
+ float:right;
+ display:inline;
+}
+.panel-light .middle {
+ background:#fff url(img/panel/middle-light.gif) repeat-x;
+ padding:12px 19px 12px 19px;
+ overflow:auto;
+}
+.panel-light .top .left .title {
+ padding:5px 19px 3px 19px;
+ height:18px;
+}
+.panel-light .top .left .title .caption {
+ font-family:'Trebuchet MS', Tahoma, Arial, Helvetica, sans-serif;
+ color:#0076c9;
+ font-style:italic;
+ font-weight:bold;
+ font-size:11pt;
+ letter-spacing:-0.04em;
+ white-space:nowrap;
+}
+
+/* Description popup fixes */
+.panel .title .caption .popup .caption, .panel .title .caption .popup .caption {
+ font-family:Tahoma, Arial, Helvetica, sans-serif;
+ font-style:normal;
+ font-size:8pt;
+ color:#494949;
+}
+
+
+
+
+
+/*
+.textfield.over .border {
+ border: 1px solid #9999ee;
+}
+*/
+.textfield INPUT {
+ border: none;
+ padding-top: 2px;
+ padding-bottom: 2px;
+ padding-left: 5px;
+ padding-right: 5px;
+}
+
+
+
+
+/*
+* Table
+ */
+
+/* Renewed theme styles, 8.6.2006 - Jouni Koivuviita */
+.table {
+ margin:14px 10px 14px 0;
+ color:#494949;
+}
+.table .header {
+ height:25px;
+ overflow:hidden;
+ position:relative;
+ top:3px;
+ z-index:1;
+}
+.table .header .left {
+ width:20px;
+ height:25px;
+ float:left;
+ background:url(img/table/caption-left.gif) no-repeat;
+}
+.table .header .title {
+ height:25px;
+ float:left;
+ background:url(img/table/caption-bg.gif) repeat-x;
+ padding-right:20px;
+}
+.table .header .right {
+ width:20px;
+ height:25px;
+ float:left;
+ background:url(img/table/caption-right.gif) no-repeat;
+}
+.table .header .title {
+ padding-top:7px;
+ color:#fff;
+}
+.table .top {
+ height:3px;
+ overflow:hidden;
+}
+.table .top .left {
+ background:url(img/table/top-left.gif) no-repeat;
+ margin-right:4px;
+ height:3px;
+}
+.table .top .right {
+ background:url(img/table/top-right.gif) no-repeat right top;
+ width:4px;
+ height:3px;
+ float:right;
+}
+
+.table .middle {
+ background-color:#f8f8f8;
+ border-left:solid 3px #f1f1f1;
+ border-right:solid 3px #f1f1f1;
+ color:#494949;
+}
+.table .bottom {
+ height:3px;
+}
+.table .bottom .left {
+ background:url(img/table/bottom-left.gif) no-repeat;
+ margin-right:4px;
+ height:3px;
+
+}
+.table .bottom .right {
+ background:url(img/table/bottom-right.gif) no-repeat right top;
+ width:4px;
+ height:3px;
+ float:right;
+}
+.table .header .title .caption {
+ color:#fff;
+}
+.table .col-headers {
+ background:#f4f4f4 url(img/table/col-header-bg.gif) repeat-x;
+ color:#0076c9;
+}
+
+
+/* Old table styles */
+.list .bg {
+ background-image: none;
+}
+.list .cheader {
+ border-width: 1px 1px 1px 1px;
+}
+.list .content TABLE {
+ width: 100%;
+}
+.list .nav {
+ border-top: 2px solid #eeeeee;
+ text-align: center;
+ font-size: smaller;
+}
+.list .nav .small {
+ font-size: smaller;
+}
+.list .content TR.over {
+ background-image: url('img/bg1.gif');
+ background-repeat: repeat-x;
+ background-color: white;
+}
+.list .content TD.scroll {
+ background: white;
+}
+.list .content TD.scroll {
+ background: white;
+}
+.table .content {
+ padding: 0px;
+}
+.table .content TABLE {
+ border-collapse: collapse;
+ empty-cells: show;
+ width: 100%;
+}
+.table .content TD {
+ padding-left: 5px;
+ padding-right: 5px;
+ padding-top: 3px;
+ padding-bottom: 3px;
+ border-left: 1px solid #eeeeee;
+ border-bottom: 1px solid #eeeeee;
+}
+
+.table .cheader {
+ border-bottom-color: #999999;
+ border-left: 1px solid #cdcdcd;
+ padding-top: 5px;
+ padding-bottom: 5px;
+ vertical-align: middle;
+}
+.table .cheader.over {
+ border-color: #9999ee;
+ padding-bottom: 4px;
+}
+.table .cheader.sorted {
+ border-color: #9999ee;
+ padding-bottom: 4px;
+}
+.table .rheader {
+ text-align: right;
+ border-right-color: #999999;
+ border-left: none;
+}
+.table .selected .rheader {
+ background-color: white;
+}
+.table .empty {
+ border-bottom-color: #999999;
+ border-right-color: #999999;
+}
+.table .nav {
+ border-top: 2px solid #eeeeee;
+ text-align: center;
+ font-size: smaller;
+}
+.table .nav .small {
+ font-size: smaller;
+}
+.table .content TR.over {
+ background-image: url(img/bg1.gif);
+ background-repeat: repeat-x;
+ background-color: white;
+}
+.table .content TR.over TD {
+ border-bottom: 1px solid #9999ee;
+}
+
+.table .content TD.scroll {
+ padding: 0px;
+ border: none;
+ width: 16px;
+ height: 100%;
+}
+.table .content TD.cheader.scroll {
+ border-left: 1px solid #999999;
+ border-bottom: 1px solid #999999;
+ width: 16px;
+}
+.table DIV.scroll {
+ width: 16px;
+ border-left: 1px solid #eeeeee;
+ /*overflow: scroll;*/
+ height: 100%;
+}
+td.header {
+ background: url(img/bg1.gif);
+ background-repeat: repeat-x;
+}
+.table .icon {
+ width:16px;
+ height:16px;
+ background:url(img/table/col-header-bg.gif) repeat-x;
+}
+
+
+/**
+* General HTML-tag styles
+* Added 6.6.2006
+* Jouni Koivuviita
+**/
+
+body {
+ margin:0;
+ padding:20px;
+ background: url(img/body_bg.gif) repeat-x #fff;
+ color:#494949;
+ font-family:Tahoma, Arial, Helvetica, sans-serif;
+ font-size:62.5%;
+}
+td {
+ font-size:8pt;
+}
+p {
+ font-size:1em;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ font-family: "Trebuchet MS", sans-serif;
+ color:#494949;
+ letter-spacing:-0.03em;
+}
+h1 {
+ font-size: 18pt;
+ text-transform:uppercase;
+ margin:1em 0 0.6em 0;
+}
+h2 {
+ font-size:17pt;
+ font-weight:normal;
+ color:#0076c9;
+ margin:0.8em 0 0.5em 0;
+}
+h3 {
+ font-size: 14pt;
+ margin:0.6em 0 0.4em 0;
+}
+h4 {
+ font-size:12.4pt;
+ font-style:italic;
+ color:#0076c9;
+ margin:0.4em 0 0.3em 0;
+}
+h5 {
+ font-size:10pt;
+ margin:0.3em 0 0.2em 0;
+} \ No newline at end of file
diff --git a/WebContent/themes/default/theme.js b/WebContent/themes/default/theme.js
new file mode 100644
index 0000000000..52a8525f8b
--- /dev/null
+++ b/WebContent/themes/default/theme.js
@@ -0,0 +1,4119 @@
+
+// IE DOM Node support
+if(document.all) {
+ Node = new Object();
+ Node.ELEMENT_NODE = 1;
+ Node.ATTRIBUTE_NODE = 2;
+ Node.TEXT_NODE = 3;
+ Node.CDATA_SECTION_NODE = 4;
+ Node.ENTITY_REFERENCE_NODE = 5;
+ Node.ENTITY_NODE = 6;
+ Node.PROCESSING_INSTRUCTION_NODE = 7;
+ Node.COMMENT_NODE = 8;
+ Node.DOCUMENT_NODE = 9;
+ Node.DOCUMENT_TYPE_NODE = 10;
+ Node.DOCUMENT_FRAGMENT_NODE = 11;
+ Node.NOTATION_NODE = 12;
+}
+
+
+/** Default theme constructor.
+ *
+ * @param themeRoot The base URL for theme resources.
+ * @constructor
+ *
+ */
+function DefaultTheme(themeRoot) {
+ this.themeName = "DefaultTheme";
+
+ // Store the the root URL
+ this.root = themeRoot;
+}
+
+
+/** Register all renderers to a ajax client.
+ *
+ * @param client The ajax client instance.
+ */
+DefaultTheme.prototype.registerTo = function(client) {
+
+ // This hides all integer, string, etc. variables
+ client.registerRenderer(this,"integer",null,function() {});
+ client.registerRenderer(this,"string",null,function() {});
+ // and special tags
+ client.registerRenderer(this,"description",null,function() {});
+ client.registerRenderer(this,"error",null,function() {});
+ client.registerRenderer(this,"actions",null,function() {});
+
+
+ // Register renderer functions
+ client.registerRenderer(this,"component",null,this.renderComponent);
+ client.registerRenderer(this,"label",null,this.renderLabel);
+ client.registerRenderer(this,"data",null,this.renderData);
+ client.registerRenderer(this,"pre",null,this.renderData);
+ client.registerRenderer(this,"link",null,this.renderLink);
+ client.registerRenderer(this,"button",null,this.renderButton);
+ client.registerRenderer(this,"textfield",null,this.renderTextField);
+ client.registerRenderer(this,"datefield",null,this.renderDateField);
+ client.registerRenderer(this,"datefield","calendar",this.renderDateFieldCalendar);
+ client.registerRenderer(this,"select",null,this.renderSelect);
+ client.registerRenderer(this,"select","optiongroup",this.renderSelectOptionGroup);
+ client.registerRenderer(this,"upload",null,this.renderUpload);
+ client.registerRenderer(this,"embedded",null,this.renderEmbedded);
+
+ client.registerRenderer(this,"window",null,this.renderWindow);
+ client.registerRenderer(this,"framewindow",null,this.renderFramewindow);
+ client.registerRenderer(this,"open",null,this.renderOpen);
+
+ client.registerRenderer(this,"panel",null,this.renderPanel);
+ client.registerRenderer(this,"orderedlayout",null,this.renderOrderedLayout);
+ client.registerRenderer(this,"customlayout",null,this.renderCustomLayout);
+ client.registerRenderer(this,"gridlayout",null,this.renderGridLayout);
+ client.registerRenderer(this,"tabsheet",null,this.renderTabSheet);
+
+ client.registerRenderer(this,"table",null,this.renderScrollTable);
+ client.registerRenderer(this,"tree",null,this.renderTree);
+ client.registerRenderer(this,"tree","coolmenu",this.renderTreeMenu);
+ //client.registerRenderer(this,"tree","menu",this.renderTreeMenu);
+};
+
+DefaultTheme.prototype.renderComponent = function(renderer,uidl,target,layoutInfo) {
+
+ // Create containing element
+ var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
+ if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
+
+ // Render default header
+ renderer.theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
+
+ // Render children to div
+ renderer.theme.renderChildNodes(renderer, uidl, div);
+}
+
+DefaultTheme.prototype.renderWindow = function(renderer,uidl,target,layoutInfo) {
+ var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
+ if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
+
+ var theme = renderer.theme;
+
+ theme.addHidePopupListener(theme,renderer.client,div,"click",true);
+
+ // Render children to div
+ theme.renderChildNodes(renderer, uidl, div);
+
+ // Apply width and height
+ theme.applyWidthAndHeight(uidl,div);
+ if (!div.ownerDocument.isMainDocument && div.ownerDocument.body.clientHeight && div.ownerDocument.body.firstChild.style) {
+ theme.registerWindowLayoutFunction(client,target);
+ // Make frames in framewindow scrollable
+ /*
+ div.ownerDocument.body.firstChild.style.height = div.ownerDocument.body.clientHeight+ "px";
+ div.ownerDocument.body.firstChild.style.overflow = "auto";
+ */
+ }
+
+ // Focusing
+ var focused = theme.getVariableElement(uidl,"string","focused");
+ var focusid = theme.getVariableElementValue(focused);
+ if (focusid) {
+ var found = false;
+ var els = div.getElementsByTagName("input");
+ var len = (els?els.length:0);
+ for (var i=0;i<len;i++) {
+ var el = els[i];
+ if (focusid == el["focusid"]) {
+ el.focus();
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ els = div.getElementsByTagName("select");
+ var len = (els?els.length:0);
+ for (var i=0;i<len;i++) {
+ var el = els[i];
+ if (focusid == el["focusid"]) {
+ el.focus();
+ found = true;
+ break;
+ }
+ }
+ }
+ if (!found) {
+ els = div.getElementsByTagName("textarea");
+ var len = (els?els.length:0);
+ for (var i=0;i<len;i++) {
+ var el = els[i];
+ if (focusid == el["focusid"]) {
+ el.focus();
+ found = true;
+ break;
+ }
+ }
+ }
+ }
+}
+DefaultTheme.prototype.registerWindowLayoutFunction = function(client,target) {
+
+ //target.ownerDocument.body.firstChild.style.height = target.ownerDocument.body.clientHeight+ "px";
+ //target.ownerDocument.body.firstChild.style.overflow = "auto";
+ var ua = navigator.userAgent.toLowerCase();
+ var msie = ua.indexOf("msie")>=0;
+ client.registerLayoutFunction(target, function() {
+
+
+ if (msie) return; //TODO make it work in all browsers
+ var iframes = target.getElementsByTagName("iframe");
+ if (iframes&&iframes.length>0) {
+ iframes[0].style.height = (target.ownerDocument.body.clientHeight-2)+ "px";
+ }
+
+ target.ownerDocument.body.firstChild.style.overflow = "auto";
+ target.ownerDocument.body.firstChild.style.border = "1px solid gray";
+ target.ownerDocument.body.firstChild.style.display = "none";
+ var h = target.ownerDocument.body.clientHeight;
+ target.ownerDocument.body.firstChild.style.display = "";
+ target.ownerDocument.body.firstChild.style.height = (h-2)+ "px";
+ });
+}
+
+DefaultTheme.prototype.renderOpen = function(renderer,uidl,target,layoutInfo) {
+ // Shortcuts
+ var theme = renderer.theme;
+
+ var src = uidl.getAttribute("src");
+ var name = uidl.getAttribute("name");
+
+ if (name == "_new") {
+ window.open(src);
+ } else {
+ var div = theme.createPaintableElement(renderer,uidl,target,layoutInfo);
+ div.innerHTML = "<IFRAME name=\""+name+"\" id=\""+name+"\" width=100% height=100% style=\"border:none;margin:0px;padding:0px;background:none;\" src=\""+src+"\"></IFRAME>";
+ theme.registerOpenLayoutFunction(client,target,div.firstChild);
+ }
+}
+DefaultTheme.prototype.registerOpenLayoutFunction = function(client,target,iframe) {
+ client.registerLayoutFunction(target, function() {
+ iframe.style.height = target.ownerDocument.body.clientHeight+ "px";
+ });
+}
+
+DefaultTheme.prototype.renderFramewindow = function(renderer,uidl,target,layoutInfo) {
+
+ var theme = renderer.theme;
+ var client = renderer.client;
+
+ // TODO: Should we unregister all previous child windows?
+
+ // We just reinitialize the window
+ var win = target.ownerDocument.ownerWindow;
+ client.initializeNewWindow(win,uidl,theme);
+}
+
+DefaultTheme.prototype.renderCustomLayout = function(renderer,uidl,target,layoutInfo) {
+ // Shortcuts
+ var theme = renderer.theme;
+
+ // Get style
+ var style = uidl.getAttribute("style");
+ if (style == null) return null;
+
+ // Load the layout
+ var url = theme.root + style;
+ var text = renderer.client.loadDocument(url,false);
+ if (text == null) {
+ client.debug("CustomLayout " + style + " NOT FOUND @ "+ url);
+ return null;
+ }
+
+ // Create containing element
+ var main = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
+ if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
+
+ var locations = new Object();
+ var unused = new Object();
+ var cN = uidl.childNodes;
+ var len = cN.length;
+ for (var j=0; j < len; j++) {
+ var c = cN.item(j);
+ if (c.nodeType == Node.ELEMENT_NODE
+ && c.nodeName == "location"
+ && c.getAttribute("name")) {
+
+ locations[c.getAttribute("name")] = c;
+ unused[c.getAttribute("name")] = c;
+ }
+ }
+
+
+ var n = theme.createElementTo(main, "div");
+ n.setAttribute("id",uidl.getAttribute("id"));
+ n.innerHTML=text;
+ var divs = n.getElementsByTagName("div");
+ for (var i=0; i<divs.length; i++) {
+ var div = divs.item(i);
+ var name = div.getAttribute("location");
+ if (name != null) {
+ var c = locations[name];
+ if (c && c.getAttribute("name") == name) {
+ delete unused[name];
+ for (var k=0; k<c.childNodes.length; k++) {
+ var cc = c.childNodes.item(k);
+ if (cc.nodeType == Node.ELEMENT_NODE) {
+ var parent = div.parentNode;
+ // TODO
+ if (parent != null) {
+ theme.removeAllChildNodes(div);
+ var newNode = renderer.client.renderUIDL(cc,div);
+ }
+ }
+ }
+ } else {
+ client.warn("Location " + name + " NOT USED in CustomLayout " + style);
+ }
+ }
+ }
+ if (unused.length>0) {
+ for (var k in usedLocations) {
+ client.error("Location " + k + " NOT FOUND in CustomLayout " + style);
+ }
+ }
+
+}
+
+DefaultTheme.prototype.renderOrderedLayout = function(renderer,uidl,target,layoutInfo) {
+ // Shortcuts
+ var theme = renderer.theme;
+
+ // Create containing element
+ var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
+ if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
+
+ // Render all children to table
+ var vertical = uidl.getAttribute("orientation") != "horizontal";
+ var table = null;
+ var tr = null;
+ var td = null;
+ var style = uidl.getAttribute("style");
+ var form = style == "form";
+
+ var childUIDL = uidl.firstChild;
+ while (childUIDL) {
+ //for (var i=0; i<uidl.childNodes.length; i++) {
+ // var childUIDL = uidl.childNodes.item(i);
+ td = null;
+ if (childUIDL.nodeType == Node.ELEMENT_NODE) {
+
+ // Ensure TABLE and TR
+ if (tr == null || vertical) {
+ if (table == null) {
+ table = renderer.theme.createElementTo(div,"table","orderedlayout");
+ table.width="100%";
+ renderer.theme.addCSSClass(table,"layout");
+ table = renderer.theme.createElementTo(table,"tbody","layout");
+ }
+ tr = renderer.theme.createElementTo(table,"tr","layout");
+ }
+
+ // Create extra TD for form style captions
+ var layoutInfo = null;
+ if (form) {
+ layoutInfo = new Object()
+ td = renderer.theme.createElementTo(tr,"td","layout");
+ layoutInfo.captionNode = td;
+ }
+
+ // Force new TD for each child rendered
+ td = renderer.theme.createElementTo(tr,"td","layout");
+
+ // Render the component to TD
+ renderer.client.renderUIDL(childUIDL,td, null, layoutInfo);
+
+ }
+
+ childUIDL = childUIDL.nextSibling;
+
+ }
+}
+
+
+DefaultTheme.prototype.renderGridLayout = function(renderer,uidl,target,layoutInfo) {
+ // NOTE TODO indenting might be off
+ // Shortcuts
+ var theme = renderer.theme;
+
+ var h = uidl.getAttribute("h");
+ var w = uidl.getAttribute("w");
+ // Create component element
+ var div = theme.createPaintableElement(renderer,uidl,target,layoutInfo);
+ if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
+ //var width = (div.offsetWidth||div.clientWidth)-20;
+ //var px = Math.floor(width/parseInt(w));
+
+ var table = theme.createElementTo(div,"table", "layout");
+ //table.width = "100%";
+ table = renderer.theme.createElementTo(table,"tbody","layout");
+ var tr = null;
+ var td = null;
+ var rowUidl = uidl.firstChild;
+ while (rowUidl) {
+ //for (var y=0; y<uidl.childNodes.length; y++) {
+ //var rowUidl = uidl.childNodes[y];
+
+ if (rowUidl.nodeType == Node.ELEMENT_NODE || rowUidl.nodeName == "gr") {
+
+ tr = theme.createElementTo(table,"tr","layout");
+ tr.style.verticalAlign = "top";
+ td = null;
+
+ for (var x=0; x<rowUidl.childNodes.length; x++) {
+ var cellUidl = rowUidl.childNodes[x];
+
+ // Add colspan and rowspan
+ if (cellUidl.nodeType == Node.ELEMENT_NODE && cellUidl.nodeName == "gc") {
+ // Create new TD for each child rendered
+ td = renderer.theme.createElementTo(tr,"td","layout");
+
+ var w = cellUidl.getAttribute('w');
+ var h = cellUidl.getAttribute('h');
+ //var cont = renderer.theme.createElementTo(td,"div");
+ //cont.style.width = ((w?w:1)*px)+"px";
+ if (w != null) {
+ td.setAttribute('colspan',w);
+ }
+ if (h != null) {
+ td.setAttribute('rowspan',h);
+ }
+ // Render the component(s) to TD
+ if (cellUidl.childNodes != null && cellUidl.childNodes.length >0) {
+ var len = cellUidl.childNodes.length;
+ for (var c=0;c<len;c++) {
+ var el = cellUidl.childNodes[c];
+ if (el.nodeType == Node.ELEMENT_NODE) {
+ renderer.client.renderUIDL(el,td);
+ }
+ }
+ //cont.style.width = "";
+ }
+ }
+ }
+ }
+ rowUidl = rowUidl.nextSibling;
+ }
+}
+
+/* Deprecated - 8.6.2006, Jouni Koivuviita
+*
+DefaultTheme.prototype.renderPanel = function(renderer,uidl,target,layoutInfo) {
+ // Supports styles "light" and "none"
+
+ // Shortcuts
+ var theme = renderer.theme;
+
+ var style = uidl.getAttribute("style");
+
+ // Create component element
+ var outer = theme.createPaintableElement(renderer,uidl,target,layoutInfo);
+ if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
+
+ if ("none"!=style) {
+ theme.addCSSClass(div,"outset");
+ }
+ if ("light"==style) {
+ theme.addCSSClass(div,"light");
+ }
+
+ // Create extra DIV for visual layout
+ var div = theme.createElementTo(outer,"div");
+ if ("none"!=style) {
+ theme.setCSSClass(div,"border");
+ }
+
+ // Create default header
+ var caption = theme.renderDefaultComponentHeader(renderer,uidl,div);
+ theme.addCSSClass(caption,"pad");
+ if ("light"==style) {
+ theme.addCSSClass(caption,"lightcap");
+ }
+
+ // Create content DIV
+ var content = theme.createElementTo(div,"div");
+ theme.setCSSClass(content,"content");
+
+ // Render children to div
+ theme.renderChildNodes(renderer, uidl, content);
+
+ // Apply width and height
+ theme.applyWidthAndHeight(uidl,outer);
+
+}
+*/
+/*
+DefaultTheme.prototype.renderTabSheet = function(renderer,uidl,target,layoutInfo) {
+
+ var theme = renderer.theme;
+
+ // Create container element
+ var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
+ if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
+
+ // Create default header
+ var caption = renderer.theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
+ theme.createElementTo(div,"br");
+
+ // Render tabs
+ var tabs = theme.createElementTo(div,"div","tabs");
+ var varId = theme.getVariableElement(uidl,"string","selected").getAttribute("id");
+
+ var tabNodes = theme.getChildElements(uidl,"tabs");
+ if (tabNodes != null && tabNodes.length >0) tabNodes = theme.getChildElements(tabNodes[0],"tab");
+ var selectedTabNode = null;
+ if (tabNodes != null && tabNodes.length >0) {
+ for (var i=0; i< tabNodes.length;i++) {
+ var tabNode = tabNodes[i];
+ var tab = theme.createElementTo(tabs,"div");
+ var key = tabNode.getAttribute("key");
+ var iconUrl = tabNode.getAttribute("icon");
+ if (iconUrl && iconUrl.indexOf("theme://") == 0) {
+ iconUrl = (theme.iconRoot != null ? theme.iconRoot : theme.root)
+ + iconUrl.substring(8);
+ }
+ if (tabNode.getAttribute("selected") == "true") {
+ theme.addCSSClass(tab,"tab-on inline");
+ selectedTabNode = tabNode;
+ } else if (tabNode.getAttribute("disabled") == "true") {
+ theme.setCSSClass(tab,"tab disabled inline");
+ } else {
+ theme.setCSSClass(tab,"tab clickable inline");
+ theme.addAddClassListener(theme,client,tab,"mouseover","over",tab);
+ theme.addRemoveClassListener(theme,client,tab,"mouseout","over",tab);
+ theme.addSetVarListener(theme,client,tab,"click",varId,key,true);
+ }
+ // Extra div in tab
+ tab = theme.createElementTo(tab,"div","caption border pad inline");
+
+ // Icon
+ if (iconUrl) {
+ tab.innerHTML = "<IMG src=\""+iconUrl+"\" class=\"icon\" />"+tabNode.getAttribute("caption");
+ //var icon = theme.createElementTo(tab,"img","icon");
+ //icon.src = iconUrl;
+ } else {
+ tab.innerHTML = tabNode.getAttribute("caption");
+ }
+
+ // Caption
+ //theme.createTextNodeTo(tab,tabNode.getAttribute("caption"));
+
+ }
+ }
+
+ // Render content
+ var content = theme.createElementTo(div,"div","outset");
+ content = theme.createElementTo(content,"div","content border");
+ if (selectedTabNode != null) {
+ theme.renderChildNodes(renderer,selectedTabNode, content);
+ }
+}
+*/
+DefaultTheme.prototype.renderTree = function(renderer,uidl,target,layoutInfo) {
+
+ var theme = renderer.theme;
+
+ // Create container element
+ var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
+ if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
+
+ // Get tree attributes
+ var style = uidl.getAttribute("style");
+ var immediate = ("true" == uidl.getAttribute("immediate"));
+ var disabled = ("true" == uidl.getAttribute("disabled"));
+ var readonly = ("true" == uidl.getAttribute("readonly"));
+ var selectMode = uidl.getAttribute("selectmode");
+ var selectable = selectMode == "multi" || selectMode == "single";
+ var selected;
+ if (selectable) {
+ selected = new Object();
+ }
+ var selectionVariable = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","selected"));
+ var expandVariable = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","expand"));
+ var collapseVariable = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","collapse"));
+
+ var actions = null;
+ var actionVar = null;
+ var alNode = theme.getFirstElement(uidl,"actions")
+ if (alNode) {
+ actionVar = theme.createVariableElementTo(div,theme.getVariableElement(alNode,"string","action"));
+ actions = new Object();
+ var ak = alNode.getElementsByTagName("action");
+ for (var i=0;i<ak.length;i++) {
+ actions[ak[i].getAttribute("key")] = ak[i].getAttribute("caption");
+ }
+ }
+ delete alNode;
+
+ // Create default header
+ var caption = renderer.theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
+
+ // Content DIV
+ var content = theme.createElementTo(div,"div","content");
+
+ // Iterate all nodes
+ var node = uidl.firstChild;
+ while (node) {
+ if (node.nodeName == "node" || node.nodeName == "leaf") {
+ theme.renderTreeNode(renderer,node,content,selectable,selectMode,selected,selectionVariable,expandVariable,collapseVariable,actions,actionVar,immediate,disabled,readonly);
+ }
+ node = node.nextSibling;
+ }
+}
+
+DefaultTheme.prototype.renderTreeNode = function(renderer,node,target,selectable,selectMode,selected,selectionVariable,expandVariable,collapseVariable,actions,actionVar,immediate,disabled,readonly) {
+
+ var theme = renderer.theme;
+ var client = renderer.client;
+
+ var n = theme.createElementTo(target,"div","node clickable");
+
+ // Expand/collapse/spacer button
+ var img = theme.createElementTo(n,"img","icon");
+ var key = node.getAttribute("key");
+ var icon = node.getAttribute("icon");
+ if (icon) {
+ var iconurl = theme.root+icon.split("theme:")[1];
+ var iimg = theme.createElementTo(n,"img","icon");
+ iimg.src = iconurl;
+ }
+
+ // Caption
+ var cap = theme.createElementTo(n,"div","caption inline");
+ theme.createTextNodeTo(n,node.getAttribute("caption"));
+
+ // Hover effects
+ if (!disabled&&!readonly) {
+ theme.addAddClassListener(theme,client,n,"mouseover","over",n);
+ theme.addRemoveClassListener(theme,client,n,"mouseout","over",n);
+ }
+
+ // Server-side selection
+ if (selectable && node.getAttribute("selected") == "true") {
+ theme.addCSSClass(n,"selected");
+ selected[key] = n;
+ }
+
+ // Indicate selection
+ if (theme.listContainsInt(selectionVariable.value,key)) {
+ theme.addCSSClass(n, "selected");
+ }
+
+ // Selection listeners
+ if (selectable && !disabled) {
+ if (!readonly) {
+ if (selectMode == "single") {
+ theme.addAddClassListener(theme,client,n,"click","selected",n,selected);
+ theme.addSetVarListener(theme,client,n,"click",selectionVariable,key,immediate);
+
+ } else if (selectMode == "multi") {
+ theme.addToggleClassListener(theme,client,n,"click","selected");
+ theme.addToggleVarListener(theme,client,n,"click",selectionVariable,key,immediate);
+
+ }
+ }
+ }
+
+ // Actions
+ if (!disabled && !readonly) {
+ for (var i = 0; i< node.childNodes.length;i++) {
+ var childNode = node.childNodes[i];
+ if (childNode.nodeName == "al" ) {
+ theme.renderActionPopup(renderer,childNode,n,actions,actionVar,key); // TODO check
+ }
+ }
+ }
+
+ // Render all sub-nodes
+ if (node.nodeName == "node") {
+ var subnodes = theme.createElementTo(target,"div","nodes");
+ if (node.childNodes != null && node.childNodes.length >0) {
+ img.src = theme.root + "img/tree/on.gif";
+ img.expanded = "true";
+ } else {
+ img.src = theme.root + "img/tree/off.gif";
+ img.expanded = "false";
+ }
+ for (var i = 0; i< node.childNodes.length;i++) {
+ var childNode = node.childNodes[i];
+ if (childNode.nodeName == "node" || childNode.nodeName == "leaf") {
+ theme.renderTreeNode(renderer,childNode,subnodes,selectable,selectMode,selected,selectionVariable,expandVariable,collapseVariable,actions,actionVar,immediate,disabled,readonly);
+ }
+ }
+
+ // Add event listener
+ if (!disabled) {
+ var target = (selectable&&!readonly?img:n);
+ theme.addToggleClassListener(theme,client,target,"mouseup","hidden",subnodes);
+ theme.addExpandNodeListener(theme,client,img,"mouseup",subnodes,expandVariable,collapseVariable,key,immediate,target);
+ theme.addStopListener(theme,client,target,"mouseup");
+ theme.addStopListener(theme,client,target,"click");
+ }
+
+ } else {
+ img.src = theme.root + "img/tree/empty.gif";
+ }
+
+}
+
+DefaultTheme.prototype.renderTextField = function(renderer,uidl,target, layoutInfo) {
+ var client = renderer.client;
+ var theme = renderer.theme;
+ var immediate = uidl.getAttribute("immediate") == "true";
+ var readonly = uidl.getAttribute("readonly") == "true";
+ var multiline = uidl.getAttribute("multiline") == "true";
+ var secret = uidl.getAttribute("secret") == "true";
+ var cols = uidl.getAttribute("cols");
+ var rows = uidl.getAttribute("rows");
+ var disabled = uidl.getAttribute("disabled") == "true";
+ var focusid = uidl.getAttribute("focusid");
+ var tabindex = uidl.getAttribute("tabindex");
+
+ // Create containing element
+ var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
+ if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
+
+ // Render default header
+ renderer.theme.renderDefaultComponentHeader(renderer,uidl,div, layoutInfo);
+
+ // Create border
+ var border = renderer.theme.createElementTo(div,"div","border");
+
+ // Create input
+ var input = null;
+ if (multiline) {
+ input = renderer.theme.createElementTo(border,"textarea");
+ if (focusid) {
+ input.focusid = focusid;
+ }
+ } else {
+ input = renderer.theme.createInputElementTo(border,(secret?"password":"text"),null,focusid);
+ }
+ if (tabindex) input.tabIndex = tabindex;
+ if (disabled||readonly) {
+ input.disabled = "true";
+ }
+
+
+ // Assign cols and rows
+ if (cols >0) {
+ if (multiline) {
+ input.cols = cols;
+ } else {
+ input.size = cols;
+ }
+ }
+ if (rows >0) {
+ input.rows = rows;
+ }
+
+ // Find variable node
+ var strNode = theme.getVariableElement(uidl,"string","text");
+ var inputId = strNode.getAttribute("id");
+ input.id = inputId;
+
+ // Assign value
+ strNode= theme.getFirstTextNode(strNode);
+ if (strNode != null && strNode.data != null) {
+ input.value = strNode.data;
+ }
+
+ // Listener
+ theme.addSetVarListener(theme,client,input,"change",inputId,input,immediate);
+
+}
+
+DefaultTheme.prototype.renderDateField = function(renderer,uidl,target,layoutInfo) {
+ // TODO needs simplification
+ // - jscalendar supports time! but not resolution?
+ // - dynamic .js loading!
+
+ var theme = renderer.theme;
+
+ // Create containing element
+ var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
+
+ if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
+
+ /* Styles:
+ * time - only time selection (no date)
+ */
+ var style = uidl.getAttribute("style");
+
+ var immediate = uidl.getAttribute("immediate") == "true";
+ var disabled = uidl.getAttribute("disabled") == "true";
+ var readonly = uidl.getAttribute("readonly") == "true";
+
+ /* locale, translate UI */
+ var locale = uidl.getAttribute("locale")
+ /*
+ if (locale && !disabled && !readonly) {
+ locale = locale.toLowerCase().split("_")[0];
+ var lang = renderer.client.loadDocument(theme.root+"jscalendar/lang/calendar-"+locale+".js",false);
+ if (lang) {
+ try {
+ window.eval(lang);
+ } catch (e) {
+ client.error("Could not eval DateField lang ("+locale+"):"+e );
+ }
+ }
+ }
+ */
+
+ // Render default header
+ renderer.theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
+
+ var yearVar = theme.getVariableElement(uidl,"integer","year");
+ var monthVar = theme.getVariableElement(uidl,"integer","month");
+ var dayVar = theme.getVariableElement(uidl,"integer","day");
+ var hourVar = theme.getVariableElement(uidl,"integer","hour");
+ var minVar = theme.getVariableElement(uidl,"integer","min");
+ var secVar = theme.getVariableElement(uidl,"integer","sec");
+ var msecVar = theme.getVariableElement(uidl,"integer","msec");
+
+ var year = null;
+ var month = null;
+ var day = null;
+ var hour = null;
+ var min = null;
+ var sec = null;
+ var msec = null;
+ var text = null;
+
+ var inputId = yearVar.getAttribute("id") + "_input";
+ var buttonId = yearVar.getAttribute("id") + "_button";
+
+ // Assign the value to textfield
+ var yearValue = yearVar != null? yearVar.getAttribute("value"): null;
+ var monthValue = monthVar != null? monthVar.getAttribute("value"): null;
+ var dayValue = dayVar != null? dayVar.getAttribute("value"): null;
+ var hourValue = hourVar != null? hourVar.getAttribute("value"): null;
+ var minValue = minVar != null? minVar.getAttribute("value"): null;
+ var secValue = secVar != null? secVar.getAttribute("value"): null;
+ var msecValue = msecVar != null? msecVar.getAttribute("value"): null;
+
+ if (style != "time") {
+ if (dayValue) {
+ // Using calendar - create textfield
+ if (readonly) {
+ text = theme.createTextNodeTo(div,dayValue+"."+monthValue+"."+yearValue);
+ } else {
+ text = theme.createInputElementTo(div,"text");
+ text.id = inputId;
+ text.size = "10";
+ if (disabled) {
+ text.disabled = true;
+ }
+ if (yearValue >0 && monthValue >0 && dayValue >0) {
+ text.value = dayValue+"."+monthValue+"."+yearValue;
+ } else {
+ text.value ="";
+ }
+ }
+
+ // Create button
+ var button = theme.createInputElementTo(div,"button");
+ button.id =buttonId;
+ button.value = "...";
+ if (disabled||readonly) {
+ button.disabled = true;
+ }
+ } else {
+ if (yearVar) {
+ // Year select
+ if (readonly) {
+ theme.createTextNodeTo(div,yearValue);
+ } else {
+ var year = theme.createElementTo(div,"select");
+ year.options[0] = new Option("",-1);
+ for (var i=0;i<2000;i++) {
+ year.options[i+1] = new Option(i+1900,i+1900);
+ if (yearValue == (i+1900)) {
+ year.options[i+1].selected = true;
+ }
+ }
+
+ if (disabled) {
+ year.disabled = true;
+ }
+ if (!readonly) theme.addSetVarListener(theme,client,year,"change",yearVar.getAttribute("id"),year,immediate);
+ }
+ }
+ if (monthVar) {
+ // Month select
+ if (readonly) {
+ theme.createTextNodeTo(div,"."+monthValue);
+ } else {
+ month = theme.createElementTo(div,"select");
+ month.options[0] = new Option("",-1);
+ for (var i=0;i<12;i++) {
+ month.options[i+1] = new Option(i+2,i+2);
+ if (monthValue == i+2) {
+ month.options[i+1].selected = true;
+ }
+ }
+ if (disabled) {
+ month.disabled = true;
+ }
+ if (!readonly) theme.addSetVarListener(theme,client,month,"change",monthVar.getAttribute("id"),month,immediate);
+ }
+ }
+ }
+ }
+ if (hourVar) {
+ if (readonly) {
+ theme.createTextNodeTo(div," "+(hourValue<10?"0"+hourValue:hourValue));
+ } else {
+ if (div.ownerDocument.__datefieldhourselect) {
+ hour = div.ownerDocument.__datefieldhourselect;
+ div.appendChild(hour);
+ div.ownerDocument.__datefieldhourselect = hour.cloneNode(true);
+ } else {
+ hour = theme.createElementTo(div,"select");
+ hour.options[0] = new Option("",-1);
+ for (var i=0;i<24;i++) {
+ var cap = (i+1<10?"0"+(i+1):(i+1));
+ if (!minVar) {
+ // Append anyway, makes it easier to recognize as time
+ cap = cap + ":00";
+ }
+ hour.options[i+1] = new Option(cap,i+1);
+ }
+ div.ownerDocument.__datefieldhourselect = hour.cloneNode(true);
+ }
+ if (hourValue) hour.options[parseInt(hourValue)+1].selected = true;
+ if (disabled) {
+ hour.disabled = true;
+ }
+ if (!readonly) theme.addSetVarListener(theme,client,hour,"change",hourVar.getAttribute("id"),hour,immediate);
+ }
+ }
+ if (minVar) {
+ // Minute select
+ if (readonly) {
+ theme.createTextNodeTo(div,":"+(minValue<10?"0"+minValue:minValue));
+ } else {
+ theme.createTextNodeTo(div,":");
+ if (div.ownerDocument.__datefieldminselect) {
+ min = div.ownerDocument.__datefieldminselect;
+ div.appendChild(min);
+ div.ownerDocument.__datefieldminselect = min.cloneNode(true);
+ } else {
+ min = theme.createElementTo(div,"select");
+ min.options[0] = new Option("",-1);
+ for (var i=0;i<60;i++) {
+ min.options[i+1] = new Option((i<10?"0"+(i):(i)),i);
+ }
+ div.ownerDocument.__datefieldminselect = min.cloneNode(true);
+ }
+ if (minValue) min.options[parseInt(minValue)+1].selected = true;
+ if (disabled) {
+ min.disabled = true;
+ }
+ if (!readonly) theme.addSetVarListener(theme,client,min,"change",minVar.getAttribute("id"),min,immediate);
+ }
+ }
+ if (secVar) {
+ // Second select
+ if (readonly) {
+ theme.createTextNodeTo(div,":"+(secValue<10?"0"+secValue:secValue));
+ } else {
+ theme.createTextNodeTo(div,":");
+ if (div.ownerDocument.__datefieldsecselect) {
+ sec = div.ownerDocument.__datefieldsecselect;
+ div.appendChild(sec);
+ div.ownerDocument.__datefieldsecselect = sec.cloneNode(true);
+ } else {
+ sec = theme.createElementTo(div,"select");
+ sec.options[0] = new Option("",-1);
+ for (var i=0;i<60;i++) {
+ sec.options[i+1] = new Option((i<10?"0"+(i):(i)),i);
+ }
+ div.ownerDocument.__datefieldsecselect = sec.cloneNode(true);
+ }
+ if (secValue) sec.options[parseInt(secValue)+1].selected = true;
+ if (disabled) {
+ sec.disabled = true;
+ }
+ if (!readonly) theme.addSetVarListener(theme,client,sec,"change",secVar.getAttribute("id"),sec,immediate);
+ }
+ }
+ if (msecVar) {
+ // Millisecond select
+ if (readonly) {
+ var cap = msecValue;
+ if (msecValue < 100) {
+ cap = "0"+cap;
+ }
+ if (msecValue < 10) {
+ cap = "0"+cap;
+ }
+ if (msecValue < 0) cap = "";
+ theme.createTextNodeTo(div,"."+cap);
+ } else {
+ var cap = msecValue;
+ if (msecValue < 100) {
+ cap = "0"+cap;
+ }
+ if (msecValue < 10) {
+ cap = "0"+cap;
+ }
+ if (msecValue < 0) cap = "";
+ theme.createTextNodeTo(div,".");
+ msec = theme.createInputElementTo(div,"text",null);
+ msec.value = cap;
+ msec.size = 3;
+ msec.setAttribute("maxlength", 3);
+ /*
+ msec = theme.createElementTo(div,"select");
+ msec.options[0] = new Option("",-1);
+ for (var i=0;i<1000;i++) {
+ var cap = i;
+ if (i < 100) {
+ cap = "0"+cap;
+ }
+ if (i < 10) {
+ cap = "0"+cap;
+ }
+ msec.options[i+1] = new Option(cap,i);
+ if (msecValue == i) {
+ msec.options[i+1].selected = true;
+ }
+ }
+ */
+ if (disabled) {
+ msec.disabled = true;
+ }
+ if (!readonly) theme.addSetVarListener(theme,client,msec,"change",msecVar.getAttribute("id"),msec,immediate);
+ }
+ }
+
+ if (!readonly) {
+ if (msec) theme.addDateFieldNullListener(client,msec,text,msec,sec,min,hour,day,month,year,yearVar,immediate);
+ if (sec) theme.addDateFieldNullListener(client,sec,text,msec,sec,min,hour,day,month,year,yearVar,immediate);
+ if (min) theme.addDateFieldNullListener(client,min,text,msec,sec,min,hour,day,month,year,yearVar,immediate);
+ if (hour) theme.addDateFieldNullListener(client,hour,text,msec,sec,min,hour,day,month,year,yearVar,immediate);
+ if (day) theme.addDateFieldNullListener(client,day,text,msec,sec,min,hour,day,month,year,yearVar,immediate);
+ if (month) theme.addDateFieldNullListener(client,month,text,msec,sec,min,hour,day,month,year,yearVar,immediate);
+ if (year) theme.addDateFieldNullListener(client,year,text,msec,sec,min,hour,day,month,year,yearVar,immediate);
+
+ }
+
+ var nullFunc = function () {
+ // TODO wierd when un-nulling
+ // -> serverside, examine
+ // + nulls in dropdowns!
+ text.value = "";
+ if (msec) {
+ msec.options[0].selected = true;
+ //client.changeVariable(msecVar.getAttribute("id"), -1, false);
+ }
+ if (sec) {
+ sec.options[0].selected = true;
+ //client.changeVariable(secVar.getAttribute("id"), -1, false);
+ }
+ if (min) {
+ min.options[0].selected = true;
+ //client.changeVariable(minVar.getAttribute("id"), -1, false);
+ }
+ if (hour) {
+ hour.options[0].selected = true;
+ //client.changeVariable(hourVar.getAttribute("id"), -1, false);
+ }
+ //client.changeVariable(dayVar.getAttribute("id"), -1, false);
+ //client.changeVariable(monthVar.getAttribute("id"), -1, false);
+ client.changeVariable(yearVar.getAttribute("id"), -1, immediate);
+ }
+
+ // Function that updates the datefield
+ var updateFunc = function (event) {
+ if (text.value == null || text.value == "") {
+ nullFunc();
+ return;
+ }
+ if (dayVar) {
+ var d = text.value.split(".")[0];
+ if (d == null || d < 1 || d > 31 ) alert("Error");
+ client.changeVariable(dayVar.getAttribute("id"), d, false);
+ }
+ if (monthVar) {
+ var m = text.value.split(".")[1];
+ if (m == null || m < 1 || m > 12) alert("Error");
+ client.changeVariable(monthVar.getAttribute("id"), m, false);
+ }
+ var y = text.value.split(".")[2];
+ if (y == null || y < 0 || y > 5000) alert("Error");
+ client.changeVariable(yearVar.getAttribute("id"), y, immediate);
+
+
+ };
+
+ if (!readonly && !disabled && style != "time" && dayVar) {
+ // Create a unique temporary variable
+ // Dont know if all this is needed, but its purpose is to avoid
+ // javascript problems with event handlers scopes.
+ var temp = "datefield_" + (new Date()).getTime();;
+ eval (temp + " = new Object();");
+ var tempObj = (eval (temp));
+ tempObj.update = function () { updateFunc() };
+ var st = "Calendar.setup({onUpdate : function () { " + temp +
+ ".update(); } ,inputField : '"+inputId+"', firstDay : 1,"+
+ " ifFormat : '%d.%m.%Y', button : '"+buttonId+"'});";
+
+ // Assign update function to textfield
+ text.onchange = updateFunc;
+
+ // TODO externalize:
+ // Assign initialization to button mouseover (lazy initialization)
+ //theme.addDateFieldInitListener(client,theme,button,temp,locale,st,disabled,readonly);
+
+
+ client.addEventListener(button, "mouseover", function(event) {
+ if (!eval(temp).initialized) {
+ eval(temp).initialized =true;
+ if (locale && !disabled && !readonly) {
+ locale = locale.toLowerCase().split("_")[0];
+ var lang = renderer.client.loadDocument(theme.root+"jscalendar/lang/calendar-"+locale+".js",false);
+ if (lang) {
+ try {
+ window.eval(lang);
+ } catch (e) {
+ client.error("Could not eval DateField lang ("+locale+"):"+e );
+ }
+ }
+ }
+ eval(st);
+ }
+ }
+ );
+
+
+ }
+
+}
+DefaultTheme.prototype.addDateFieldInitListener = function(client,theme,button,temp,locale,st,disabled,readonly) {
+ client.addEventListener(button, "mouseover", function(event) {
+ if (!eval(temp).initialized) {
+ eval(temp).initialized =true;
+ if (locale && !disabled && !readonly) {
+ locale = locale.toLowerCase().split("_")[0];
+ var lang = renderer.client.loadDocument(theme.root+"jscalendar/lang/calendar-"+locale+".js",false);
+ if (lang) {
+ try {
+ window.eval(lang);
+ } catch (e) {
+ client.error("Could not eval DateField lang ("+locale+"):"+e );
+ }
+ }
+ }
+ eval(st);
+ client.removeAllEventListeners(button);
+ }
+ }
+ );
+}
+DefaultTheme.prototype.addDateFieldNullListener = function (client,elm,text,msec,sec,min,hour,day,month,year,yearVar,immediate) {
+ client.addEventListener(elm, "change", function(event) {
+
+ if ( !elm || (elm.value != -1 && elm.value != "")) return;
+
+
+ if (text) text.value = "";
+
+ if (msec) {
+ //msec.options[0].selected = true;
+ msec.value = "";
+ //client.changeVariable(msecVar.getAttribute("id"), -1, false);
+ }
+ if (sec) {
+ sec.options[0].selected = true;
+ //client.changeVariable(secVar.getAttribute("id"), -1, false);
+ }
+ if (min) {
+ min.options[0].selected = true;
+ //client.changeVariable(minVar.getAttribute("id"), -1, false);
+ }
+ if (hour) {
+ hour.options[0].selected = true;
+ //client.changeVariable(hourVar.getAttribute("id"), -1, false);
+ }
+ if (day) {
+ hour.options[0].selected = true;
+ //client.changeVariable(hourVar.getAttribute("id"), -1, false);
+ }
+ if (month) {
+ hour.options[0].selected = true;
+ //client.changeVariable(hourVar.getAttribute("id"), -1, false);
+ }
+ if (year) {
+ hour.options[0].selected = true;
+ //client.changeVariable(hourVar.getAttribute("id"), -1, false);
+ }
+ //client.changeVariable(dayVar.getAttribute("id"), -1, false);
+ //client.changeVariable(monthVar.getAttribute("id"), -1, false);
+ client.changeVariable(yearVar.getAttribute("id"), -1, immediate);
+ });
+}
+
+
+
+DefaultTheme.prototype.renderDateFieldCalendar = function(renderer,uidl,target,layoutInfo) {
+
+ var theme = renderer.theme;
+
+ // Create containing element
+ var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
+ if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
+
+ // Render default header
+ renderer.theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
+
+ var immediate = uidl.getAttribute("immediate") == "true";
+ var enabled = uidl.getAttribute("enabled") == "true";
+ var readonly = uidl.getAttribute("readonly") == "true";
+ var yearVar = theme.getVariableElement(uidl,"integer","year");
+ var monthVar = theme.getVariableElement(uidl,"integer","month");
+ var dayVar = theme.getVariableElement(uidl,"integer","day");
+ var hourVar = theme.getVariableElement(uidl,"integer","hour");
+ var minVar = theme.getVariableElement(uidl,"integer","minutes");
+ var secVar = theme.getVariableElement(uidl,"integer","seconds");
+ var msecVar = theme.getVariableElement(uidl,"integer","millseconds");
+
+ var showTime = hourVar != null;
+ var inputId = yearVar.getAttribute("id") + "_input";
+
+ // Create container DIV
+ var calDiv = theme.createElementTo(div,"div");
+ calDiv.id = inputId;
+
+ // Assign the value to textfield
+ var yearValue = yearVar != null? yearVar.getAttribute("value"): -1;
+ var monthValue = monthVar != null? monthVar.getAttribute("value"): -1;
+ var dayValue = dayVar != null? dayVar.getAttribute("value"): -1;
+ var hourValue = hourVar != null? hourVar.getAttribute("value"): -1;
+ var minValue = minVar != null? minVar.getAttribute("value"): -1;
+ var secValue = secVar != null? secVar.getAttribute("value"): -1;
+ var msecValue = msecVar != null? msecVar.getAttribute("value"): -1;
+ if (yearValue >0 && monthValue >0 && dayValue >0) {
+ //TODO Assign date
+ } else {
+ //TODO Assign date
+ }
+
+
+ // Create a unique temporary variable
+ // Dont know if all this is needed, but its purpose is to avoid
+ // javascript problems with event handlers scopes.
+ var temp = "datefield_" + (new Date()).getTime();;
+ eval (temp + " = new Object();");
+
+ // Function that updates the datefield
+ var dateChanged = function (cal) {
+ var y = cal.date.getFullYear();
+ var m = cal.date.getMonth();
+ var d = cal.date.getDate();
+ if (d == null || y == null || m == null || d < 1 ||
+ d > 31 || m < 1 || m > 12 || y < 0 || y > 5000) alert("Error");
+ client.changeVariable(dayVar.getAttribute("id"), d, false);
+ client.changeVariable(monthVar.getAttribute("id"), m, false);
+ client.changeVariable(yearVar.getAttribute("id"), y, immediate);
+ };
+
+ // Calendar setup code
+ (eval (temp)).update = dateChanged;
+ var st = "Calendar.setup({flatCallback : function (cal) { " + temp +
+ ".update(cal); } ,showsTime: "+showTime+", flat: '"+inputId+"', firstDay : 1,"+
+ " ifFormat : '%d.%m.%Y'});";
+
+
+ // Assign initialization to button mouseover (lazy initialization)
+ client.addEventListener(div, "mouseover", function(event) {
+ if (!eval(temp).initialized) {
+ eval(temp).initialized =true;
+ eval(st);
+
+ }
+ }
+ );
+
+}
+
+
+DefaultTheme.prototype.renderUpload = function(renderer,uidl,target,layoutInfo) {
+
+ var theme = renderer.theme;
+ var client = renderer.client;
+ var varNode = theme.getVariableElement(uidl,"uploadstream","stream");
+
+ // Create containing element
+ var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
+ if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
+
+ var caption = uidl.getAttribute("caption")||"Send";
+
+
+ // Render default header
+ renderer.theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
+
+ // Unique name for iframes
+ var frameName = "upload_"+varNode.getAttribute("id")+"_iframe";
+
+ var iframe = theme.createElementTo(div, "iframe");
+ iframe.style.width = '350px';
+ iframe.style.height = '30px';
+ iframe.id = frameName;
+ iframe.name = frameName;
+ iframe.src = 'about:blank';
+ iframe.style.border = 'none';
+ iframe.style.margin = '0px';
+ iframe.style.padding = '0px';
+ iframe.style.background = 'none';
+
+
+ var win = target.ownerDocument.ownerWindow;
+ // Get the window object of the iframe
+ var ifr = win.frames[frameName];
+
+ // TODO: FF fix. The above does not work in FF, so we
+ // have to work our way around it. Iterate all frames.
+ if (ifr == null) {
+ var fi = 0;
+ while (fi < win.frames.length) {
+ if (win.frames[fi].frameElement != null && win.frames[fi].frameElement.name == frameName) {
+ ifr = win.frames[fi];
+ }
+ fi++;
+ }
+ }
+
+ if (ifr != null) {
+
+ // TODO: Put some initial content to IFRAME.
+ // Nasty, but without this the browsers fail
+ // to create any elements into window.
+ var code="<HTML>"+"<BODY STYLE=\" overflow: hidden; border: none; margin: 0px; padding: 0px;\"><\/BODY><\/HTML>";
+ ifr.document.open();
+ ifr.document.write(code);
+ ifr.document.close();
+
+
+ // Ok. Now we are ready render the actual upload form and
+ // inputs.
+ var form = ifr.document.createElement('form');
+ form.setAttribute("action",client.ajaxAdapterServletUrl);
+ form.setAttribute("method", "post");
+ form.setAttribute("enctype", "multipart/form-data");
+ if (document.all) {
+ form = ifr.document.createElement('<form action="'+client.ajaxAdapterServletUrl+'" method="post" enctype="multipart/form-data">');
+ }
+ var upload = theme.createInputElementTo(form, "file");
+ upload.id = varNode.getAttribute("id");
+ upload.name = varNode.getAttribute("id");
+ var submit = theme.createInputElementTo(form, "submit");
+ submit.value = caption;
+ submit.disabled = true;
+ upload.onchange = function() {
+ if(upload.value) {
+ submit.disabled = false;
+ } else {
+ submit.disabled = true;
+ }
+ }
+ ifr.document.body.appendChild(form);
+
+ // Attach event listeners for processing the chencges after upload.
+ if (document.all) {
+ iframe.onreadystatechange = function() {
+ if (iframe.readyState == "complete") {
+ iframe.onreadystatechange = null;
+ client.processUpdates(ifr.document.XMLDocument);
+ }
+ };
+ } else {
+ iframe.onload = function() {
+ if (ifr.document != null && (ifr.document.contentType == "application/xml")) {
+ iframe.onload = null;
+ client.processUpdates(ifr.document);
+ }
+ };
+ }
+
+ }
+}
+
+DefaultTheme.prototype.renderEmbedded = function(renderer,uidl,target,layoutInfo) {
+
+ var theme = renderer.theme;
+
+ // Create containing element
+ var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
+ if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
+
+ // Render default header
+ renderer.theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
+
+ if (uidl.getAttribute("type") == "image") {
+
+ // Image mode
+ var img = renderer.theme.createElementTo(div,"img","embedded");
+
+ // SRC
+ var val = uidl.getAttribute("src");
+ if (val != null) img.src = val;
+
+ // Width
+ val = uidl.getAttribute("width");
+ if (val != null && val > 0) img.width = val;
+
+ // Height
+ val = uidl.getAttribute("height");
+ if (val != null && val > 0) img.height = val;
+
+ // ALT-attribute
+ img.alt = theme.getElementContent(uidl,"description");
+ } else {
+
+ /*
+ // Object mode
+ var embedded = renderer.theme.createElementTo(div,"object","embedded");
+ // SRC
+ var val = uidl.getAttribute("src");
+ if (val) embedded.src = val;
+
+
+ // Width
+ val = uidl.getAttribute("width");
+ if (val != null && val > 0) embedded.width = val;
+
+ // Height
+ val = uidl.getAttribute("height");
+ if (val != null && val > 0) embedded.height = val;
+
+ // Codebase
+ val = uidl.getAttribute("codebase");
+ if (val != null) embedded.codebase = val;
+
+ // Standby
+ val = uidl.getAttribute("standby");
+ if (val != null) embedded.codebase = val;
+ */
+
+ var html = "<object ";
+ var val = uidl.getAttribute("src");
+ if (val) html += " data=\""+val+"\" ";
+
+ val = uidl.getAttribute("width");
+ if (val) html += " width=\""+val+"\" ";
+
+ val = uidl.getAttribute("height");
+ if (val) html += " height=\""+val+"\" ";
+
+ val = uidl.getAttribute("codebase");
+ if (val) html += " codebase=\""+val+"\" ";
+
+ val = uidl.getAttribute("standby");
+ if (val) html += " standby=\""+val+"\" ";
+
+ html += ">";
+
+ // Add all parameters
+ var params = theme.getChildElements(uidl,"embeddedparams");
+ if (params != null) {
+ var len = params.length;
+ for (var i=0;i<len;i++) {
+ html += "<param name=\""+params[i].getAttribute("name")+"\" value=\""+params[i].getAttribute("name")+"\" />"
+ }
+ }
+
+ html += "</object>";
+
+ div.innerHTML = html;
+ }
+}
+
+DefaultTheme.prototype.renderLink = function(renderer,uidl,target,layoutInfo) {
+ // Shortcut variables
+ var theme = renderer.theme;
+ var client = renderer.client;
+
+ var immediate = "true"==uidl.getAttribute("immediate");
+ var disabled = "true"==uidl.getAttribute("disabled");
+ var readonly = "true"==uidl.getAttribute("readonly");
+
+ var targetName = uidl.getAttribute("name");
+ var width = uidl.getAttribute("width");
+ var height = uidl.getAttribute("height");
+ var border = uidl.getAttribute("border");
+ var src = uidl.getAttribute("src");
+ if (src && src.indexOf("theme://") == 0) {
+ src = theme.root + src.substring(8);
+ }
+
+ // Create containing element
+ var div = theme.createPaintableElement(renderer,uidl,target,layoutInfo);
+ if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
+
+ var link = theme.createElementTo(div,"div", "link pad clickable");
+
+ if (!disabled&&!readonly) {
+ theme.addAddClassListener(theme,client,div,"mouseover","over");
+ theme.addRemoveClassListener(theme,client,div,"mouseout","over");
+
+ var feat;
+ switch (border) {
+ case "minimal":
+ feat = "menubar=yes,location=no,status=no";
+ break;
+ case "none":
+ feat = "menubar=no,location=no,status=no";
+ break;
+ default:
+ feat = "menubar=yes,location=yes,scrollbars=yes,status=yes";
+ break;
+ }
+ if (width||height) {
+ feat += ",resizable=no";
+ feat += (width?",width="+width:"");
+ feat += (height?",height="+height:"");
+ } else {
+ feat += ",resizable=yes";
+ }
+ theme.addLinkOpenWindowListener(theme,client,div,"click",src,targetName,feat);
+ }
+ /*
+ with(props) {
+ client.addEventListener(div,"mouseover", function(e) {
+ theme.addCSSClass(div,"over");
+ }
+ );
+ client.addEventListener(div,"mouseout", function(e) {
+ theme.removeCSSClass(div,"over");
+ }
+ );
+ client.addEventListener(div,"click", function(e) {
+ theme.hidePopup();
+ if (!target) {
+ window.location = src;
+ } else {
+ var feat;
+ switch (border) {
+ case "minimal":
+ feat = "menubar=yes,location=no,status=no";
+ break;
+ case "none":
+ feat = "menubar=no,location=no,status=no";
+ break;
+ default:
+ feat = "menubar=yes,location=yes,scrollbars=yes,status=yes";
+ break;
+ }
+ if (width||height) {
+ feat += ",resizable=no"
+ } else {
+ feat += ",resizable=yes"
+ }
+ var win = window.open(src, target,
+ feat
+ +(width?",width="+width:"")
+ +(height?",height="+height:"")
+ );
+ win.focus();
+ }
+ }
+ );
+ }
+ */
+ //var inner = theme.createElementTo(div,"div", "border pad");
+
+ // Render default header
+ theme.renderDefaultComponentHeader(renderer,uidl,link);
+
+ // Description under link
+ var descriptionText = theme.getElementContent(uidl,"description");
+ if (descriptionText) {
+ var desc = theme.createElementTo(link,"div", "description");
+ theme.createTextNodeTo(desc,descriptionText);
+ }
+}
+DefaultTheme.prototype.addLinkOpenWindowListener = function(theme,client,element,event,url,target,features) {
+ client.addEventListener(element,(event=="rightclick"?"click":event), function(e) {
+ var evt = client.getEvent(e);
+ if (event=="rightclick"&&!evt.rightclick) return;
+ if (!target) {
+ window.location = url;
+ } else {
+ var win = window.open(url, target, features);
+ win.focus();
+ }
+ }
+ );
+}
+DefaultTheme.prototype.renderTable = function(renderer,uidl,target,layoutInfo) {
+ // Shortcut variables
+ var theme = renderer.theme;
+ var client = renderer.client;
+
+ // Create containing DIV
+ var div = theme.createPaintableElement(renderer,uidl,target,layoutInfo);
+ if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
+
+ if ("list"==uidl.getAttribute("style")) {
+ theme.removeCSSClass(div,"table");
+ theme.addCSSClass(div,"list");
+ }
+ // Create default header
+ var caption = theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
+
+ // Get table attributes
+ var rowheaders = ("true"==uidl.getAttribute("rowheaders"));
+ var totalrows = parseInt(uidl.getAttribute("totalrows"));
+ var pagelength = parseInt(uidl.getAttribute("pagelength"));
+ var rowCount = parseInt(uidl.getAttribute("rows"));
+ var firstvisible = theme.getVariableElementValue(theme.getVariableElement(uidl,"integer","firstvisible"))||1;
+ var firstvisibleVar = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"integer","firstvisible"));
+ var immediate = ("true" == uidl.getAttribute("immediate"));
+ var selectMode = uidl.getAttribute("selectmode");
+ var selectable = selectMode == "multi" || selectMode == "single";
+ var selected; // Selected map
+ if (selectable) {
+ selected = new Array();
+ }
+ var selectionVariable = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","selected"));
+ var visibleCols = theme.getFirstElement(uidl,"visiblecolumns");
+ var collapseVariable = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","collapsedcolumns"));
+ var sortcolVar = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"string","sortcolumn"));
+ var sortkey = theme.getVariableElementValue(theme.getVariableElement(uidl,"string","sortcolumn"));
+ var sortasc = theme.getVariableElement(uidl,"boolean","sortascending");
+ var sortascVar = theme.createVariableElementTo(div,sortasc);
+ sortasc = sortasc != null && "true"==sortasc.getAttribute("value");
+
+ var actions = null;
+ var actionVar = null;
+ var alNode = theme.getFirstElement(uidl,"actions")
+ if (alNode) {
+ actionVar = theme.createVariableElementTo(div,theme.getVariableElement(alNode,"string","action"));
+ actions = new Object();
+ var ak = alNode.getElementsByTagName("action");
+ for (var i=0;i<ak.length;i++) {
+ actions[ak[i].getAttribute("key")] = ak[i].getAttribute("caption");
+ }
+ }
+ delete alNode;
+
+ // Create table for content
+ div = theme.createElementTo(div,"div","outset");
+ div = theme.createElementTo(div,"div","content border");
+
+ var table = theme.createElementTo(div,"table");
+ table = theme.createElementTo(table,"tbody");
+ table.setAttribute("cellpadding","0");
+ table.setAttribute("cellspacing","0");
+ var tr = null;
+ var td = null;
+
+
+ // Column headers
+ var cols = theme.getFirstElement(uidl,"cols");
+ if (cols != null) {
+ cols = cols.getElementsByTagName("ch");
+ }
+ if (cols != null && cols.length >0) {
+ tr = theme.createElementTo(table,"tr","header");
+ if (rowheaders) {
+ theme.createElementTo(tr,"td","empty");
+ }
+ for (var i=0; i<cols.length;i++) {
+ var sortable = cols[i].getAttribute("sortable");
+ td = theme.createElementTo(tr,"td","cheader bg");
+ // Sorting
+ var key = cols[i].getAttribute("cid");
+ if (sortable=="true") {
+ theme.addCSSClass(td,"clickable");
+ // Sorting always immediate
+ theme.addSetVarListener(theme,client,td,"click",sortascVar,(key==sortkey?!sortasc:sortasc),false);
+ theme.addSetVarListener(theme,client,td,"click",sortcolVar,key,true);
+
+ }
+ var ch = cols[i].getAttribute("caption");
+ var cap = theme.createElementTo(td,"div","caption");
+ theme.createTextNodeTo(cap,ch != null? ch : "");
+ if (sortkey==key) {
+ var icon = theme.createElementTo(cap,"IMG","icon");
+ icon.src = theme.root+"img/table/"+(sortasc?"asc.gif":"desc.gif");
+ }
+ }
+
+ // Collapsing
+ td = theme.createElementTo(tr,"td","cheader scroll bg");
+ if (visibleCols) {
+ var iconDiv = theme.createElementTo(td,"div");
+ var icon = theme.createElementTo(iconDiv,"img","icon");
+ icon.src = theme.root+"/img/table/colsel.gif";
+ var popup = theme.createElementTo(td,"div","outset popup hide");
+ var inner = theme.createElementTo(popup,"div","border");
+ // empty row to allow closing:
+ var row = theme.createElementTo(inner,"div","item clickable pad border");
+
+ theme.addHidePopupListener(theme,client,row,"click");
+ theme.addToggleClassListener(theme,client,row,"mouseover","over");
+ theme.addToggleClassListener(theme,client,row,"mouseout","over");
+ theme.addTogglePopupListener(theme,client,iconDiv,"click",popup);
+
+ var cols = visibleCols.getElementsByTagName("column");
+ for (var i=0;i<cols.length;i++) {
+ var row = theme.createElementTo(inner,"div","item clickable pad border");
+ var collapsed = "true"==cols[i].getAttribute("collapsed");
+ icon = theme.createElementTo(row,"img","icon");
+ icon.src = theme.root+"/img/table/"+(collapsed?"off.gif":"on.gif");
+ theme.createTextNodeTo(row,cols[i].getAttribute("caption"));
+
+ theme.addToggleClassListener(theme,client,row,"mouseover","over");
+ theme.addToggleClassListener(theme,client,row,"mouseout","over");
+ theme.addToggleVarListener(theme,client,row,"click",collapseVariable,cols[i].getAttribute("cid"),true);
+ }
+ delete cols;
+ }
+ }
+ delete cols;
+
+ // Table rows
+ var rows = theme.getFirstElement(uidl,"rows");
+ if (rows != null) {
+ rows = theme.getChildElements(rows,"tr");
+ }
+ if (rows != null && rows.length >0) {
+ for (var i=0; i<rows.length;i++) {
+ tr = theme.createElementTo(table,"tr");
+ // TODO rowheader
+ theme.setCSSClass(tr, (i % 2 == 0?"even":"odd"));
+
+ if (selectable) theme.addCSSClass(tr, "clickable");
+ var key = rows[i].getAttribute("key");
+
+ if (selectable&&"true"==rows[i].getAttribute("selected")) {
+ theme.addCSSClass(tr, "selected");
+ selected[selected.length] = tr;
+ }
+
+ if (selectable) {
+ if (selectMode == "multi") {
+ theme.addToggleClassListener(theme,client,tr,"click","selected");
+ theme.addToggleVarListener(theme,client,tr,"click",selectionVariable,key,immediate);
+ } else {
+ theme.addAddClassListener(theme,client,tr,"click","selected",tr,selected);
+ theme.addSetVarListener(theme,client,tr,"click",selectionVariable,key,immediate);
+ }
+ }
+
+ if (rowheaders) {
+ var td = theme.createElementTo(tr,"td","rheader bg");
+ var caption = theme.createElementTo(td,"div","caption");
+ theme.createTextNodeTo(caption,rows[i].getAttribute("caption"));
+ }
+ if (rows[i].childNodes != null && rows[i].childNodes.length >0) {
+ var al = null;
+ for (var j=0; j<rows[i].childNodes.length;j++) {
+ if (rows[i].childNodes[j].nodeName == "al") {
+ al = rows[i].childNodes[j];
+ } else if (rows[i].childNodes[j].nodeType == Node.ELEMENT_NODE) {
+ td = theme.createElementTo(tr,"td");
+ renderer.client.renderUIDL(rows[i].childNodes[j],td);
+ if (al) {
+ theme.renderActionPopup(renderer,al,td,actions,actionVar,key);
+ }
+ }
+ }
+ }
+ // SCROLLBAR
+ if (i==0) {
+ td = theme.createElementTo(tr,"td", "scroll border");
+ // TODO:
+ //theme.tableAddScrollEvents(theme,td);
+
+ td.setAttribute("rowSpan",rows.length);
+ var inner = theme.createElementTo(td,"div", "scroll");
+ }
+ }
+ }
+ delete rows;
+
+ var paging = theme.createElementTo(div,"div","nav pad");
+ var button = theme.createElementTo(paging,"div","pad caption inline");
+ if (firstvisible > 1) {
+ theme.addCSSClass(button,"clickable");
+ theme.addAddClassListener(theme,client,button,"mouseover","bg");
+ theme.addRemoveClassListener(theme,client,button,"mouseout","bg");
+ theme.addSetVarListener(theme,client,button,"click",firstvisibleVar,(parseInt(firstvisible)-parseInt(pagelength)),true);
+ } else {
+ theme.addCSSClass(button,"disabled");
+ }
+ theme.createTextNodeTo(button,"<<");
+
+ button = theme.createElementTo(paging,"div","small pad inline");
+ theme.createTextNodeTo(button,firstvisible+" - "+(firstvisible-1+parseInt(rowCount))+ " / " + totalrows);
+
+ button = theme.createElementTo(paging,"div","pad caption inline");
+ if (parseInt(firstvisible)+parseInt(pagelength)<=parseInt(totalrows)) {
+ theme.addCSSClass(button,"clickable");
+ theme.addAddClassListener(theme,client,button,"mouseover","bg");
+ theme.addRemoveClassListener(theme,client,button,"mouseout","bg");
+ theme.addSetVarListener(theme,client,button,"click",firstvisibleVar,(parseInt(firstvisible)+parseInt(pagelength)),true);
+ } else {
+ theme.addCSSClass(button,"disabled");
+ }
+ theme.createTextNodeTo(button,">>");
+}
+
+DefaultTheme.prototype.renderScrollTable = function(renderer,uidl,target,layoutInfo) {
+ // Shortcut variables
+ var theme = renderer.theme;
+ var client = renderer.client;
+ var colWidths;
+ if (target.colWidths) {
+ colWidths = target.colWidths;
+ } else {
+ colWidths = new Object();
+ }
+ var wholeWidth = target.wholeWidth;
+ var scrolledLeft = target.scrolledLeft;
+
+ // Get attributes
+ var pid = uidl.getAttribute("id");
+ var immediate = uidl.getAttribute("immediate")||false;
+ var selectmode = uidl.getAttribute("selectmode");
+ var cols = parseInt(uidl.getAttribute("cols"));
+ var rows = parseInt(uidl.getAttribute("rows"));
+ var totalrows = parseInt(uidl.getAttribute("totalrows"));
+ var pagelength = uidl.getAttribute("pagelength");
+ var colheaders = uidl.getAttribute("colheaders")||false;
+ var rowheaders = uidl.getAttribute("rowheaders")||false;
+ var visiblecols = theme.getFirstElement(uidl,"visiblecolumns");
+ var sortkey = theme.getVariableElementValue(theme.getVariableElement(uidl,"string","sortcolumn"));
+
+ var colorder = new Array();
+ var fv = parseInt(theme.getVariableElementValue(theme.getVariableElement(uidl,"integer","firstvisible"))||1);
+ var selected; // Selected map
+ if (selectmode) {
+ selected = new Array();
+ }
+
+ // Create containing DIV
+ var div = theme.createPaintableElement(renderer,uidl,target,layoutInfo);
+ div.colWidths = colWidths;
+ if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
+
+ // Variables
+ var fvVar = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"integer","firstvisible"));
+ var ccVar = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","collapsedcolumns"));
+ var coVar = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","columnorder"));
+ var selVar = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","selected"));
+ var sortVar = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"string","sortcolumn"));
+ var sortasc = theme.getVariableElement(uidl,"boolean","sortascending");
+ var sortascVar = theme.createVariableElementTo(div,sortasc);
+ sortasc = (sortasc != null && "true"==sortasc.getAttribute("value"));
+
+ // Create default header
+ //var caption = theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
+ // column collapsing
+
+ // Renewed theme, 9.6.2006 - Jouni Koivuviita
+ // Table container divs
+ var capsule = theme.createElementTo(div,"div","header");
+ var capsuleContent; // pointer, in which the actual table is fitted
+ if(uidl.getAttribute("caption")) {
+ capsule.innerHTML = "<div class=\"left\"></div><div class=\"title\"></div><div class=\"right\"></div>";
+ var caption = theme.renderDefaultComponentHeader(renderer,uidl,capsule.childNodes[1],layoutInfo);
+ }
+ div.innerHTML += "<div class=\"top\"><div class=\"right\"></div><div class=\"left\"></div></div><div id=\""+pid+"-tablecontent\" class=\"middle\"></div><div class=\"bottom\"><div class=\"right\"></div><div class=\"left\"></div></div>";
+ var tableContent = div.ownerDocument.getElementById(pid + "-tablecontent");
+
+ // main div
+ //var inner = theme.createElementTo(div,"div","border");
+ var inner = tableContent;
+ inner.innerHTML = "<TABLE width=\"100%\"><TR><TD></TD></TR></TABLE>";
+ if (!wholeWidth) {
+ wholeWidth = inner.offsetWidth||inner.clientWidth||300;
+ wholeWidth -= 2; // Leave room for border, TODO: more dynamic
+ if (wholeWidth<200) wholeWidth = 300;
+ }
+ div.wholeWidth = wholeWidth;
+ var offsetLeft = client.getElementPosition(inner).x;
+
+ // Actions
+ var actions = null;
+ var actionVar = null;
+ var alNode = theme.getFirstElement(uidl,"actions")
+ if (alNode) {
+ actionVar = theme.createVariableElementTo(div,theme.getVariableElement(alNode,"string","action"));
+ actions = new Object();
+ var ak = alNode.getElementsByTagName("action");
+ for (var i=0;i<ak.length;i++) {
+ actions[ak[i].getAttribute("key")] = ak[i].getAttribute("caption");
+ }
+ }
+ delete alNode;
+
+ inner.innerHTML = "<DIV id=\""+pid+"status\" align=\"center\" class=\"abs border pad\" style=\"width:"+(wholeWidth/2)+"px;background-color:white;display:none;\"></DIV><TABLE cellpadding=0 cellspacing=0 border=0 width=100%><TBODY><TR valign=top><TD></TD><TD width=16></TD></TR></TBODY></TABLE><TABLE>";
+ //inner.style.width = wholeWidth+"px";
+ var vcols = inner.childNodes[1].firstChild.firstChild.childNodes[1];
+ if (visiblecols) {
+ vcols.innerHTML = "<IMG class=\"icon\" src=\""+theme.root+"img/table/colsel.gif\"/>";
+ var icon = vcols.firstChild;
+ vcols.id = pid+"vcols";
+ var popup = theme.createElementTo(div,"div","border popup hide");
+ theme.addTogglePopupListener(theme,client,icon,"click",popup);
+ theme.addStopListener(theme,client,icon,"mouseover");
+ theme.addStopListener(theme,client,icon,"mouseout");
+ var row = theme.createElementTo(popup,"div","item clickable pad border");
+ theme.addHidePopupListener(theme,client,row,"click");
+ var cols = visiblecols.getElementsByTagName("column");
+ for (var i=0;i<cols.length;i++) {
+ var row = theme.createElementTo(popup,"div","item clickable pad border");
+ var collapsed = "true"==cols[i].getAttribute("collapsed");
+ icon = theme.createElementTo(row,"img","icon");
+ icon.src = theme.root+"/img/table/"+(collapsed?"off.gif":"on.gif");
+ theme.createTextNodeTo(row,cols[i].getAttribute("caption"));
+ theme.addAddClassListener(theme,client,row,"mouseover","over");
+ theme.addRemoveClassListener(theme,client,row,"mouseout","over");
+ theme.addToggleVarListener(theme,client,row,"click",ccVar,cols[i].getAttribute("cid"),true);
+ }
+ delete cols;
+ }
+
+
+ // FIRST render the table
+ var alignments = new Array();
+
+ // headers
+ var hout = theme.createElementTo(inner.childNodes[1].firstChild.firstChild.firstChild,"div","col-headers");
+ hout.style.width = (wholeWidth-16)+"px";
+ hout.style.paddingRight = "0px";
+ hout.id = pid+"hout";
+ hout.style.overflow = "hidden";
+ var html = "<TABLE id=\""+pid+"hin\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><TBODY><TR>";
+ if (rowheaders) {
+ html += "<TD ";
+ if (colWidths["heh"]) {
+ html += "width=\""+colWidths["heh"]+"\" ";
+ }
+ html += "style=\"overflow:hidden\" cid=\"heh\" id=\""+pid+"heh\"><DIV class=\"padnr\" style=\"";
+ if (colWidths["heh"]) {
+ html += "width:"+colWidths["heh"]+"px;";
+ }
+ html += "overflow:hidden;height:100%;white-space:nowrap;border-right:1px solid #cdcdcd;\"><IMG id=\""+pid+"hah\" align=\"right\" src=\""+theme.root+"img/table/handle.gif\" border=\"0\" style=\"height:100%;width:3px;cursor:w-resize;\"></DIV></TD>";
+ }
+ var chs = theme.getFirstElement(uidl, "cols").getElementsByTagName("ch");
+ var len = chs.length;
+ for (var i=0;i<len;i++) {
+ var col = chs[i];
+ var cap = col.getAttribute("caption")||(visiblecols?"":"");
+ var hheight = (cap?"1.5em":"5px");
+ var sort = col.getAttribute("sortable");
+ var cid = col.getAttribute("cid");
+ var iconUrl = col.getAttribute("icon");
+ if (iconUrl && iconUrl.indexOf("theme://") == 0) {
+ iconUrl = (theme.iconRoot != null ? theme.iconRoot : theme.root)
+ + iconUrl.substring(8);
+ }
+ alignments[i] = col.getAttribute("align");
+ colorder[i] = cid;
+ html += "<TD ";
+ if (colWidths[cid]) {
+ html += "width=\""+colWidths[cid]+"\" ";
+ }
+ if (sortkey == cid) {
+ html += "sorted=\"true\" ";
+ }
+ html += "style=\"overflow:hidden\" cid=\""+cid+"\" id=\""+pid+"he"+i+"\" >"
+ html += "<DIV class=\"padnr\" ";
+ if (alignments[i]) {
+ switch (alignments[i]) {
+ case "e":
+ html += "align=\"right\"";
+ break;
+ case "c":
+ html += "align=\"center\"";
+ break;
+ default:
+ }
+ }
+ html += " style=\"";
+ if (colWidths[cid]) {
+ html += "width:"+colWidths[cid]+"px;";
+ }
+ html += "overflow:hidden;font-weight:bold;height:100%;white-space:nowrap;border-right:1px solid #cdcdcd;\"><IMG id=\""+pid+"ha"+cid+"\" align=\"right\" src=\""+theme.root+"img/table/handle.gif\" border=\"0\" style=\"height:"+hheight+";width:4px;cursor:w-resize;\">";
+ html += (iconUrl?"<IMG src=\""+iconUrl+"\" class=\"icon\">":"")+cap+"</DIV></TD>";
+ }
+ html += "</TR></TBODY></TABLE>";
+ hout.innerHTML = html;
+
+ // content
+ // scroll padding calculations
+ // TODO these need to be calculated better, perhaps updated after rendering content
+ var rowHeight = 22;
+ var prePad = (fv==1?1:fv*rowHeight);
+ var postPad = (totalrows-fv-rows+1)*rowHeight;
+ // html
+ cout = theme.createElementTo(inner,"div");
+ cout.style.width = wholeWidth+"px";
+ cout.style.height = ((hout.offsetHeight>18?hout.offsetHeight:18)*pagelength)+"px";
+ cout.id = pid+"cout";
+ cout.style.overflow = "auto";
+ html = "<TABLE border=\"0\" cellpadding=\"0\" cellspacing=\"0\" id=\""+pid+"cin\"><TBODY><TR height=\""+prePad+"\"></TR>";
+ var trs = theme.getFirstElement(uidl, "rows").getElementsByTagName("tr");
+ // dummy object, used when creating empty rows up to pagelength
+ var dummy = {getAttribute: function () {return "";}, childNodes : [] };
+ for (var i=0;i<len;i++) {
+ // fill dummy columns (len is still column count)
+ dummy.childNodes[i] = "";
+ }
+ len = pagelength;//trs.length;
+
+ if (len==0) {
+ html += "<TR id=\""+pid+"firstrow\"><TD style=\"overflow:hidden\">";
+ html += "<DIV class=\"pad\" style=\"overflow:hidden;height:100%;white-space:nowrap;border-right:1px solid gray;\"></DIV></TD></TR>";
+ }
+ for (var i=0;i<len;i++) {
+ var row = trs[i]||dummy;
+ var cap = row.getAttribute("caption");
+ var key = row.getAttribute("key");
+ var seld = row.getAttribute("selected");
+ var iconUrl = row.getAttribute("icon");
+ html += "<TR "+(i==0?"id=\""+pid+"firstrow\"":"");
+ html += " key=\""+key+"\"";
+ if (seld) {
+ html += " selected=\"true\" class=\"selected\" ";
+ } else if(i%2!=0) {
+ html += " class=\"odd\" ";
+ }
+ html += ">";
+ if (rowheaders) {
+ html += "<TD ";
+ if (colWidths["heh"]) {
+ html += "width=\""+colWidths["heh"]+"\" ";
+ }
+ html += "style=\"overflow:hidden\"><DIV class=\"padnr\" style=\"";
+ if (colWidths["heh"]) {
+ html += "width:"+colWidths["heh"]+"px;";
+ }
+ html += "overflow:hidden;height:100%;white-space:nowrap;border-right:1px dotted gray;\">";
+ if (iconUrl) {
+ if (iconUrl.indexOf("theme://") == 0) {
+ iconUrl = (theme.iconRoot != null ? theme.iconRoot : theme.root)
+ + iconUrl.substring(8);
+ }
+ html += "<IMG src=\""+iconUrl+"\" class=\"icon\" />";
+ }
+ html += row.getAttribute("caption")+"</DIV></TD>";
+ }
+ var comps = row.childNodes;
+ var l = comps.length;
+ if (l==0) {
+ html += "<TD><DIV class=\"padnr\" style=\"overflow:hidden;height:100%;white-space:nowrap;border-right:1px dotted gray;\"></DIV></TD>";
+ }
+
+ var colNum = -1;
+ for (j=0;j<l;j++) {
+ var comp = comps[j];
+ if (comp.nodeName == "al"||comp.nodeName == "#text") continue;
+ colNum++;
+ // Placeholder TD, we'll render the content later
+ html += "<TD "
+ if (colWidths[colorder[colNum]]) {
+ html += "width=\""+colWidths[colorder[colNum]]+"\" ";
+ }
+ if (alignments[colNum]) {
+ switch (alignments[colNum]) {
+ case "e":
+ html += " align=\"right\" ";
+ break;
+ case "c":
+ html += " align=\"center\" ";
+ break;
+ default:
+ }
+ }
+ html += "style=\"overflow:hidden\"><DIV class=\"padnr\" style=\"";
+ if (colWidths[colorder[colNum]]) {
+ html += "width:"+colWidths[colorder[colNum]]+"px;";
+ }
+ html += "overflow:hidden;height:100%;white-space:nowrap;border-right:1px dotted #c6c6c6;\">&nbsp;</DIV></TD>";
+ }
+ html += "</TR>";
+ }
+ html += "<TR id=\""+pid+"lastrow\" height=\""+postPad+"\"></TR></TBODY></TABLE>";
+ cout.innerHTML = html;
+
+ // SECOND render the sub-components (TD content)
+ var trs = cout.firstChild.firstChild.childNodes;
+ var utrs = theme.getFirstElement(uidl, "rows").getElementsByTagName("tr");
+ for (var i=0;i<len;i++) {
+ var tr = trs[i+1];
+ var key = tr.getAttribute("key");
+ var utr = utrs[i];
+ var dummyrow = false;
+ if (!utr) {
+ utr = dummy;
+ dummyrow = true;
+ }
+ var comps = utr.childNodes;
+ var l = comps.length;
+ var currentCol = (rowheaders?1:0);
+ var al = null;
+ for (j=0;j<l;j++) {
+ var comp = comps[j];
+ if (comp.nodeName == "#text") continue;
+ if (comp.nodeName == "al") {
+ al = comp;
+ continue;
+ }
+ var trg = tr.childNodes[currentCol++].firstChild;
+ if (dummyrow) {
+ trg.innerHTML = "&nbsp;";
+ } else {
+ trg.innerHTML = "";
+ client.renderUIDL(comp, trg);
+ }
+ }
+
+
+ if (!dummyrow&&al&&tr.firstChild) {
+ theme.renderActionPopup(renderer,al,tr,actions,actionVar,key,"rightclick");
+ }
+
+ // selection
+ if (!dummyrow&&selectmode) {
+ selected[selected.length] = tr;
+ theme.addCSSClass(tr,"clickable");
+ theme.addToggleClassListener(theme,client,tr,"mouseover","selectable");
+ theme.addToggleClassListener(theme,client,tr,"mouseout","selectable");
+ if (selectmode == "multi") {
+ theme.addToggleClassListener(theme,client,tr,"click","selected");
+ theme.addToggleVarListener(theme,client,tr,"click",selVar,key,immediate);
+ } else {
+ theme.addAddClassListener(theme,client,tr,"click","selected",tr,selected);
+ theme.addSetVarListener(theme,client,tr,"click",selVar,key,immediate);
+ }
+ }
+ }
+
+ // THIRD do some initial sizing and scrolling
+ // FIX SAFARI lr is constantly 0
+ var fr = target.ownerDocument.getElementById(pid+"firstrow").offsetTop;
+ var lr = target.ownerDocument.getElementById(pid+"lastrow").offsetTop;
+ cout.style.height = (lr-fr)+"px";//(lr-fr+(cout.scrollWidth>cout.offsetWidth?0:0))+"px";
+ cout.scrollTop = fr;//(fv>totalrows-rows?cout.scrollHeight:fr);
+ div.recalc = theme.scrollTableRecalc;
+ div.initialWidth = wholeWidth;
+ div.recalc(pid,target);
+ cout.scrollLeft = scrolledLeft;
+ hout.scrollLeft = scrolledLeft;
+
+ var status = target.ownerDocument.getElementById(pid+"status");
+ var p = client.getElementPosition(inner);
+ status.style.top = (p.y + p.h/2) + "px";
+ status.style.left = (p.x + p.w/2 - wholeWidth/4) +"px";
+ theme.scrollTableAddScrollHandler(client,theme,cout,div,status,lr,fr,rows,totalrows,fv,fvVar,immediate);
+ theme.scrollTableAddScrollListener(theme,div,pid,lr,fr,rows,totalrows,fv);
+
+
+ // Column order drag & drop
+ var hin = target.ownerDocument.getElementById(pid+"hin");
+ var h = hin.getElementsByTagName("td");
+ var dragOrderGroup = new Object();
+ for (var i = 0;i<h.length;i++) {
+ var id = h[i].getAttribute("id");
+ if (id==pid+"heh") {
+ var handle = target.ownerDocument.getElementById(pid+"hah");
+ if (handle) {
+ theme.tableAddWidthListeners(client,theme,handle,"heh",div,pid);
+ }
+ }
+ if (!id||id.indexOf(pid+"he")<0) {
+ continue;
+ }
+ var cid = h[i].getAttribute("cid");
+ var handle = target.ownerDocument.getElementById(pid+"ha"+cid);
+ if (handle) {
+ theme.tableAddWidthListeners(client,theme,handle,cid,div,pid);
+ }
+ if (coVar||sortVar) {
+ theme.addCSSClass(h[i],"clickable");
+ theme.addToDragOrderGroup(client,theme,h[i],dragOrderGroup,coVar,sortVar,sortascVar,sortasc);
+ }
+ }
+
+ var hin = target.ownerDocument.getElementById(pid+"hin");
+ var cin = target.ownerDocument.getElementById(pid+"cin");
+ theme.scrollTableRegisterLF(client,theme,div,inner,cout,hout,cin,hin);
+}
+// Header order drag & drop
+DefaultTheme.prototype.tableAddWidthListeners = function(client,theme,element,cid,table,pid) {
+
+ var colWidths = table.colWidths;
+
+ var mouseDragListener = function (e) {
+ var evt = client.getEvent(e);
+ evt.stop();
+ element.ownerDocument.onselectstart = function(e) {return false;}
+ var target = element.target;
+ var div = target.parentNode;
+ var td = div.parentNode;
+ //target.style.position = "relative";
+ target.style.zIndex = "99999";
+ var offset = -(target.origX-evt.mouseX+10);
+ var w = (target.origW+offset);
+ if (w < 7) w = 7;
+ try {
+ target.style.left = offset+"px";
+ td.width = w;
+ td.style.width = w+"px";
+ td.firstChild.style.width = w+"px";
+ colWidths[cid] = w;
+ } catch (err) {
+ client.debug("Failed: d&d target.style.left="+ offset+"px");
+ }
+
+ }
+
+ var mouseUpListener = function(e) {
+ client.removeEventListener(element.ownerDocument.body,"mousemove",mouseDragListener);
+ client.removeEventListener(element.ownerDocument.body,"mouseup",arguments.callee);
+ client.removeEventListener(element.ownerDocument.body,"drag",stopListener);
+ var evt = client.getEvent(e);
+ evt.stop();
+ element.ownerDocument.onselectstart = null;
+ element.dragging = false;
+ // TODO apply for all rows
+ table.recalc(pid,table);
+ return false;
+ };
+
+ var stopListener = function (e) {
+ var evt = client.getEvent(e);
+ evt.stop();
+ return false;
+ }
+
+ client.addEventListener(element,"mousedown", function(e) {
+ var evt = client.getEvent(e);
+ evt.stop();
+ element.dragging = true;
+ element.moved = false;
+ element.target = evt.target;
+ evt.target.origX = evt.mouseX;
+ evt.target.origW = evt.target.parentNode.offsetWidth;
+ client.addEventListener(element.ownerDocument.body,"mousemove", mouseDragListener);
+ client.addEventListener(element.ownerDocument.body,"mouseup", mouseUpListener);
+ client.addEventListener(element.ownerDocument.body,"drag",stopListener);
+ });
+}
+
+DefaultTheme.prototype.scrollTableRegisterLF = function(client,theme,paintableElement,inner,cout,hout,cin,hin) {
+ client.registerLayoutFunction(paintableElement,function() {
+ var w = (inner.offsetWidth-6) +"px";
+ cout.style.width = w;
+ //cin.style.width = w;
+ //hout.style.width = w;
+ //hin.style.width = w;
+ hout.style.width = hout.offsetParent.offsetWidth + "px";
+ //div.recalc();
+ });
+}
+
+DefaultTheme.prototype.scrollTableAddScrollListener = function (theme,target,pid,lr,fr,rows,totalrows,fv) {
+ var hout = target.ownerDocument.getElementById(pid+"hout");
+ var cout = target.ownerDocument.getElementById(pid+"cout");
+ client.addEventListener(cout,"scroll", function (e) {
+ if (cout.scrollTimeout) {
+ clearTimeout(cout.scrollTimeout);
+ }
+ hout.scrollLeft = cout.scrollLeft;
+ target.scrolledLeft = cout.scrollLeft;
+ var status = target.ownerDocument.getElementById(pid+"status");
+ var d = theme.scrollTableGetFV(cout,lr,fr,rows,totalrows,fv);
+ if (d!=fv) {
+ status.innerHTML = d + "-" + (d+rows-1) + " / " + totalrows;
+ status.style.display = "";
+ }
+ cout.scrollTimeout = setTimeout(function () {
+ var cout = target.ownerDocument.getElementById(pid+"cout");
+ cout.scrollHandler();
+ },500)
+ });
+}
+DefaultTheme.prototype.scrollTableGetFV = function(cout,lr,fr,rows,totalrows,fv) {
+ var rh = (lr-fr)/rows;
+ if (cout.scrollTop >= (fr+rh/2) || cout.scrollTop <= (fr-rh/2)) {
+ var d = Math.round((cout.scrollTop-fr)/rh);
+ d = (fv+d);
+ if (d<1) d=1; // scrolled past begin
+ if (d>(totalrows-rows+1)) d=(totalrows-rows+1); // scrolled past last page
+ return d;
+ } else {
+ return fv;
+ }
+ }
+DefaultTheme.prototype.scrollTableAddScrollHandler = function(client,theme,cout,target,status,lr,fr,rows,totalrows,fv,fvVar,immediate) {
+ cout.scrollHandler = function () {
+ var rh = (lr-fr)/rows;
+ var d = theme.scrollTableGetFV(cout,lr,fr,rows,totalrows,fv);
+ if (d!=fv) {
+ // only submit if firstvisible changed
+ status.innerHTML = d + "-" + (d+rows-1) + " / " + totalrows + "...";
+ status.style.display = "";
+ // always immediate
+ theme.setVariable(client, fvVar, d, true);
+ } else {
+ // else realign
+ status.style.display = "none";
+ //cout.scrollTop = fr;
+ }
+ };
+}
+DefaultTheme.prototype.scrollTableRecalc = function(pid,target) {
+ var defPad = 7;
+ var div = target.ownerDocument.getElementById(pid);
+ var wholeWidth = div.initialWidth;
+ var colWidths = div.colWidths;
+ if (!colWidths) {
+ colWidths = new Object();
+ div.colWidths = colWidths;
+ }
+ var hout = target.ownerDocument.getElementById(pid+"hout");
+ var cout = target.ownerDocument.getElementById(pid+"cout");
+ var hin = target.ownerDocument.getElementById(pid+"hin");
+ var cin = target.ownerDocument.getElementById(pid+"cin");
+ var h = hin.getElementsByTagName("td");
+ var c = cin.getElementsByTagName("td");
+ var whole = 0;
+ var col = -1;
+ for (var i = 0;i<h.length;i++) {
+ if (!h[i].getAttribute||!h[i].getAttribute("id")||h[i].getAttribute("id").indexOf(pid+"he")<0) {
+ continue;
+ }
+ col++;
+ // colWidth, or whole width if only one column
+ var cw = (h.length>1?colWidths[h[i].getAttribute("cid")]:hout.clientWidth-20);
+ var w1 = h[i].firstChild.clientWidth + defPad;
+ var w2 = (c[col]?c[col].firstChild.clientWidth + defPad:0);
+
+ var w = parseInt((cw?cw:(w1>w2?w1:w2)));
+ h[i].width = w;
+ h[i].style.width = w+"px";
+ h[i].firstChild.style.width = w+"px";
+ var rows = c.length/h.length;
+ for (var j=0;j<rows;j++) {
+ var idx = j*h.length+col;
+ if (c[idx]) {
+ c[idx].width = w;
+ c[idx].firstChild.style.width = w+"px";
+ c[idx].style.width = w+"px";
+ colWidths[h[i].getAttribute("cid")] = w;
+ }
+ }
+ whole += parseInt(w);
+ }
+}
+// Header order drag & drop
+DefaultTheme.prototype.addToDragOrderGroup = function (client,theme,element,group,variable,sortVar,sortascVar,sortasc) {
+ element.dragGroup = group;
+ if (!group.elements) {
+ group.elements = new Array();
+ }
+ var idx = group.elements.length;
+ group.elements[idx] = element;
+
+ var mouseDragListener = function (e) {
+ var evt = client.getEvent(e);
+ evt.stop();
+ element.ownerDocument.onselectstart = function() {return false;}
+ var target = element.target;
+ target.style.position = "relative";
+ target.style.top = "5px";
+ try {
+ target.style.left = -(target.origX-evt.mouseX+10)+"px";
+ } catch (err) {
+ client.error("Failed: d&d target.style.left="+ (-(target.origX-evt.mouseX+10)+"px"));
+ }
+ var dragGroup = element.dragGroup;
+ dragGroup.moved = true;
+ var els = dragGroup.elements;
+ for (var i=0;i<els.length;i++) {
+ if (i==element.idx) continue;
+ var el = els[i];
+ var p = client.getElementPosition(el);
+ if (i!=dragGroup.origIdx&&i-1!=dragGroup.origIdx&&p.x < evt.mouseX && p.x+p.w/2 > evt.mouseX) {
+ dragGroup.targetIdx = i;
+ el.style.borderLeft = "1px solid black";
+ el.style.borderRight = "";
+ break;
+ } else if (i!=dragGroup.origIdx&&i+1!=dragGroup.origIdx && p.x+p.w/2 < evt.mouseX && p.x+p.w > evt.mouseX) {
+ dragGroup.targetIdx = i+1;
+ el.style.borderRight = "1px solid black";
+ el.style.borderLeft = "";
+ break;
+ } else {
+ dragGroup.targetIdx = dragGroup.origIdx;
+ el.style.borderRight = "";
+ el.style.borderLeft = "";
+ }
+ }
+ }
+
+ var mouseUpListener = function(e) {
+ client.removeEventListener(element.ownerDocument.body,"mousemove",mouseDragListener);
+ client.removeEventListener(element.ownerDocument.body,"mouseup",arguments.callee);
+ var evt = client.getEvent(e);
+ evt.stop();
+ element.ownerDocument.onselectstart = null;
+ element.target.style.background = "";
+ element.dragGroup.dragging = false;
+ if (element.dragGroup.dragTM) {
+ clearTimeout(element.dragGroup.dragTM);
+ }
+ if (!element.dragGroup.moved) {
+ if (sortVar) {
+ var cid = element.getAttribute("cid");
+ var sorted = element.getAttribute("sorted");
+ //alert("sorting "+element.getAttribute("cid") + " " + sorted + " " + sortasc);
+ if (sorted) {
+ theme.setVariable(client, sortascVar, !sortasc, true);
+ } else {
+ theme.setVariable(client, sortVar, cid, true);
+ }
+ }
+ }
+ var origIdx = element.dragGroup.origIdx;
+ var targetIdx = element.dragGroup.targetIdx;
+ if (origIdx != targetIdx) {
+ var els = element.dragGroup.elements;
+ var neworder = new Array();
+ for (var i=0;i<els.length;i++) {
+ if (i==origIdx) continue;
+ if (i==targetIdx) {
+ neworder[neworder.length] = els[origIdx].getAttribute("cid");
+ }
+ neworder[neworder.length] = els[i].getAttribute("cid");
+ }
+ theme.setVariable(client, variable, neworder, true);
+ } else {
+ element.target.style.left = "0px";
+ element.target.style.top = "0px";
+ }
+ };
+
+ client.addEventListener(element,"mousedown", function(e) {
+ var evt = client.getEvent(e);
+ evt.stop();
+ element.dragGroup.dragging = true;
+ element.dragGroup.moved = false;
+ element.dragGroup.origIdx = idx;
+ element.dragGroup.targetIdx = idx;
+ element.target = evt.target;
+ evt.target.dragGroup = element.dragGroup;
+ evt.target.origX = evt.mouseX;
+ evt.target.idx = idx;
+ if (element.dragGroup.dragTM) {
+ clearTimeout(element.dragGroup.dragTM);
+ }
+ client.addEventListener(element.ownerDocument.body,"mouseup", mouseUpListener);
+ if (variable) {
+ // column reordering allowed
+ group.dragTM = setTimeout(function () {
+ if(element.dragGroup.dragging) {
+ evt.target.style.background = "white";
+ client.addEventListener(element.ownerDocument.body,"mousemove",mouseDragListener);
+ }
+ },100);
+ }
+ });
+ //client.addEventListener(element,"mouseup", mouseUpListener);
+}
+
+DefaultTheme.prototype.renderSelect = function(renderer,uidl,target,layoutInfo) {
+ var theme = renderer.theme;
+ var client = renderer.client;
+
+ // Create containing element
+ var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
+ if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
+
+ // Create selection variable
+ var selectMode = uidl.getAttribute("selectmode");
+ var selectable = selectMode == "multi" || selectMode == "single";
+ var immediate = ("true" == uidl.getAttribute("immediate"));
+ var disabled = ("true" == uidl.getAttribute("disabled"));
+ var readonly = ("true" == uidl.getAttribute("readonly"));
+ var newitem = ("true" == uidl.getAttribute("allownewitem"));
+ var focusid = uidl.getAttribute("focusid");
+ var tabindex = uidl.getAttribute("tabindex");
+ var style = uidl.getAttribute("style");
+ var cache = (style?style.indexOf("cache-")==0:false);
+
+ var selectionVariable = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","selected"));
+
+ // Render default header
+ theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
+
+ // Create select input
+ var select = theme.createElementTo(div,"select");
+ if (focusid) select.focusid = focusid;
+ if (tabindex) select.tabIndex = tabindex;
+ if (selectMode == "multi") {
+ select.setAttribute("multiple", "true");
+ if (newitem) {
+ theme.createElementTo(div,"br");
+ }
+ } else {
+ if (newitem) {
+ theme.addCSSClass(div,"nobr");
+ }
+ }
+ var options = theme.getFirstElement(uidl,"options");
+ if (options != null) {
+ options = options.getElementsByTagName("so");
+ }
+ if (disabled||readonly) {
+ select.disabled = "true";
+ } else {
+ // Add change listener
+ theme.addSetVarListener(theme,client,select,"change",selectionVariable,select,immediate);
+ }
+ // Empty selection for WA compatibility
+ var optionNode = theme.createElementTo(select,"option");
+ theme.createTextNodeTo(optionNode,"-");
+
+ // Selected options
+ if (options != null && options.length >0) {
+
+ var len = options.length;
+ for (var i=0; i<len;i++) {
+ var uop = options[i];
+ var op = new Option(uop.getAttribute("caption"),uop.getAttribute("key"));
+ select.options[i] = op;
+ if (uop.getAttribute("selected") == "true") op.selected = "true";
+ /*
+ var optionNode = theme.createElementTo(select,"option");
+ optionNode.setAttribute("value", options[i].getAttribute("key"));
+ if (options[i].getAttribute("selected") == "true") {
+ optionNode.selected="true";
+ }
+ theme.createTextNodeTo(optionNode,options[i].getAttribute("caption"));
+ */
+ }
+
+ }
+
+ if (newitem) {
+ var input = theme.createInputElementTo(div,"text");
+ var button = theme.createElementTo(div,"button");
+ theme.createTextNodeTo(button,"+");
+ var newitemVariable = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"string","newitem"));
+ theme.addSetVarListener(theme,client,input,"change",newitemVariable,input,immediate);
+ }
+}
+
+
+DefaultTheme.prototype.renderSelectOptionGroup = function(renderer,uidl,target,layoutInfo) {
+ // TODO:
+ // - newitem currently always immediate, change
+ // - optiongrouphorizontal style
+
+ var theme = renderer.theme;
+ var client = renderer.client;
+
+ // Create containing element
+ var div = theme.createPaintableElement(renderer,uidl,target);
+
+ // Create selection variable
+ var selectMode = uidl.getAttribute("selectmode");
+ var selectable = selectMode == "multi" || selectMode == "single";
+ var immediate = ("true" == uidl.getAttribute("immediate"));
+ var disabled = ("true" == uidl.getAttribute("disabled"));
+ var readonly = ("true" == uidl.getAttribute("readonly"));
+ var newitem = ("true" == uidl.getAttribute("allownewitem"));
+ var selectionVariable = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","selected"));
+
+ // Render default header
+ theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
+
+ // Create select input
+ var select = theme.createElementTo(div,"div");
+ var options = theme.getFirstElement(uidl,"options");
+ if (options != null) {
+ options = options.getElementsByTagName("so");
+ }
+
+ // Selected options
+ if (options != null && options.length >0) {
+ for (var i=0; i<options.length;i++) {
+ var optionUidl = options[i];
+ var iconUrl = optionUidl.getAttribute("icon");
+ var div = theme.createElementTo(select,"div", "nobr");
+ var key = optionUidl.getAttribute("key");
+
+ // Create input
+ var inputName = "input"+uidl.getAttribute("id");
+ var inputId = inputName+i;
+ var input = null;
+ var caption = optionUidl.getAttribute("caption");
+ var html;
+ if (selectMode == "multi") {
+ html = "<input type=checkbox name=\""+inputName+"\" id=\""+inputId+"\" ";
+ } else {
+ html = "<input type=radio name=\""+inputName+"\" id=\""+inputId+"\" ";
+ }
+ if (disabled||readonly) html += " disabled=\"true\" "
+ if (optionUidl.getAttribute("selected") == "true") {
+ html += " checked=\"true\" "
+ }
+ html += " ><label class=\"clickable\" for=\""+inputId+"\">";
+ if (caption) html += caption;
+ if (iconUrl) {
+ if (iconUrl.indexOf("theme://") == 0) {
+ iconUrl = (theme.iconRoot != null ? theme.iconRoot : theme.root)
+ + iconUrl.substring(8);
+ }
+ html += "<IMG src=\""+iconUrl+"\" class=\"icon\">";
+ }
+ html += "</label>";
+
+ div.innerHTML = html;
+ if (!(disabled||readonly)) {
+ var input = div.firstChild;
+ if (selectMode == "multi") {
+ theme.addToggleVarListener(theme,client,input,"click",selectionVariable,key,immediate);
+ } else {
+ theme.addSetVarListener(theme,client,input,"click",selectionVariable,key,immediate);
+ }
+ }
+ }
+ }
+ if (newitem) {
+ theme.createElementTo(div,"br");
+ var input = theme.createInputElementTo(div,"text");
+ var button = theme.createElementTo(div,"button");
+ theme.createTextNodeTo(button,"+");
+ var newitemVariable = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"string","newitem"));
+ theme.addSetVarListener(theme,client,input,"change",newitemVariable,input,true);
+ }
+}
+
+DefaultTheme.prototype.renderLabel = function(renderer,uidl,target,layoutInfo) {
+
+ // Create container element
+ var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
+ if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
+
+ // Create default header
+ var caption = renderer.theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
+
+ // Render children to div
+ if (uidl.childNodes.length>0) {
+ div = renderer.theme.createElementTo(div,"div");
+ renderer.theme.renderChildNodes(renderer, uidl, div);
+ }
+ if (div.innerHTML == "") div.innerHTML = "&nbsp;";
+}
+
+DefaultTheme.prototype.renderData = function(renderer,uidl,target) {
+
+ var html = "";
+ for (var i=0; i<uidl.childNodes.length; i++) {
+ var child = uidl.childNodes.item(i);
+ if (child.nodeType == Node.ELEMENT_NODE) {
+ html += renderer.theme.nodeToString(child,true);
+ } if (child.nodeType == Node.TEXT_NODE && child.data != null) {
+ html += child.data;
+ }
+ }
+ target.innerHTML = html;
+
+}
+
+DefaultTheme.prototype.renderPre = function(renderer,uidl,target) {
+
+ // Create pre node
+ var pre = renderer.theme.createElementTo(target,"pre");
+
+ var html = "";
+ for (var i=0; i<uidl.childNodes.length; i++) {
+ var child = uidl.childNodes.item(i);
+ if (child.nodeType == Node.ELEMENT_NODE) {
+ html += renderer.theme.nodeToString(child,true);
+ } if (child.nodeType == Node.TEXT_NODE && child.data != null) {
+ html += child.data;
+ }
+ }
+ pre.innerHTML = html;
+}
+
+
+DefaultTheme.prototype.renderButton = function(renderer,uidl,target,layoutInfo) {
+ // Branch for checkbox
+ if (uidl.getAttribute("type") == "switch") {
+ return renderer.theme.renderCheckBox(renderer,uidl,target,layoutInfo);
+ }
+
+ // Shortcuts
+ var theme = renderer.theme;
+ var client = renderer.client;
+
+ var disabled = "true"==uidl.getAttribute("disabled");
+ var readonly = "true"==uidl.getAttribute("readonly");
+ var immediate = "true"==uidl.getAttribute("immediate");
+ var tabindex = uidl.getAttribute("tabindex");
+ var style = uidl.getAttribute("style");
+ var linkStyle = (style&&style.indexOf("link")>=0);
+
+ var div = theme.createPaintableElement(renderer,uidl,target,layoutInfo);
+ if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
+
+ if(!linkStyle) renderer.theme.createElementTo(div,"div","btn-left clickable");
+ var div_btn = renderer.theme.createElementTo(div,"div",(linkStyle?"link clickable":"btn clickable"));
+ if(!linkStyle) renderer.theme.createElementTo(div,"div","btn-right clickable");
+ var inner = renderer.theme.createElementTo(div_btn,"div",(linkStyle?"pad":""));
+ //var div = renderer.theme.createElementTo(div,"div",(linkStyle?"link clickable":"outset clickable"));
+ //var inner = renderer.theme.createElementTo(div,"div",(linkStyle?"pad":"border pad bg"));
+
+ var caption = theme.renderDefaultComponentHeader(renderer,uidl,inner);
+ theme.addTabtoHandlers(client,theme,caption,div,tabindex,("default"==uidl.getAttribute("style")));
+
+ if (!disabled&&!readonly) {
+ // Handlers
+ var v = theme.getVariableElement(uidl,"boolean", "state");
+ if (v != null) {
+ var varId = v.getAttribute("id");
+ theme.addSetVarListener(theme,client,div,"click",varId,"true",immediate);
+ theme.addAddClassListener(theme,client,div,"mouseover","over",div);
+ theme.addRemoveClassListener(theme,client,div,"mouseout","over",div);
+ }
+ }
+
+}
+
+DefaultTheme.prototype.renderCheckBox = function(renderer,uidl,target,layoutInfo) {
+ // Shortcuts
+ var theme = renderer.theme;
+ var client = renderer.client;
+
+ var div = theme.createPaintableElement(renderer,uidl,target,layoutInfo);
+ if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
+
+ var immediate = (uidl.getAttribute("immediate") == "true");
+ var disabled = (uidl.getAttribute("disabled") == "true");
+ var readonly = (uidl.getAttribute("readonly") == "true");
+ var tabindex = uidl.getAttribute("tabindex");
+
+ // Create input
+ var div = theme.createElementTo(div,"div","nocappad nobr");
+ var input = theme.createInputElementTo(div,"checkbox");
+ input.setAttribute("id", "input"+uidl.getAttribute("id"));
+ if (tabindex) input.tabIndex = tabindex;
+ if (disabled||readonly) {
+ input.disabled = "true";
+ }
+
+ // Create label
+ var label = theme.createElementTo(div,"label", "clickable");
+ var cap = theme.renderDefaultComponentHeader(renderer,uidl,label);
+ theme.addCSSClass(cap,"inline");
+ label.setAttribute("for","input"+uidl.getAttribute("id"));
+ // Value
+ var v = theme.getVariableElement(uidl,"boolean", "state");
+ if ( v!= null) {
+ var varId = v.getAttribute("id");
+ input.checked = (v.getAttribute("value") == "true");
+ // Attach listener
+ theme.addSetVarListener(theme,client,input,(immediate?"click":"change"),varId,input,immediate);
+ }
+}
+
+DefaultTheme.prototype.renderChildNodes = function(renderer, uidl, to) {
+ var child = uidl.firstChild;
+ while (child) {
+ if (child.nodeType == Node.ELEMENT_NODE) {
+ renderer.client.renderUIDL(child,to);
+ } else if (child.nodeType == Node.TEXT_NODE) {
+ to.appendChild(to.ownerDocument.createTextNode(child.data));
+ }
+ child = child.nextSibling;
+ }
+}
+
+DefaultTheme.prototype.renderActionPopup = function(renderer, uidl, to, actions, actionVar, id, popupEvent) {
+ // Shortcuts
+ var theme = renderer.theme;
+ var client = renderer.client;
+ var evtName = popupEvent||"rightclick";
+
+ var ak = uidl.getElementsByTagName("ak");
+ var len = ak.length;
+ if (len < 1) return;
+
+ var popup = theme.createElementTo((to.nodeName=="TR"?to.firstChild:to),"div", "popup outset hide");
+ popup.style.position = "absolute";
+ theme.addHidePopupListener(theme,client,popup,"click");
+ theme.addStopListener(theme,client,popup,"click");
+
+ var inner = theme.createElementTo(popup,"div", "border");
+ var item = theme.createElementTo(inner,"div", "item pad clickable");
+
+ for (var k=0;k<len;k++) {
+ var key = theme.getFirstTextNode(ak[k]).data;
+ var item = theme.createElementTo(inner,"div", "item pad clickable");
+ theme.createTextNodeTo(item,actions[key]);
+ item.style.color = "black";
+ theme.addAddClassListener(theme,client,item,"mouseover","over");
+ theme.addRemoveClassListener(theme,client,item,"mouseout","over");
+ theme.addSetVarListener(theme,client,item,"click",actionVar,id+","+key,true);
+ theme.addHidePopupListener(theme,client,item,"click");
+ theme.addStopListener(theme,client,item,"click");
+ }
+ theme.addStopListener(theme,client,to,"contextmenu");
+ //theme.addStopListener(theme,client,to,evtName);
+ theme.addTogglePopupListener(theme,client,to,evtName,popup);
+}
+
+
+DefaultTheme.prototype.createElementTo = function (target, tagName, cssClass) {
+
+ if (target == null) return null;
+
+ // Create the requested element
+ var e = target.ownerDocument.createElement(tagName);
+
+ // Set CSS class if specified
+ if (cssClass) {
+ this.setCSSClass(e,cssClass);
+ }
+
+ // Append to parent
+ target.appendChild(e);
+
+ return e;
+}
+
+DefaultTheme.prototype.createTextNodeTo = function (target,text) {
+
+ // Sanity check
+ if (text == null || target == null) return null;
+
+ // Create DIV as container
+ var tn = target.ownerDocument.createTextNode(text);
+
+ // Append to parent
+ target.appendChild(tn);
+
+ return tn;
+}
+
+DefaultTheme.prototype.createPaintableElement = function (renderer, uidl, target,layoutInfo) {
+
+ // And create DIV as container
+ var div = null;
+ var pid = uidl.getAttribute("id");
+ var li = layoutInfo||target.layoutInfo;
+ if (pid != null && target.getAttribute("id") == pid){
+ div = target;
+ } else {
+ div = renderer.client.createPaintableElement(uidl,target);
+ }
+ div.layoutInfo = li;
+
+ // Remove possible previous content from target
+ while (div.firstChild != null) {
+ div.removeChild(div.firstChild);
+ }
+
+ // Assign CSS class
+ this.setCSSDefaultClass(renderer,div,uidl);
+ if ("true"==uidl.getAttribute("disabled")) {
+ this.addCSSClass(div,"disabled");
+ }
+ if (this.getFirstElement(uidl,"error")) {
+ this.addCSSClass(div,"error");
+ }
+
+ // Return reference to newly created div
+ return div;
+}
+
+DefaultTheme.prototype.addCSSClass = function(element, className) {
+ if (element == null) return element;
+ if (element.className) {
+ var classArray = element.className.split(" ");
+ for (var i in classArray) {
+ if (classArray[i]==className) {
+ // allready in className
+ return element;
+ }
+ }
+ }
+ element.className = (element.className?element.className:"") + " " + className;
+ return element;
+}
+
+DefaultTheme.prototype.removeCSSClass = function(element, className) {
+ if (element == null) return element;
+ var classArray = new Array();
+ if (element.className) {
+ classArray = element.className.split(" ");
+ }
+ var newArray = new Array();
+ for (var i in classArray) {
+ if (classArray[i]!=className) {
+ newArray[newArray.length] = classArray[i];
+ }
+ }
+ element.className = newArray.join(" ");
+ return element;
+}
+DefaultTheme.prototype.toggleCSSClass = function(element, className) {
+ if (element == null) return element;
+
+ var classArray = new Array();
+ if (element.className) {
+ classArray = element.className.split(" ");
+ }
+ for (var i=0;i<classArray.length;i++) {
+ if (classArray[i]==className) {
+ this.removeCSSClass(element, className);
+ return;
+ }
+ }
+ this.addCSSClass(element, className);
+
+ return element;
+}
+
+
+DefaultTheme.prototype.setCSSClass = function(element, className) {
+ if (element == null) return element;
+ element.className = className;
+ return element;
+}
+
+DefaultTheme.prototype.getFirstElement = function(parent, elementName) {
+ /*
+ if (parent && parent.childNodes) {
+ var cn = parent.childNodes;
+ var len = cn.length;
+ for (var i=0;i<len;i++) {
+ if (cn[i].nodeName == elementName) {
+ return cn[i];
+ }
+ }
+ }
+ */
+
+
+ if (parent && parent.firstChild) {
+ var n = parent.firstChild;
+ while (n) {
+ if (n.nodeName == elementName) {
+ return n;
+ } else {
+ n = n.nextSibling;
+ }
+ }
+ }
+
+
+ /*
+ try {
+ var els = parent.getElementsByTagName(elementName)[0];
+ if (els.parentNode == parent) {
+ return els;
+ }
+ } catch (e) {
+ }
+ */
+
+ //return parent.selectNodes(elementName)[0];
+
+ return null;
+}
+
+DefaultTheme.prototype.getFirstTextNode = function(parent) {
+ try {
+ var child = parent.firstChild;
+ while (child) {
+ if (child.nodeType == Node.TEXT_NODE) {
+ return child;
+ }
+ child = child.nextSibling;
+ }
+ } catch (e) {
+ }
+ return null;
+}
+
+/**
+ * Removes all children of an element an element.
+ *
+ * @param element Remove children of this element.
+ *
+ * @return the element with children removed
+ */
+DefaultTheme.prototype.removeAllChildNodes = function(element) {
+ //TODO event listener leakage prevention, verify
+ // MOVED to client
+ //this.removeAllEventListeners(element);
+
+
+ /*
+ while (element.childNodes&&element.childNodes.length > 0) {
+ element.removeChild(element.childNodes[0]);
+ }
+ */
+ while (element.firstChild) {
+ element.removeChild(element.firstChild);
+ }
+ return element;
+}
+
+DefaultTheme.prototype.getElementContent = function(parent, elementName) {
+ if (elementName != null) {
+ // Find element and return its content
+ var n = this.getFirstElement(parent,elementName);
+ if (n == null) return null;
+ var tn = this.getFirstTextNode(n);
+ if (tn != null && tn.data != null) {
+ return tn.data;
+ }
+ return "";
+ } else {
+ // If no element name is given return
+ // content of parent
+ var tn = this.getFirstTextNode(parent);
+ if (tn != null && tn.data != null) {
+ return tn.data;
+ }
+ return "";
+ }
+}
+
+DefaultTheme.prototype.setCSSDefaultClass = function(renderer,element,uidl) {
+ if (element == null) return element;
+ var cn = this.styleToCSSClass(renderer.tag,uidl.getAttribute("style"));
+ element.className = cn;
+ return element;
+}
+
+DefaultTheme.prototype.renderDefaultComponentHeader = function(renderer,uidl,target, layoutInfo) {
+ var theme = renderer.theme;
+ var doc = renderer.doc;
+
+ var captionText = uidl.getAttribute("caption");
+ var error = this.getFirstElement(uidl,"error");
+ var descriptionText = this.getElementContent(uidl,"description");
+ var icon = uidl.getAttribute("icon");
+ var style = uidl.getAttribute("style");
+ var altdesc = (style && style.indexOf("-altdesc")>-1);
+
+ if (!captionText && !error && !descriptionText && !icon) {
+ return null;
+ }
+
+ if (!layoutInfo) {
+ layoutInfo = target.layoutInfo;
+ }
+
+ // If layout info contains caption node, use it as caption position
+ if (layoutInfo != null && layoutInfo.captionNode) {
+ target = layoutInfo.captionNode;
+ target.innerHTML = "";
+ }
+
+ // Caption container
+ var caption = this.createElementTo(target,"div");
+ // Create debug-mode UIDL div
+ if (renderer.client.debugEnabled) {
+ var uidlDebug = this.createElementTo(caption,"div","uidl minimized");
+ renderer.client.renderHTML(uidl,uidlDebug);
+ var t = this;
+ client.addEventListener(uidlDebug,"click", function (e) {
+ if (uidlDebug.className.indexOf("minimized") >=0) {
+ t.removeCSSClass(uidlDebug,"minimized");
+ } else {
+ t.addCSSClass(uidlDebug,"minimized");
+ }
+ }
+ );
+ }
+ if (captionText||error||descriptionText||icon) {
+ this.addCSSClass(caption,"caption");
+ } else {
+ return caption;
+ }
+ if (descriptionText || error) {
+ this.addCSSClass(caption,"clickable");
+ }
+
+ if (error||(descriptionText&&!altdesc)) {
+ var popup = this.renderDescriptionPopup(renderer,uidl,(captionText?caption:target));
+ }
+
+ var iconUrl = uidl.getAttribute("icon");
+
+ if (iconUrl) {
+ if (iconUrl.indexOf("theme://") == 0) {
+ iconUrl = (theme.iconRoot != null ? theme.iconRoot : theme.root)
+ + iconUrl.substring(8);
+ }
+ var icon = this.createElementTo(caption,"img","icon");
+ icon.src = iconUrl;
+ icon.align = "bottom";
+ }
+
+ // Caption text
+ this.createTextNodeTo(caption,captionText);
+
+ var icon;
+ if (error) {
+ icon = this.createElementTo(caption,"span","icon-mini error"); // Using span + inline-block in css
+ //icon.src = theme.root+"/img/icon/error-mini.gif"; //Now read from CSS (8.6.2006)
+ if (iconUrl) {
+ /* overlay icon */
+ //this.setCSSClass(icon,"error");
+ } else {
+ //this.setCSSClass(icon,"error");
+ }
+ } else if (descriptionText&&!altdesc) {
+ icon = this.createElementTo(caption,"span","icon-mini info"); // Using span + inline-block in css
+ //icon.src = theme.root+"/img/icon/info-mini.gif"; //Now read from CSS (8.6.2006)
+ if (iconUrl) {
+ /* overlay icon */
+ //this.setCSSClass(icon,"error");
+ } else {
+ //this.setCSSClass(icon,"error");
+ }
+ }
+ if (!error && altdesc && descriptionText) {
+ caption.title = descriptionText;
+ }
+
+ return caption;
+}
+
+// TODO move generalized func:
+DefaultTheme.prototype.addTabtoHandlers = function(client,theme,target,hoverTarget,tabindex,defaultButton) {
+ var b = this.createInputElementTo(target,(defaultButton?"submit":"button"));
+ b.style.border = "none";
+ b.style.background = "none";
+ b.style.padding = "0px";
+ b.style.width = "0px";
+ b.style.height = "0px";
+
+ if (tabindex) b.tabIndex = tabindex;
+
+ client.addEventListener(b,"focus", function() {
+ theme.addCSSClass(hoverTarget,"over");
+ });
+ client.addEventListener(b,"blur", function() {
+ theme.removeCSSClass(hoverTarget,"over");
+ });
+}
+
+
+DefaultTheme.prototype.renderDescriptionPopup = function (renderer,uidl,target) {
+ var theme = renderer.theme;
+ var doc = renderer.doc;
+
+ var captionText = uidl.getAttribute("caption");
+ var desc = this.getFirstElement(uidl,"description");
+
+ var error = this.getFirstElement(uidl,"error");
+ var iconUrl = uidl.getAttribute("icon");
+ if (!iconUrl&&desc) {
+ iconUrl = theme.root+"/img/icon/info.gif";
+ }
+
+ // Caption container
+ var popup = this.createElementTo(target,"div","outset popup hide");
+ var inner = this.createElementTo(popup,"table","border pad");
+ inner = this.createElementTo(inner,"tbody");
+ var tr = this.createElementTo(inner,"tr");
+ var td = this.createElementTo(tr,"td");
+ if (iconUrl) {
+ if (iconUrl.indexOf("theme://") == 0) {
+ iconUrl = (theme.iconRoot != null ? theme.iconRoot : theme.root)
+ + iconUrl.substring(8);
+ }
+ var icon = this.createElementTo(td,"img","icon");
+ icon.src = iconUrl;
+ }
+ td = this.createElementTo(tr,"td");
+ var caption = this.createElementTo(td,"div","caption");
+ this.createTextNodeTo(caption,captionText);
+
+ if (desc) {
+ var description = this.createElementTo(td,"div","content");
+ description.innerHTML = renderer.client.getXMLtext(desc);
+ description.style.whiteSpace ="normal";
+ }
+ if (error) {
+ tr = this.createElementTo(inner,"tr");
+ td = this.createElementTo(tr,"td");
+ icon = this.createElementTo(td,"img","icon");
+ icon.src = theme.root+"/img/icon/error.gif";
+ td = this.createElementTo(tr,"td");
+ var errorDiv = this.createElementTo(td,"div","error pad");
+ this.renderData(renderer,error,errorDiv);
+ var ew = errorDiv.ownerDocument.getElementById("error-window");
+ if (ew) {
+ ew.innerHTML += "<DIV><B>"+captionText+":</B> "+errorDiv.innerHTML+"</DIV><BR/>";
+ ew.style.display = "inline";
+ }
+ }
+ if (desc||error) {
+ this.addTogglePopupListener(theme,client,target,"mouseover",popup,1000,500,target);
+ //theme.addTogglePopupListener(theme,client,target,"click",popup,0,500);
+ this.addHidePopupListener(theme,client,popup,"click",popup);
+ this.addHidePopupListener(theme,client,target,"mouseout",popup);
+ this.addHidePopupListener(theme,client,popup,"mouseout",popup);
+ }
+
+ return popup;
+}
+
+DefaultTheme.prototype.styleToCSSClass = function(prefix,style) {
+
+ var s = "";
+ if (prefix != null) {
+ s = prefix;
+ }
+ if (style != null) {
+ if (s.length > 0) {
+ s = s + "-";
+ }
+ s = s + style;
+ }
+ return s
+}
+
+DefaultTheme.prototype.getChildElements = function(parent, tagName) {
+ /*
+ if (parent == null || parent.childNodes == null || tagName == null) return null;
+ // Iterate all child nodes
+ var res = new Array();
+ for (var i=0; i < parent.childNodes.length; i++) {
+ var n = parent.childNodes[i];
+ if (n.nodeType == Node.ELEMENT_NODE && n.nodeName == tagName) {
+ res[res.length++] = n;
+ }
+ }
+ return res;
+ */
+ var res = new Array();
+ try {
+ var child = parent.firstChild;
+ while (child) {
+ if (child.nodeType == Node.ELEMENT_NODE && child.nodeName == tagName) {
+ res[res.length] = child;
+ }
+ child = child.nextSibling;
+ }
+ } catch (e) {
+ }
+ return res;
+
+}
+
+DefaultTheme.prototype.getVariableElement = function(uidl,type,name) {
+
+ if (uidl == null) return;
+
+ var nodes = this.getChildElements(uidl,type);
+ if (nodes != null) {
+ for (var i=0; i < nodes.length; i++) {
+ if (nodes[i].getAttribute("name") == name) {
+ return nodes[i];
+ }
+ }
+ }
+ return null;
+}
+
+
+DefaultTheme.prototype.applyWidthAndHeight = function(uidl,target,which) {
+ if (target == null || uidl == null) return;
+
+
+ // Width
+ if(!which || which == "width") {
+ var widthEl = this.getVariableElement(uidl,"integer","width");
+ if (widthEl) {
+ var w = widthEl.getAttribute("value");
+ if (w > 0) {
+ target.style.width = ""+w+"px";
+ }
+ }
+ }
+
+ // Height
+ if(!which || which == "height") {
+ var heightEl = this.getVariableElement(uidl,"integer","height");
+ if (heightEl) {
+ var h = heightEl.getAttribute("value");
+ if (h > 0) {
+ target.style.height = ""+h+"px";
+ }
+ }
+ }
+}
+
+DefaultTheme.prototype.createInputElementTo = function(target,type,className,focusid) {
+
+ var input = null;
+ if (document.all) {
+ // IE only
+ input = this.createElementTo(target,"<input type='"+type+"'>");
+ } else {
+ // Other browsers
+ input = this.createElementTo(target,"input");
+ input.type = type;
+ }
+
+ // Assign class
+ if (className != null && className != "") {
+ this.setCSSClass(input,className);
+ }
+
+ if (focusid) input.focusid = focusid;
+
+ return input;
+}
+
+DefaultTheme.prototype.createVariableElementTo = function(target,variableElement) {
+ if (!variableElement) {
+ return null;
+ }
+ var input = this.createInputElementTo(target,"hidden");
+ input.variableId = variableElement.getAttribute("id");
+ input.variableName = variableElement.getAttribute("name");
+ if (variableElement.nodeName == "array") {
+ input.variableId = "array:"+input.variableId;
+ input.value = this.arrayToList(variableElement);
+ } else if (variableElement.nodeName == "string") {
+ var node = this.getFirstTextNode(variableElement);
+ input.value = (node?node.data:"");
+ } else {
+ input.value = variableElement.getAttribute("value");
+ }
+ return input;
+}
+
+DefaultTheme.prototype.getVariableElementValue = function(variableElement) {
+ if ( variableElement == null) {
+ return null;
+ }
+
+ if (variableElement.nodeName == "array") {
+ return this.arrayToList(variableElement);
+ } else if (variableElement.nodeName == "string") {
+ var node = this.getFirstTextNode(variableElement);
+ return (node?node.data:"");
+ } else {
+ return variableElement.getAttribute("value");
+ }
+ return null;
+}
+DefaultTheme.prototype.setVariable = function(client, variableNode, newValue, immediate) {
+ if (variableNode == null) return;
+ variableNode.value = newValue;
+ client.changeVariable(variableNode.variableId, newValue, immediate);
+}
+DefaultTheme.prototype.setStringVariable = function(client, variableNode, newValue, immediate) {
+ alert("REMOVED FUNC!");
+}
+DefaultTheme.prototype.setBooleanVariable = function(client, variableNode, newValue, immediate) {
+ alert("REMOVED FUNC!");
+}
+
+DefaultTheme.prototype.setArrayVariable = function(client, variableNode, newValue, immediate) {
+ alert("REMOVED FUNC!");
+}
+
+DefaultTheme.prototype.addArrayVariable = function(client, variableNode, newValue, immediate) {
+ if (variableNode == null) return;
+ variableNode.value = this.listAddInt(variableNode.value,newValue);
+ client.changeVariable(variableNode.variableId, variableNode.value, immediate);
+}
+DefaultTheme.prototype.toggleArrayVariable = function(client, variableNode, value, immediate) {
+ if (variableNode == null) return;
+ if (this.listContainsInt(variableNode.value,value)) {
+ variableNode.value = this.listRemoveInt(variableNode.value,value);
+ } else {
+ variableNode.value = this.listAddInt(variableNode.value,value);
+ }
+ client.changeVariable(variableNode.variableId, variableNode.value, immediate);
+}
+DefaultTheme.prototype.removeArrayVariable = function(client, variableNode, value, immediate) {
+ if (variableNode == null) return;
+ variableNode.value = this.listRemoveInt(variableNode.value,value);
+ client.changeVariable(variableNode.variableId, variableNode.value, immediate);
+}
+
+DefaultTheme.prototype.arrayToList = function(arrayVariableElement) {
+
+ var list = "";
+ if (arrayVariableElement == null) return list;
+
+ var items = arrayVariableElement.getElementsByTagName("ai");
+ if (items == null) return list;
+
+ for (var i=0; i <items.length;i++) {
+ var v = this.getFirstTextNode(items[i]);
+ if (v != null && v.data != null) {
+ if (list.length >0) list += ",";
+ list += v.data;
+ }
+ }
+
+ return list;
+}
+
+/** TODO REMOVE */
+DefaultTheme.prototype.addEventListener = function(element,type,func) {
+ alert("addEventListener -> client");
+}
+/** TODO REMOVE */
+DefaultTheme.prototype.removeEventListener = function(element,type,func) {
+ alert("removeEventListener -> client");
+}
+
+
+/**
+ * Check if integer list contains a number.
+ *
+ * @param list Comma separated list of integers
+ * @param number Number to be tested
+ *
+ * @return true iff the number can be found in the list
+ */
+
+DefaultTheme.prototype.listContainsInt = function(list,number) {
+ if (!list) return false;
+ a = list.split(",");
+
+ for (i=0;i<a.length;i++) {
+ if (a[i] == number) return true;
+ }
+
+ return false;
+}
+
+
+/** Add number to integer list, if it does not exit before.
+ *
+ *
+ * @param list Comma separated list of integers
+ * @param number Number to be added
+ *
+ * @return new list
+ */
+
+DefaultTheme.prototype.listAddInt = function(list,number) {
+
+ if (this.listContainsInt(list,number))
+ return list;
+
+ if (list == "") return number;
+ else return list + "," + number;
+}
+
+
+/** Remove number from integer list.
+ *
+ * @param list Comma separated list of integers
+ * @param number Number to be removed
+ *
+ * @return new list
+ */
+DefaultTheme.prototype.listRemoveInt = function(list,number) {
+ if (!list) return "";
+ retval = "";
+ a = list.split(',');
+
+ for (i=0;i<a.length;i++) {
+ if (a[i] != number) {
+ if (i == 0) retval += a[i];
+ else retval += "," + a[i];
+ }
+ }
+ return retval;
+}
+
+
+/** Show popup at specified position.
+ * Hides previous popup.
+ *
+ * @param popup The element to popup
+ * @param x horizontal popup position
+ * @param y vertical popup position
+ * @param delay delay before popping up
+ * @param defWidth (optional) default width for the popup
+ *
+ */
+DefaultTheme.prototype.showPopup = function(client,popup, x, y, delay, defWidth) {
+ if (this.popupTimeout) {
+ clearTimeout(this.popupTimeout);
+ delete this.popupTimeout;
+ }
+ if (!popup) {
+ var popup = this.popup;
+ this.popupShowing = true;
+ var scrollTop = (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);
+ var scrollLeft = (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);
+ var docWidth = document.body.clientWidth;
+ var docHeight = document.body.clientHeight;
+ this.removeCSSClass(popup,"hide");
+
+ var ua = navigator.userAgent.toLowerCase();
+ if (ua.indexOf("msie")>=0) {
+ var sels = popup.ownerDocument.getElementsByTagName("select");
+ if (sels) {
+ var len = sels.length;
+ var hidden = new Array();
+ for (var i=0;i<len;i++) {
+ var sel = sels[i];
+ if (sel.style&&sel.style.display!="none") {
+ sel.style.visibility = "hidden";
+ hidden[hidden.length] = sel;
+ }
+ }
+ this.popupSelectsHidden = hidden;
+ }
+ }
+ /* TODO fix popup width & position */
+ //popup.style.left = x + "px";
+ //popup.style.top = y + "px";
+ return;
+ }
+ if (!delay) var delay = 0;
+ if (this.popup && this.popup != popup) {
+ this.hidePopup();
+ }
+ this.popup = popup;
+ popup.style.left = 0+"px";
+ popup.style.top = 0+"px";
+ this.removeCSSClass(popup,"hide");
+ var p = client.getElementPosition(popup);
+ this.addCSSClass(popup,"hide");
+ // TODOO!!! width not working properly
+ if (p.w > document.body.clientWidth/2) {
+ popup.style.width = Math.round(document.body.clientWidth/2)+"px";
+ p.w = Math.round(document.body.clientWidth/2);
+ }
+
+ var posX = x;//||p.x;
+ var posY = y;//||p.y;
+ if (posX+p.w>document.body.clientWidth) {
+ posX = document.body.clientWidth-p.w;
+ if (posX<0) posX=0;
+ }
+ if (posY+p.h>document.body.clientHeight) {
+ posY = document.body.clientHeight-p.h;
+ if (posY < 0) posY =0;
+ }
+
+ if (p.h > document.body.clientHeight -20) {
+ popup.style.height = document.body.clientHeight -20 + "px";
+ popup.style.overflow = "auto";
+ posX -= 20;
+ }
+
+
+ popup.style.left = posX+"px";
+ popup.style.top = posY+"px";
+
+ if (delay > 0) {
+ with ({theme:this}) {
+ theme.popupTimeout = setTimeout(function(){
+ theme.showPopup(client);
+ }, delay);
+ }
+ } else {
+ this.showPopup(client);
+ }
+}
+/** Hides previous popup.
+ */
+DefaultTheme.prototype.hidePopup = function() {
+ if (this.popupSelectsHidden) {
+ var len = this.popupSelectsHidden.length;
+ for (var i=0;i<len;i++) {
+ var sel = this.popupSelectsHidden[i];
+ try {
+ sel.style.visibility = "visible";
+ } catch (e) {
+ // select in other window, which was closed?
+ }
+ }
+ this.popupSelectsHidden = null;
+ }
+
+ if (this.popup) {
+ try {
+ this.addCSSClass(this.popup,"hide");
+ } catch (e) {
+ // popup in other window, which was closed?
+ }
+ this.popupShowing = false;
+ }
+ if (this.popupTimeout) {
+ clearTimeout(this.popupTimeout);
+ delete this.popupTimeout;
+ }
+}
+/** Shows the popup if it's not currently shown,
+ * hides the popup otherwise.
+ * Hides previous popup.
+ *
+ * @param popup The element to popup
+ * @param x horizontal popup position
+ * @param y vertical popup position
+ * @param delay delay before popping up
+ * @param defWidth (optional) default width for the popup
+ *
+ */
+DefaultTheme.prototype.togglePopup = function(popup, x, y, delay, defWidth) {
+ if (this.popup == popup && this.popupShowing) {
+ this.hidePopup();
+ } else {
+ this.showPopup(client,popup,x,y,delay,defWidth);
+ }
+}
+
+// TODO REMOVE
+DefaultTheme.prototype.getEventProperties = function(e) {
+ alert("getEventProperties() -> client.getEvent()");
+}
+
+DefaultTheme.prototype.nodeToString = function(node, deep) {
+
+ if (node == null) {
+ return "";
+ } else if (node.nodeType == Node.TEXT_NODE) {
+ // Render text nodes.
+ if (node.data) {
+ return node.data;
+ } else {
+ return "";
+ }
+
+ } else if (node.nodeType == Node.ELEMENT_NODE) {
+
+ // Renderer element nodes.
+ var txt = "<" + node.nodeName;
+ if (node.attributes.length > 0)
+ for(var i=0; i<node.attributes.length; i++) {
+ var a = node.attributes.item(i);
+ txt += " " + a.name + "=\"" + a.value+"\"";
+ }
+ if (deep && node.childNodes != null && node.childNodes.length >0) {
+ txt += ">";
+ for (var i=0; i<node.childNodes.length; i++) {
+ var c = node.childNodes.item(i);
+ txt += this.nodeToString(c,deep);
+ }
+ txt += "</"+node.nodeName+">";
+ } else {
+ txt += "/>";
+ }
+ return txt;
+ }
+
+ return ""+node.nodeName + "-node";
+}
+
+
+// EVENTS
+DefaultTheme.prototype.addAddClassListener = function(theme,client,element,event,className,target,current) {
+ client.addEventListener(element,event, function(e) {
+ if (current) {
+ if (current.length) {
+ var length = current.length;
+ while (length--) {
+ theme.removeCSSClass(current[length],className);
+ delete current[length];
+ }
+ } else {
+ for (e in current) {
+ theme.removeCSSClass(current[e],className);
+ delete current[e];
+ }
+ }
+ }
+ theme.addCSSClass((target?target:element),className);
+ if (current) {
+ current[current.length] = (target?target:element);
+ }
+ }
+ );
+}
+DefaultTheme.prototype.addRemoveClassListener = function(theme,client,element,event,className,target) {
+ client.addEventListener(element,event, function(e) {
+ theme.removeCSSClass((target?target:element),className);
+ }
+ );
+}
+DefaultTheme.prototype.addToggleClassListener = function(theme,client,element,event,className,target) {
+ client.addEventListener(element,event, function(e) {
+ theme.toggleCSSClass((target?target:element),className);
+ }
+ );
+}
+DefaultTheme.prototype.addStopListener = function(theme,client,element,event) {
+ client.addEventListener(element, event, function(e) {
+ var evt = client.getEvent(e);
+ evt.stop();
+ return false;
+ }
+ );
+}
+DefaultTheme.prototype.addSetVarListener = function(theme,client,element,event,variable,key,immediate) {
+ client.addEventListener(element,event, function(e) {
+ var value = "";
+ if (typeof(key)=="string") {
+ value = key;
+ } else if (key.type=="checkbox"||key.type=="radio") {
+ value = key.checked;
+ } else if (key.type=="select-multiple") {
+ var s = new Array();
+ for (var i = 0; i < key.options.length; i++) {
+ if (key.options[i].selected) {
+ s[s.length] = key.options[i].value;
+ }
+ }
+ value = s.join(',');
+ } else {
+ value = key.value;
+ }
+ if (typeof(variable) == "string") {
+ client.changeVariable(variable,value,immediate);
+ } else {
+ theme.setVariable(client,variable,value,immediate);
+ }
+ }
+ );
+}
+DefaultTheme.prototype.addRemoveVarListener = function(theme,client,element,event,variable,key,immediate) {
+ client.addEventListener(element,event, function(e) {
+ theme.removeArrayVariable(client,variable,key,immediate);
+ }
+ );
+}
+DefaultTheme.prototype.addAddVarListener = function(theme,client,element,event,variable,key,immediate) {
+ client.addEventListener(element,event, function(e) {
+ theme.addArrayVariable(client,variable,key,immediate);
+ }
+ );
+}
+DefaultTheme.prototype.addToggleVarListener = function(theme,client,element,event,variable,key,immediate) {
+ client.addEventListener(element,event, function(e) {
+ theme.toggleArrayVariable(client,variable,key,immediate);
+ }
+ );
+}
+DefaultTheme.prototype.addExpandNodeListener = function(theme,client,img,event,subnodes,expandVariable,collapseVariable,key,immediate,target) {
+ client.addEventListener((target?target:img), event, function(e) {
+ if (img.expanded == "true") {
+ theme.removeArrayVariable(client,expandVariable,key,false);
+ theme.addArrayVariable(client,collapseVariable,key,immediate);
+ img.src = theme.root + "img/tree/off.gif";
+ img.expanded = "false";
+ } else {
+ theme.removeArrayVariable(client,collapseVariable,key,false);
+ theme.addArrayVariable(client,expandVariable,key,immediate ||
+ !img.expanded || !subnodes.childNodes || subnodes.childNodes.length <= 0);
+ img.src = theme.root + "img/tree/on.gif";
+ img.expanded = "true";
+ }
+ }
+ );
+}
+
+DefaultTheme.prototype.addTogglePopupListener = function(theme,client,element,event,popup,delay,defWidth,popupAt) {
+ client.addEventListener(element,(event=="rightclick"?"mouseup":event), function(e) {
+ var evt = client.getEvent(e);
+ if (event=="rightclick"&&!evt.rightclick) return;
+ if(evt.target.nodeName == "INPUT" || evt.target.nodeName == "SELECT") return;
+ if (evt.alt) return;
+ if (popupAt) {
+ //var p = client.getElementPosition(popupAt);
+ //theme.togglePopup(popup,p.x,(p.y+p.h),(delay?delay:0),(defWidth?defWidth:100));
+
+ // Now using mouse coordinates, 9.6.2006 - Jouni Koivuviita
+ theme.togglePopup(popup,(evt.mouseX+6),(evt.mouseY+12),(delay?delay:0),(defWidth?defWidth:100));
+ } else {
+ theme.togglePopup(popup,(evt.mouseX+6),(evt.mouseY+12),(delay?delay:0),(defWidth?defWidth:100));
+ }
+ evt.stop();
+ }
+ );
+}
+DefaultTheme.prototype.addShowPopupListener = function(theme,client,element,event,popup,delay,defWidth) {
+ client.addEventListener(element,(event=="rightclick"?"click":event), function(e) {
+ var evt = client.getEvent(e);
+ if (event=="rightclick"&&!evt.rightclick) return;
+
+ theme.showPopup(client,popup,evt.mouseX,evt.mouseY,(delay?delay:0),(defWidth?defWidth:100));
+ evt.stop();
+ }
+ );
+}
+// TODO dontstop -> stop in all listeners
+DefaultTheme.prototype.addHidePopupListener = function(theme,client,element,event,dontstop) {
+ client.addEventListener(element,(event=="rightclick"?"click":event), function(e) {
+ var evt = client.getEvent(e);
+ if (evt.alt) return;
+ if (event=="rightclick"&&!evt.rightclick) return;
+ theme.hidePopup();
+ if (!dontstop) {
+ evt.stop();
+ }
+ }
+ );
+}
+
+
+
+
+///////
+
+/**
+ * Render tree as a menubar.
+ * NOTE:
+ * First level nodes are not selectable - menu opens with click.
+ * If style == "coolmenu", immediate is forced.
+ *
+ */
+
+DefaultTheme.prototype.renderTreeMenu = function(renderer,uidl,target,layoutInfo) {
+
+ var theme = renderer.theme;
+
+ // Create container element
+ var div = renderer.theme.createPaintableElement(renderer,uidl,target,layoutInfo);
+ if (uidl.getAttribute("invisible")) return; // Don't render content if invisible
+
+ // Get tree attributes
+ var style = uidl.getAttribute("style");
+ var immediate = ("true" == uidl.getAttribute("immediate")||style=="coolmenu");
+ var disabled = ("true" == uidl.getAttribute("disabled"));
+ var readonly = ("true" == uidl.getAttribute("readonly"));
+ var selectMode = uidl.getAttribute("selectmode");
+ var selectable = selectMode == "multi" || selectMode == "single";
+ var selected;
+ if (selectable) {
+ selected = new Object();
+ }
+ var selectionVariable = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","selected"));
+ var expandVariable = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","expand"));
+ var collapseVariable = theme.createVariableElementTo(div,theme.getVariableElement(uidl,"array","collapse"));
+
+ var actions = null;
+ var actionVar = null;
+ var alNode = theme.getFirstElement(uidl,"actions")
+ if (alNode) {
+ actionVar = theme.createVariableElementTo(div,theme.getVariableElement(alNode,"string","action"));
+ actions = new Object();
+ var ak = alNode.getElementsByTagName("action");
+ for (var i=0;i<ak.length;i++) {
+ actions[ak[i].getAttribute("key")] = ak[i].getAttribute("caption");
+ }
+ }
+ delete alNode;
+
+ // Create default header
+ var caption = renderer.theme.renderDefaultComponentHeader(renderer,uidl,div,layoutInfo);
+
+ // Content DIV
+ var content = theme.createElementTo(div,"div","content menu");
+
+ // Iterate all nodes
+ for (var i = 0; i< uidl.childNodes.length;i++) {
+ var node = uidl.childNodes[i];
+ if (node.nodeName == "node" || node.nodeName == "leaf") {
+ theme.renderTreeMenuNode(renderer,node,content,selectable,selectMode,selected,selectionVariable,expandVariable,collapseVariable,actions,actionVar,immediate,disabled,readonly,0);
+ }
+ }
+}
+
+DefaultTheme.prototype.renderTreeMenuNode = function(renderer,node,target,selectable,selectMode,selected,selectionVariable,expandVariable,collapseVariable,actions,actionVar,immediate,disabled,readonly,level) {
+
+ var theme = renderer.theme;
+ var client = renderer.client;
+
+ var n = theme.createElementTo(target,"div",(level==0?"inline clickable":"clickable"));
+
+
+ // Caption
+ var cap = theme.createElementTo(n,"div","inline caption pad");
+ theme.createTextNodeTo(cap,node.getAttribute("caption"));
+
+ // Expand/collapse/spacer button
+ var img = theme.createElementTo(n,"img","icon-mini");
+ img.align = "absbottom";
+ var key = node.getAttribute("key");
+ var icon = node.getAttribute("icon");
+ if (icon) {
+ var iconurl = theme.root+icon.split("theme:")[1];
+ var iimg = theme.createElementTo(n,"img","icon-mini");
+ iimg.src = iconurl;
+ }
+
+
+ // Hover effects
+ if (!disabled&&!readonly) {
+ theme.addAddClassListener(theme,client,n,"mouseover","selected",n);
+ theme.addRemoveClassListener(theme,client,n,"mouseout","selected",n);
+ }
+
+ // Server-side selection
+ if (selectable && node.getAttribute("selected") == "true") {
+ theme.addCSSClass(n,"selected");
+ selected[key] = n;
+ }
+
+ // Indicate selection
+ if (theme.listContainsInt(selectionVariable.value,key)) {
+ theme.addCSSClass(n, "selected");
+ }
+
+ // Selection listeners
+ if (selectable && !disabled && (level != 0 || node.nodeName == "leaf")) {
+ if (!readonly) {
+ if (selectMode == "single") {
+ theme.addAddClassListener(theme,client,n,"click","selected",n,selected);
+ theme.addSetVarListener(theme,client,n,"click",selectionVariable,key,immediate);
+
+ } else if (selectMode == "multi") {
+ theme.addToggleClassListener(theme,client,n,"click","selected");
+ theme.addToggleVarListener(theme,client,n,"click",selectionVariable,key,immediate);
+
+ }
+ }
+ }
+
+ // Actions
+ if (!disabled && !readonly) {
+ for (var i = 0; i< node.childNodes.length;i++) {
+ var childNode = node.childNodes[i];
+ if (childNode.nodeName == "al" ) {
+ theme.renderActionPopup(renderer,childNode,n,actions,actionVar,key,1); // TODO check
+ }
+ }
+ }
+
+ // Render all sub-nodes
+ if (node.nodeName == "node") {
+ var subnodes = theme.createElementTo(target,"div","hide popup");
+ var inner = theme.createElementTo(subnodes,"div","border");
+ theme.addTogglePopupListener(theme,client,n,(level==0?"click":"mouseover"),subnodes,0,null,n);
+ //theme.addToggleClassListener(theme,client,n,(level==0?"click":"mouseover"),"hide",subnodes)
+ if (node.childNodes != null && node.childNodes.length >0) {
+ img.src = theme.root + "img/tree/empty.gif";
+ img.expanded = "true";
+ } else {
+ img.src = theme.root + "img/tree/empty.gif";
+ img.expanded = "false";
+ }
+ for (var i = 0; i< node.childNodes.length;i++) {
+ var childNode = node.childNodes[i];
+ if (childNode.nodeName == "node" || childNode.nodeName == "leaf") {
+ theme.renderTreeMenuNode(renderer,childNode,inner,selectable,selectMode,selected,selectionVariable,expandVariable,collapseVariable,actions,actionVar,immediate,disabled,readonly,level+1);
+ }
+ }
+
+ // Add event listener
+ if (!disabled&&level!=0) {
+ var target = (selectable&&!readonly?img:n);
+ theme.addToggleClassListener(theme,client,target,"mouseup","hidden",subnodes);
+ theme.addExpandNodeListener(theme,client,img,"mouseup",subnodes,expandVariable,collapseVariable,key,immediate,target);
+ theme.addStopListener(theme,client,target,"mouseup");
+ theme.addStopListener(theme,client,target,"click");
+ }
+
+ } else {
+ img.src = theme.root + "img/tree/empty.gif";
+ }
+}
+
+
+
+/**
+* Additions from rondocontrol.js
+* 5.6.2006 - Jouni Koivuviita
+*/
+
+DefaultTheme.prototype.renderPanel = function(renderer,uidl,target,layoutInfo) {
+ // Shortcuts
+ var theme = renderer.theme;
+ var style = uidl.getAttribute("style");
+ // Create component element
+ var div = theme.createPaintableElement(renderer,uidl,target);
+
+ /* New panel theme, 8.6.2006 - Jouni Koivuviita */
+ div.innerHTML = "<div class=\"top\"><div class=\"right\"></div><div class=\"left\"><div class=\"title\"></div></div></div><div class=\"middle\"></div><div class=\"bottom\"><div class=\"right\"></div><div class=\"left\"></div></div>";
+ var cap = div.firstChild.firstChild.nextSibling.firstChild;
+ var content = div.childNodes[1];
+ theme.applyWidthAndHeight(uidl,div.childNodes[1],"height");
+ theme.applyWidthAndHeight(uidl,div,"width");
+
+ /*
+ div.innerHTML = "<TABLE width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><TR height=\"35\"><TD width=\"12\"><IMG onload=\"png(this);\" src=\""+theme.root+"img/top-left.png\"></TD><TD style=\"background: url('"+theme.root+"img/top.png') !important;background: none;background-position:right;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/top.png', sizingMethod='scale');\"></TD><TD width=\"12\"><IMG onload=\"png(this);\" src=\""+theme.root+"img/top-right.png\"></TD></TR><TR><TD style=\"background: url('"+theme.root+"img/left.png') !important;background: none;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/left.png', sizingMethod='scale');\"></TD><TD bgcolor=white></TD><TD style=\"background: url('"+theme.root+"img/right.png') !important;background: none;background-position:right;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/right.png', sizingMethod='scale');\"></TD></TR><TR height=\"12\"><TD><IMG onload=\"png(this);\" src=\""+theme.root+"img/bottom-left.png\"></TD><TD style=\"background: url('"+theme.root+"img/bottom.png') !important;background: none;background-position:right;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/bottom.png', sizingMethod='scale');\"></TD><TD><IMG onload=\"png(this);\" src=\""+theme.root+"img/bottom-right.png\"></TD></TR></TABLE>";
+ var cap = div.firstChild.firstChild.firstChild.childNodes[1];
+ var content = div.firstChild.firstChild.childNodes[1].childNodes[1];
+ */
+
+ theme.renderDefaultComponentHeader(renderer,uidl,cap);
+ theme.renderChildNodes(renderer, uidl, content);
+}
+
+DefaultTheme.prototype.renderPanelModal = function(renderer,uidl,target,layoutInfo,alignment) {
+ // Shortcuts
+ var theme = renderer.theme;
+ //var parentTheme = theme.parent;
+ // Create component element
+ var div = theme.createPaintableElement(renderer,uidl,target);
+ var html = "<IFRAME frameborder=\"0\" style=\"border:none;z-index:9997;position:absolute;top:0px;left:0px;width:100%;height:100%;background-color:white;filter: alpha(opacity=80);opacity:0.8;\"></IFRAME>";
+ html += "<DIV align=\"center\" style=\"position:absolute;top:0px;width:100%;left:0px;z-index:9999;filter: alpha(opacity=100);opacity:1;\"><TABLE cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><TR height=\"35\"><TD width=\"12\"><IMG onload=\"png(this);\" src=\""+theme.root+"img/top-left.png\"></TD><TD style=\"background: url('"+theme.root+"img/top.png') !important;background: none;background-position:right;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/top.png', sizingMethod='scale');\"></TD><TD width=\"12\"><IMG onload=\"png(this);\" src=\""+theme.root+"img/top-right.png\"></TD></TR><TR><TD style=\"background: url('"+theme.root+"img/left.png') !important;background: none;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/left.png', sizingMethod='scale');\"></TD><TD bgcolor=white ></TD><TD style=\"background: url('"+theme.root+"img/right.png') !important;background: none;background-position:right;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/right.png', sizingMethod='scale');\"></TD></TR><TR height=\"12\"><TD><IMG onload=\"png(this);\" src=\""+theme.root+"img/bottom-left.png\"></TD><TD style=\"background: url('"+theme.root+"img/bottom.png') !important;background: none;background-position:right;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/bottom.png', sizingMethod='scale');\"></TD><TD><IMG onload=\"png(this);\" src=\""+theme.root+"img/bottom-right.png\"></TD></TR></TABLE><DIV>";
+ div.innerHTML = html;
+ var overlay = div.firstChild;
+ overlay.style.width = div.ownerDocument.body.offsetWidth + "px";
+ overlay.style.height = div.ownerDocument.body.offsetHeight + "px";
+ var table = div.childNodes[1].firstChild;
+ var cap = table.firstChild.firstChild.childNodes[1];
+ var content = table.firstChild.childNodes[1].childNodes[1];
+
+ theme.renderDefaultComponentHeader(renderer,uidl,cap);
+ theme.renderChildNodes(renderer, uidl, content);
+
+ var ifrdiv = theme.createElementTo(div,"div");
+
+ html = "<IFRAME frameborder=\"0\" style=\"border:none;z-index:9998;position:absolute;top:"+(div.childNodes[1].offsetTop+5)+"px;left:"+(table.offsetLeft+5)+"px;width:"+(table.offsetWidth-7)+"px;height:"+(table.offsetHeight-7)+"px;background-color:white;filter: alpha(opacity=100);opacity:1;\"></IFRAME>";
+ ifrdiv.innerHTML += html;
+}
+
+DefaultTheme.prototype.renderPanelLight = function(renderer,uidl,target,layoutInfo) {
+ // Shortcuts
+ var theme = renderer.theme;
+ var style = uidl.getAttribute("style");
+ // Create component element
+ var div = theme.createPaintableElement(renderer,uidl,target);
+
+ div.innerHTML = "<TABLE width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><TR><TD width=\"12\"><IMG onload=\"png(this);\" src=\""+theme.root+"img/top-left-lite.png\"></TD><TD style=\"background: url('"+theme.root+"img/top-lite.png') !important;background: none;background-position:right;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/top-lite.png', sizingMethod='scale');\"></TD><TD width=\"12\"><IMG onload=\"png(this);\" src=\""+theme.root+"img/top-right-lite.png\"></TD></TR><TR><TD style=\"background: url('"+theme.root+"img/left.png') !important;background: none;background-position:right;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/left.png', sizingMethod='scale');\"></TD><TD bgcolor=white></TD><TD style=\"background: url('"+theme.root+"img/right.png') !important;background: none;background-position:right;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/right.png', sizingMethod='scale');\"></TD></TR><TR><TD><IMG onload=\"png(this);\" src=\""+theme.root+"img/bottom-left.png\"></TD><TD style=\"background: url('"+theme.root+"img/bottom.png') !important;background: none;background-position:right;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/bottom.png', sizingMethod='scale');\"></TD><TD><IMG onload=\"png(this);\" src=\""+theme.root+"img/bottom-right.png\"></TD></TR></TABLE>";
+
+ var content = div.firstChild.firstChild.childNodes[1].childNodes[1];
+
+ theme.renderDefaultComponentHeader(renderer,uidl,content);
+ theme.renderChildNodes(renderer, uidl, content);
+}
+
+DefaultTheme.prototype.renderPanelNone = function(renderer,uidl,target,layoutInfo) {
+ // Shortcuts
+ var theme = renderer.theme;
+ var style = uidl.getAttribute("style");
+ // Create component element
+ var div = theme.createPaintableElement(renderer,uidl,target);
+
+ var content = theme.createElementTo(div,"div");
+
+ theme.renderDefaultComponentHeader(renderer,uidl,content);
+ theme.renderChildNodes(renderer, uidl, content);
+}
+
+DefaultTheme.prototype.renderTabSheet = function(renderer,uidl,target,layoutInfo) {
+ // Shortcuts
+ var theme = renderer.theme;
+
+ // Create component element
+ var div = theme.createPaintableElement(renderer,uidl,target);
+ if (uidl.getAttribute("invisible")) return;
+
+ var style = uidl.getAttribute("style");
+ var disabled = ("true"==uidl.getAttribute("disabled"));
+
+ var cdiv = theme.createElementTo(div,"div");
+ var caption = theme.renderDefaultComponentHeader(renderer,uidl,cdiv,layoutInfo);
+ div = theme.createElementTo(div,"div");
+
+ // Tabs
+ var tabNodes = theme.getChildElements(uidl,"tabs");
+ if (tabNodes != null && tabNodes.length >0) tabNodes = theme.getChildElements(tabNodes[0],"tab");
+ var selectedTabNode = null;
+ if (tabNodes != null && tabNodes.length >0) {
+ var html = "<TABLE width=\"100%\" class=\"tabsheet-table\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><TBODY>";
+ html += "<TR valign=\"bottom\"><TD></TD>";
+
+ var posttabs = "<TR valign=\"top\"><TD><IMG onload=\"png(this);\" src=\""+theme.root+"img/tabsheet/top-left-lite.png\"/></TD>";
+ var len = tabNodes.length;
+ for (var i=0; i<len;i++) {
+ var tab = tabNodes[i];
+ var caption = tab.getAttribute("caption");
+ var icon = tab.getAttribute("icon");
+ if (icon) icon = theme.root+icon.split("theme://")[1];
+ var selected = ("true"==tab.getAttribute("selected"));
+ var disabled = ("true"==tab.getAttribute("disabled"));
+ var offset = (selected?6:4);
+
+ var variant = "";
+ if (disabled) {
+ variant = "-dis";
+ } else if (selected) {
+ variant = "-on";
+ }
+
+ if (selected) selectedTabNode = tab;
+
+ html += "<TD width=\"1\" align=\"right\"><IMG onload=\"png(this);\" onload=\"png(this);\" src=\""+theme.root+"img/tabsheet/top-left"+variant+".png\"/></TD><TD class=\""+(disabled?"caption":"caption clickable")+"\" style=\"background-image: url('"+theme.root+"img/tabsheet/top"+variant+".png') !important;background: none;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/tabsheet/top"+variant+".png', sizingMethod='scale');\">"
+ html += "<DIV style=\"padding-top:0.5em;\" class=\"caption"+(selected&&!disabled?"":" clickable")+"\">";
+ if (icon) html += "<IMG onload=\"png(this);\" class=\"icon\" src=\""+icon+"\"/>";
+ html += caption+"</DIV>";
+ html += "</TD><TD><IMG onload=\"png(this);\" src=\""+theme.root+"img/tabsheet/top-right"+variant+".png\"/></TD>";
+
+
+ // POSTTABS
+ posttabs += "<TD align=\"right\" style=\"background-image: url('"+theme.root+"img/tabsheet/top-lite.png') !important;background: none;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/tabsheet/top-lite.png', sizingMethod='scale');\"><IMG onload=\"png(this);\" height=\""+(selected?6:4)+"\" width=\"8\" src=\""+theme.root+"img/tabsheet/tab-left.png\"/></TD><TD "+(selected?"bgcolor=\"white\"":"style=\"background-image: url('"+theme.root+"img/tabsheet/top-lite.png') !important;background: white;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/tabsheet/top-lite.png', sizingMethod='scale');\"")+"></TD><TD style=\"background-image: url('"+theme.root+"img/tabsheet/top-lite.png') !important;background: none;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/tabsheet/top-lite.png', sizingMethod='scale');\"><IMG onload=\"png(this);\" height=\""+(selected?6:4)+"\" width=\"8\" src=\""+theme.root+"img/tabsheet/tab-right.png\"/></TD>";
+ }
+ html += "<TD width=\"100%\"></TD></TR>"+posttabs+"<TD style=\"background-image: url('"+theme.root+"img/tabsheet/top-lite.png') !important;background: none;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/tabsheet/top-lite.png', sizingMethod='scale');\" ></TD><TD><IMG onload=\"png(this);\" src=\""+theme.root+"img/tabsheet/top-right-lite.png\"/></TD></TR>";
+
+ //Content
+ html +="</TBODY></TABLE><TABLE width=\"100%\" class=\"tabsheet-table\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><TBODY><TR valign=\"top\"><TD style=\"width:12px;background-image: url('"+theme.root+"img/tabsheet/left.png') !important;background: none;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/tabsheet/left.png', sizingMethod='scale');\"></TD><TD style=\"width:100% !important;width:auto;\" class=\"tabsheet-content\" bgcolor=\"white\" colspan=\""+(len*3+1)+"\"><DIV></DIV></TD><TD width=\"12\" style=\"background-image: url('"+theme.root+"img/tabsheet/right.png') !important;background: none;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/tabsheet/right.png', sizingMethod='scale');\"></TD></TR>";
+ html += "<TR height=\"12\" valign=\"top\"><TD width=\"8\"><IMG onload=\"png(this);\" src=\""+theme.root+"img/tabsheet/bottom-left.png\"></TD><TD style=\"background-image: url('"+theme.root+"img/tabsheet/bottom.png') !important;background: none;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+theme.root+"img/tabsheet/bottom.png', sizingMethod='scale');\" colspan=\""+(len*3+1)+"\"></TD><TD><IMG onload=\"png(this);\" src=\""+theme.root+"img/tabsheet/bottom-right.png\"></TD></TR></TBODY></TABLE>";
+ div.innerHTML = html;
+
+ // TODO click listeners
+
+ if (!disabled) {
+ var varId = theme.getVariableElement(uidl,"string","selected").getAttribute("id");
+ for (var i=0; i<len;i++) {
+ var tabNode = tabNodes[i];
+ if (tabNode == selectedTabNode||("true"==tabNode.getAttribute("disabled"))) continue;
+ var key = tabNode.getAttribute("key");
+ var tab = div.firstChild.firstChild.firstChild.childNodes[2+i*3];
+ theme.addAddClassListener(theme,client,tab,"mouseover","over",tab);
+ theme.addRemoveClassListener(theme,client,tab,"mouseout","over",tab);
+ theme.addSetVarListener(theme,client,tab,"click",varId,key,true);
+ }
+ }
+
+ var content = div.childNodes[1].firstChild.firstChild.childNodes[1];
+ if (selectedTabNode) {
+ theme.renderChildNodes(renderer,selectedTabNode, content);
+ }
+
+ }
+
+} \ No newline at end of file
diff --git a/WebContent/themes/example/example_styles.css b/WebContent/themes/example/example_styles.css
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/WebContent/themes/example/example_styles.css
diff --git a/WebContent/themes/example/example_theme.js b/WebContent/themes/example/example_theme.js
new file mode 100644
index 0000000000..00f8a37319
--- /dev/null
+++ b/WebContent/themes/example/example_theme.js
@@ -0,0 +1,80 @@
+/** Construct example theme that extends some other theme
+ * typically the DefaultTheme.
+ *
+ * @param themeRoot The base URL of theme resources.
+ * @param defaultTheme Theme to be extended.
+ *
+ */
+
+
+function ExampleTheme(themeRoot, defaultTheme) {
+ this.themeName = "ExampleTheme";
+ this.root = themeRoot;
+ this.parent = defaultTheme;
+
+ // Tell the parent where to look for theme icons
+ this.parent.iconRoot = this.root;
+}
+
+/** Register all renderers to a ajax client.
+ *
+ * @param client The ajax client instance.
+ */
+ExampleTheme.prototype.registerTo = function(client) {
+
+ // We register our own customlayout handler.
+ // This way the layouts can be in different place.
+ client.registerRenderer(this,"customlayout",null,this.renderCustomLayout);
+
+}
+
+ExampleTheme.prototype.renderCustomLayout = function(renderer,uidl,target,layoutInfo) {
+
+ // Shortcuts
+ var theme = renderer.theme;
+ var parentTheme = theme.parent;
+
+ // Get style
+ var style = uidl.getAttribute("style");
+ if (style == null) return null;
+
+ // Load the layout
+ var url = theme.root + style + ".html";
+ var text = renderer.client.loadDocument(url,false);
+ if (text == null) return null;
+
+ // Create containing element
+ var main = parentTheme.createPaintableElement(renderer,uidl,target);
+
+ var n = parentTheme.createElementTo(main, "div");
+ n.setAttribute("id",uidl.getAttribute("id"));
+ n.innerHTML=text;
+ var divs = n.getElementsByTagName("div");
+ for (var i=0; i<divs.length; i++) {
+ var div = divs.item(i);
+ var name = div.getAttribute("location");
+ if (name != null) {
+ for (var j=0; j < uidl.childNodes.length; j++) {
+ var c = uidl.childNodes.item(j);
+ if (c.nodeType == Node.ELEMENT_NODE
+ && c.nodeName == "location"
+ && c.getAttribute("name") == name) {
+
+ for (var k=0; k<c.childNodes.length; k++) {
+ var cc = c.childNodes.item(k);
+ if (cc.nodeType == Node.ELEMENT_NODE) {
+ var parent = div.parentNode;
+
+ // TODO
+ if (parent != null) {
+ parentTheme.removeAllChildNodes(div);
+ var newNode = renderer.client.renderUIDL(cc,div);
+ }
+ }
+ }
+
+ }
+ }
+ }
+ }
+}
diff --git a/WebContent/themes/playground/components.html b/WebContent/themes/playground/components.html
new file mode 100644
index 0000000000..4aa14143cc
--- /dev/null
+++ b/WebContent/themes/playground/components.html
@@ -0,0 +1,227 @@
+<HTML>
+<HEAD>
+ <link rel="stylesheet" href="default.css" type="text/css"/>
+</HEAD>
+<BODY>
+
+
+<DIV class="table">
+ <DIV class="caption pad">Table
+
+ <DIV class="outset popup">
+ <DIV class="border pad">
+ <IMG class="icon" src="img/icon.gif"/>
+ <DIV class="content">
+ This is the popup description.
+ IT can be multiline.
+ </DIV>
+ </DIV>
+ </DIV>
+
+ </DIV>
+
+ <DIV class="outset">
+ <DIV class="border">
+ <TABLE>
+ <TR class="header">
+ <TD class="empty"></TD>
+ <TD class="cheader clickable bg"><DIV class="caption">R header 1</DIV></TD>
+ <TD class="cheader clickable bg"><DIV class="caption">R header 2</DIV></TD>
+ <TD class="cheader clickable bg"><DIV class="caption">R header 3</DIV></TD>
+ </TR>
+ <TR class="odd clickable">
+ <TD class="rheader"><DIV class="caption">C header 1</DIV></TD>
+ <TD>cell</TD>
+ <TD>cell</TD>
+ <TD>cell</TD>
+ </TR>
+ <TR class="even clickable">
+ <TD class="rheader"><DIV class="caption">C header</DIV></TD>
+ <TD>cell</TD>
+ <TD>cell</TD>
+ <TD>cell</TD>
+ </TR>
+ <TR class="odd clickable">
+ <TD class="rheader"><DIV class="caption">C header</DIV></TD>
+ <TD>cell</TD>
+ <TD>cell with some more stuff<br/>asdasdas</TD>
+ <TD>cell</TD>
+ </TR>
+ <TR class="even clickable">
+ <TD class="rheader"><DIV class="caption">C header</DIV></TD>
+ <TD>cell</TD>
+ <TD>cell</TD>
+ <TD>cell</TD>
+ </TR>
+ </TABLE>
+ <DIV class="nav pad">&lt;&lt; 5 / 72 &gt;&gt;</DIV>
+ </DIV>
+ </DIV>
+</DIV>
+
+<BR/>
+
+<DIV class="panel outset">
+ <DIV class="border">
+ <DIV class="caption pad">Panel</DIV>
+ <DIV class="content">
+ This is supposed to be panel content.
+ <P>
+ The quick brown fox jumps over the lazy dog.
+ The quick brown fox jumps over the lazy dog.
+ The quick brown fox jumps over the lazy dog.
+ The quick brown fox jumps over the lazy dog.
+ The quick brown fox jumps over the lazy dog.
+ The quick brown fox jumps over the lazy dog.
+
+
+ <DIV class="tabsheet">
+ <DIV class="caption">Tabsheet</DIV>
+ <DIV class="tabs">
+ <DIV class="tab clickable inline"><DIV class="caption border pad inline">Tab 1</DIV></DIV>
+ <DIV class="tab-on inline"><DIV class="caption border pad inline">Tab 2</DIV></DIV>
+ <DIV class="tab clickable inline"><DIV class="caption border pad inline">Tab 3</DIV></DIV>
+ <DIV class="tab disabled inline"><DIV class="caption border pad inline">Disabled</DIV></DIV>
+ </DIV>
+ <DIV class="outset">
+ <DIV class="content border">
+ This is supposed to be tabsheet content.
+ <P>
+ The quick brown fox jumps over the lazy dog.
+ The quick brown fox jumps over the lazy dog.
+ The quick brown fox jumps over the lazy dog.
+ </P>
+ </DIV>
+ </DIV>
+
+ </DIV>
+
+<BR/>
+
+ <DIV class="button outset clickable">
+ <DIV class="border pad bg">
+ <DIV class="caption">Ok</DIV>
+ </DIV>
+ </DIV>
+
+ <DIV class="button outset clickable error">
+ <DIV class="border pad bg">
+ <DIV class="caption">Error</DIV>
+ </DIV>
+ </DIV>
+
+ <DIV class="button outset disabled">
+ <DIV class="border pad bg">
+ <DIV class="caption">Disabled asdasdasdasdasdasdasdasdasd</DIV>
+ </DIV>
+ </DIV>
+
+ <DIV class="link clickable">
+ <DIV class="border pad">
+ <DIV class="caption">This is a link</DIV>
+ <DIV class="description">
+ Perhaps a link should display it's description directly? I think so :-)<br/>
+ Multiline.
+ </DIV>
+ </DIV>
+ </DIV>
+
+ <DIV class="link disabled">
+ <DIV class="border pad">
+ <DIV class="caption">This is a link</DIV>
+ <DIV class="description">
+ Perhaps a link should display it's description directly? I think so :-)<br/>
+ Multiline.
+ </DIV>
+ </DIV>
+ </DIV>
+
+ </DIV>
+
+ </DIV>
+</DIV>
+
+<BR/>
+<DIV class="outset">
+ <DIV class="border">
+ <DIV class="caption capshift inline pad">Panel lite</DIV>
+ <DIV class="content">
+
+ <DIV class="textfield">
+ <DIV class="caption">Textfield</DIV>
+ <DIV class="border">
+ <DIV class="inset">
+ <INPUT type="text">
+ </DIV>
+ </DIV>
+ </DIV>
+
+ <DIV class="textfield error">
+ <DIV class="caption">Textfield</DIV>
+ <DIV class="border">
+ <DIV class="inset">
+ <INPUT type="text">
+ </DIV>
+ </DIV>
+ </DIV>
+
+ <DIV class="textfield disabled">
+ <DIV class="caption">Disabled</DIV>
+ <DIV class="border">
+ <DIV class="inset">
+ <INPUT type="text">
+ </DIV>
+ </DIV>
+ </DIV>
+
+ </DIV>
+ </DIV>
+ </DIV>
+</DIV>
+
+
+
+<DIV class="tree">
+ <DIV class="placeholder">
+ <DIV class="caption">Tree</DIV>
+
+ <DIV class="content">
+ <DIV class="node clickable">
+ <IMG src="img/tree/on.gif" class="icon">
+ <DIV class="caption inline">Node</DIV>
+ </DIV>
+ <DIV class="nodes">
+ <DIV class="node clickable">
+ <IMG src="img/tree/off.gif" class="icon">
+ <DIV class="caption inline">Node</DIV>
+ </DIV>
+ <DIV class="node clickable">
+ <IMG src="img/tree/on.gif" class="icon">
+ <DIV class="caption inline">Node</DIV>
+ </DIV>
+ <DIV class="nodes">
+ <DIV class="node clickable">
+ <IMG src="img/tree/off.gif" class="icon">
+ <DIV class="caption inline">Node</DIV>
+ </DIV>
+ <DIV class="node clickable">
+ <IMG src="img/tree/off.gif" class="icon">
+ <DIV class="caption inline">Node</DIV>
+ </DIV>
+ </DIV>
+ </DIV>
+ <DIV class="node clickable">
+ <IMG src="img/tree/off.gif" class="icon">
+ <DIV class="caption inline">Node</DIV>
+ </DIV>
+ <DIV class="node clickable">
+ <IMG src="img/tree/off.gif" class="icon">
+ <DIV class="caption inline">Node</DIV>
+ </DIV>
+
+ </DIV>
+</DIV>
+
+
+</BODY>
+</HTML> \ No newline at end of file
diff --git a/WebContent/themes/playground/default.css b/WebContent/themes/playground/default.css
new file mode 100644
index 0000000000..936031d50c
--- /dev/null
+++ b/WebContent/themes/playground/default.css
@@ -0,0 +1,238 @@
+* {
+ font-size: 10pt;
+ font-family: sans-serif;
+}
+
+.popup {
+ font-weight: normal;
+ position: absolute;
+ z-index: 1000;
+ background: white;
+}
+.popup .content {
+ display: inline;
+}
+.popup .icon {
+ vertical-align: middle;
+}
+
+.popup.hide {
+ display: inline;
+ border: none;
+}
+.popup.hide .border {
+ display: inline;
+ border: none;
+}
+.popup.hide .icon {
+ display: inline;
+ width: 16px;
+ height: 16px;
+}
+.popup.hide .content {
+ display: none;
+}
+
+.inline {
+ display: inline;
+}
+
+.pad {
+ padding-top: 3px;
+ padding-bottom: 3px;
+ padding-left: 7px;
+ padding-right: 7px;
+}
+
+.bg {
+ background-image: url('img/bg1.gif');
+ background-repeat: repeat-x;
+}
+
+.disabled {
+ color: #999999;
+ opacity: 0.5;
+ filter: alpha(opacity=50);
+}
+.disabled .caption {
+ color: #999999;
+}
+.disabled .border .caption {
+ color: #999999;
+}
+
+.caption {
+ font-weight: bold;
+ color: black;
+ clear: both;
+}
+
+.content {
+ padding: 7px;
+}
+
+.capshift {
+ position: relative;
+ top: -10px;
+ left: 3px;
+ background-color: white;
+}
+
+.clickable {
+ cursor: hand;
+ cursor: pointer;
+}
+DIV.clickable.outset:hover {
+ border: 1px solid #eeeeee;
+}
+DIV.clickable:hover .border {
+ border: 1px solid #aaaaee;
+}
+
+.border {
+ border-top: 1px solid #aaaaaa;
+ border-left: 1px solid #aaaaaa;
+ border-bottom: 1px solid #aaaaaa;
+ border-right: 1px solid #aaaaaa;
+}
+
+.error .border {
+ border-color: #ee6666;
+}
+
+.inset {
+ border-top: 2px solid #eeeeee;
+ border-left: 2px solid #eeeeee;
+}
+
+.outset {
+ border-bottom: 2px solid #eeeeee;
+ border-right: 2px solid #eeeeee;
+}
+
+/* COMPONENTS */
+
+
+.link {
+ border: 1px solid white;
+}
+.link .caption {
+ color: blue;
+}
+.link .description {
+ font-size: smaller;
+ padding-left: 7px;
+}
+.link DIV.border {
+ border: 1px solid white;
+}
+DIV.link.clickable:hover .border {
+ background-image: url('img/bg1.gif');
+ background-repeat: repeat-x;
+}
+
+
+.tabs {
+ padding-left: 0px !important;
+ padding-left: 1px;
+ padding-top: 5px;
+ padding-bottom: 3px;
+}
+.tab, .tab-on {
+ border-right: 2px solid #eeeeee;
+ border-bottom: none;
+}
+.tab-on {
+ position: relative;
+ top: 1px;
+}
+.tab .caption {
+ background-image: url('img/bg1.gif');
+ background-repeat: repeat-x;
+ border-bottom: none;
+}
+DIV.tab.clickable:hover .caption {
+ background-image: url('img/bg1.gif');
+ background-repeat: repeat-x;
+}
+.tab-on .caption {
+ border-bottom: 1px solid white;
+ border-bottom: none;
+ background-color: white;
+}
+
+.node {
+ border: 1px solid white;
+}
+.nodes {
+ padding-left: 16px;
+}
+.node .caption {
+ vertical-align: top;
+ font-weight: normal;
+}
+DIV.node:hover{
+ border: 1px solid #aaaaee;
+ background-image: url('img/bg1.gif');
+ background-repeat: repeat-x;
+}
+DIV.node:hover .caption {
+ color: blue;
+}
+
+.panel {
+ background-image: url('img/bg3.jpg');
+ background-repeat: no-repeat;
+}
+
+DIV.textfield:hover .border {
+ border: 1px solid #aaaaee;
+}
+.textfield INPUT {
+ border: none;
+}
+
+.table TABLE {
+ border-collapse: collapse;
+ empty-cells: show;
+ xborder: 1px solid #999999;
+ width: 100%;
+}
+.table TD {
+ padding-left: 5px;
+ padding-right: 5px;
+ padding-top: 3px;
+ padding-bottom: 3px;
+ border-left: 1px solid #eeeeee;
+ border-bottom: 1px solid #eeeeee;
+}
+.table .odd {
+ background-color: #f9f9f9;
+}
+.table .cheader {
+ border-bottom-color: #999999;
+ border-left: 1px solid #999999;
+}
+.table .rheader {
+ text-align: right;
+ border-right: 1px solid #999999;
+ border-left: none;
+}
+.table .empty {
+ border-bottom-color: #999999;
+ border-right-color: #999999;
+}
+.table .nav {
+ border-top: 2px solid #eeeeee;
+ text-align: center;
+}
+.table TR.clickable:hover {
+ background-image: url('img/bg1.gif');
+ background-repeat: repeat-x;
+}
+.table TR.clickable:hover TD {
+ border-bottom: 1px solid #9999ee;
+}
+.over .caption {
+ color: #6666cc;
+} \ No newline at end of file
diff --git a/WebContent/themes/playground/img/bg1.gif b/WebContent/themes/playground/img/bg1.gif
new file mode 100644
index 0000000000..f93245029c
--- /dev/null
+++ b/WebContent/themes/playground/img/bg1.gif
Binary files differ
diff --git a/WebContent/themes/playground/img/bg2.gif b/WebContent/themes/playground/img/bg2.gif
new file mode 100644
index 0000000000..1cee3071f6
--- /dev/null
+++ b/WebContent/themes/playground/img/bg2.gif
Binary files differ
diff --git a/WebContent/themes/playground/img/bg3.jpg b/WebContent/themes/playground/img/bg3.jpg
new file mode 100644
index 0000000000..51a70f18c3
--- /dev/null
+++ b/WebContent/themes/playground/img/bg3.jpg
Binary files differ
diff --git a/WebContent/themes/playground/img/tree/off.gif b/WebContent/themes/playground/img/tree/off.gif
new file mode 100644
index 0000000000..bc8b454f81
--- /dev/null
+++ b/WebContent/themes/playground/img/tree/off.gif
Binary files differ
diff --git a/WebContent/themes/playground/img/tree/on.gif b/WebContent/themes/playground/img/tree/on.gif
new file mode 100644
index 0000000000..b23d660d90
--- /dev/null
+++ b/WebContent/themes/playground/img/tree/on.gif
Binary files differ
diff --git a/WebContent/themes/playground/table-prototypes/aquaHeaderIcon.gif b/WebContent/themes/playground/table-prototypes/aquaHeaderIcon.gif
new file mode 100644
index 0000000000..4661312080
--- /dev/null
+++ b/WebContent/themes/playground/table-prototypes/aquaHeaderIcon.gif
Binary files differ
diff --git a/WebContent/themes/playground/table-prototypes/table-proto-firefox.html b/WebContent/themes/playground/table-prototypes/table-proto-firefox.html
new file mode 100644
index 0000000000..9e01f4f703
--- /dev/null
+++ b/WebContent/themes/playground/table-prototypes/table-proto-firefox.html
@@ -0,0 +1,88 @@
+<html>
+ <head>
+ <title>Table concept prototype</title>
+ <style>
+ .header {
+ color:white;
+ padding-left:2px;
+ padding-bottom:2px;
+ border:1px solid #458cee;
+ background: transparent url(aquaHeaderIcon.gif) 0 -5px repeat-x;
+ }
+
+ div.table {
+ border: 1px solid silver;
+ width: 515px;
+ }
+
+ #scroller {
+ width: 15px;
+ float: right;
+ margin-top: 15px;
+ height: 315px;
+ overflow: -moz-scrollbars-vertical;
+ overflow-y: auto;
+ overflow-x: hidden;
+ }
+
+ div.horiz-scroller {
+ width: 500px;
+ height: 345px; '
+ overflow: -moz-scrollbars-horizontal;
+ overflow-y: hidden;
+ overflow-x: auto;
+ }
+
+ #tbody {
+ overflow: hidden;
+ height: 312px;
+ }
+
+ div.table td {
+ font: 11px "Lucida Grande",LucidaGrande,verdana,sans-serif;
+ }
+
+ div.table tbody td {
+ border-bottom: 1px solid #eee;
+ }
+
+ div.table tbody td.unknown {
+ background-color: #eee;
+ }
+ </style>
+ </head>
+ <body>
+ <script lang="JavaScript">
+ cols = 19;
+ rows = 100;
+ function scr() {
+ var t = document.getElementById("tbody");
+ var s = document.getElementById("scroller");
+ t.scrollTop = s.scrollTop;
+ }
+ </script>
+
+ <div class="table">
+ <div id="scroller" onscroll="scr()"><div style="height: 5000px; width: 1px;"> </div></div>
+ <div class="horiz-scroller">
+ <TABLE border="0" cellspacing="0" style="width: 1000px;">
+ <THEAD>
+ <tr class="header"><script>for (var i=0; cols > i; i++) document.write("<td>Col " + (1+i) + "</td>");</script></th>
+ </THEAD>
+ <TBODY id="tbody">
+ <script>
+ document.write('<tr><td class="unknown" colspan="'+cols+'" height="1000"> </td></tr>');
+ for (var j=0; rows > j; j++) {
+ document.write("<tr>");
+ for (var i=0; cols > i; i++) document.write("<td>" + (1+i) + "," + (1+j) + "</td>");
+ document.write("</tr>");
+ }
+ document.write('<tr><td class="unknown" colspan="'+cols+'" height="2000"> </td></tr>');
+ </script>
+ </TBODY>
+ </TABLE>
+ </div>
+ </div>
+
+ </body>
+</html> \ No newline at end of file
diff --git a/WebContent/themes/playground/table-prototypes/table-proto-ie.html b/WebContent/themes/playground/table-prototypes/table-proto-ie.html
new file mode 100644
index 0000000000..ee4e0f6755
--- /dev/null
+++ b/WebContent/themes/playground/table-prototypes/table-proto-ie.html
@@ -0,0 +1,40 @@
+<html>
+ <head>
+ <title>Table concept prototype</title>
+ </head>
+ <body>
+ <script lang="JavaScript">
+ cols = 10;
+ rows = 50;
+ function scr() {
+ var t = document.getElementById("inner");
+ var h = document.getElementById("header");
+ var s = document.getElementById("scroller");
+ t.scrollTop = s.scrollTop;
+ h.style.top = "" + s.scrollTop + "px";
+ }
+ </script>
+
+ <div id="outer" style="border: 2px outset #8080A0; width: 522px;">
+ <div id="scroller" onscroll="scr()"
+ style="width: 15px; float: right; margin-top: 22px; height: 308px; overflow: -moz-scrollbars-vertical; overflow-y: auto; overflow-x: hidden;">
+ <div style="height: 5000px; width: 1px;"> </div>
+ </div>
+ <div style="width: 500px; height: 345px; overflow-x: auto; overflow-y: hidden; " id="inner">
+ <TABLE border="1" style="width: 1000px;">
+ <tr id="header" style="position: relative; background-color: white; z-index: 10;"><script>for (var i=0; cols > i; i++) document.write("<th>Col " + (1+i) + "</th>");</script></th>
+ <script>
+ document.write('<tr><td colspan="'+cols+'" height="1000"> </td></tr>');
+ for (var j=0; rows > j; j++) {
+ document.write("<tr>");
+ for (var i=0; cols > i; i++) document.write("<td>" + (1+i) + "," + (1+j) + "</td>");
+ document.write("</tr>");
+ }
+ document.write('<tr><td colspan="'+cols+'" height="1000"> </td></tr>');
+ </script>
+ </TABLE>
+ </div>
+ </div>
+
+ </body>
+</html> \ No newline at end of file
diff --git a/WebContent/themes/playground/table-prototypes/table-proto-safari.html b/WebContent/themes/playground/table-prototypes/table-proto-safari.html
new file mode 100644
index 0000000000..0514d5f261
--- /dev/null
+++ b/WebContent/themes/playground/table-prototypes/table-proto-safari.html
@@ -0,0 +1,69 @@
+<html>
+ <head>
+ <title>Table concept prototype</title>
+ <style>
+ .header {
+ color:white;
+ padding-left:2px;
+ padding-bottom:2px;
+ border:1px solid #458cee;
+ background: transparent url(aquaHeaderIcon.gif) 0 -5px repeat-x;
+ }
+
+ #header {
+ position: relative;
+ }
+
+ div.table {
+ border: 1px solid silver;
+ width: 515px;
+ height: 315px;
+ overflow: auto;
+ }
+
+ div.table td {
+ font: 11px "Lucida Grande",LucidaGrande,verdana,sans-serif;
+ }
+
+ div.table tbody td {
+ border-bottom: 1px solid #eee;
+ }
+
+ div.table tbody td.unknown {
+ background-color: #eee;
+ }
+
+ </style>
+ </head>
+ <body>
+ <script lang="JavaScript">
+ cols = 19;
+ rows = 100;
+ function scr() {
+ var t = document.getElementById("tbody");
+ var h = document.getElementById("header");
+ h.style.top = "" + t.scrollTop + "px";
+ }
+ </script>
+
+ <div id="tbody" class="table" onscroll="scr()">
+ <TABLE border="0" cellspacing="0" style="width: 1000px;" id="header">
+ <tr class="header" ><script>for (var i=0; cols > i; i++) document.write("<td>Col " + (1+i) + "</td>");</script></tr>
+ </TABLE>
+ <TABLE border="0" cellspacing="0" style="width: 1000px;">
+ <script>
+ document.write('<tr><td class="unknown" colspan="'+cols+'" height="1000"> </td></tr>');
+ for (var j=0; rows > j; j++) {
+ document.write("<tr>");
+ for (var i=0; cols > i; i++) document.write("<td>" + (1+i) + "," + (1+j) + "</td>");
+ document.write("</tr>");
+ }
+ document.write('<tr><td class="unknown" colspan="'+cols+'" height="2000"> </td></tr>');
+ </script>
+ </TABLE>
+ </div>
+
+ <!-- Add script to match header widths to table column widths !!!! -->
+
+ </body>
+</html> \ No newline at end of file