]> git.argeo.org Git - gpl/argeo-slc.git/blobdiff - server/org.argeo.slc.ria/src/argeo-ria-lib/slc/class/org/argeo/slc/ria/execution/SpecEditor.js
Move to src
[gpl/argeo-slc.git] / server / org.argeo.slc.ria / src / argeo-ria-lib / slc / class / org / argeo / slc / ria / execution / SpecEditor.js
diff --git a/server/org.argeo.slc.ria/src/argeo-ria-lib/slc/class/org/argeo/slc/ria/execution/SpecEditor.js b/server/org.argeo.slc.ria/src/argeo-ria-lib/slc/class/org/argeo/slc/ria/execution/SpecEditor.js
new file mode 100644 (file)
index 0000000..6d86839
--- /dev/null
@@ -0,0 +1,254 @@
+/**\r
+ * Generic modal popup window.\r
+ * It is layed out with a dock layout. When adding components to it, they are added as "center".\r
+ * @author Charles du Jeu\r
+ */\r
+qx.Class.define("org.argeo.slc.ria.execution.SpecEditor",\r
+{\r
+       extend : qx.ui.window.Window,\r
+  \r
+       properties : {\r
+               /**\r
+                * The Spec to edit\r
+                */\r
+               batchEntrySpec : {\r
+                       check : "org.argeo.slc.ria.execution.BatchEntrySpec"\r
+               }\r
+       },\r
+       \r
+       events : {\r
+               /**\r
+                * Triggered when the user clicks the "save" button. \r
+                */\r
+               "save" : "qx.event.type.Event",\r
+               /**\r
+                * Triggered when any data is modified\r
+                */\r
+               "modified" : "qx.event.type.Event"\r
+\r
+       },\r
+       /**\r
+        * Opens an editor with the given values. \r
+        * @param batchEntrySpec {org.argeo.slc.ria.execution.BatchEntrySpec} The initial spec to edit\r
+        */\r
+       construct : function(batchEntrySpec){\r
+               var editorLabel = "Edit Specs for "+batchEntrySpec.getLabel();\r
+               this.base(arguments, editorLabel);\r
+               this.set({\r
+                       batchEntrySpec : batchEntrySpec,\r
+                       showMaximize : false,\r
+                       showMinimize : false,\r
+                       width: Math.min(parseInt(qx.bom.Viewport.getWidth()*90/100), 400),\r
+                       height: parseInt(qx.bom.Viewport.getHeight()*60/100)\r
+               });\r
+               this.setLayout(new qx.ui.layout.Dock());\r
+               this.setModal(true);\r
+               this.center();\r
+               this._initFormObject(this.getBatchEntrySpec().getLabel());\r
+               this._addFormHeader(this.formObject, editorLabel);\r
+               this.createFormFromSpec();\r
+               this.addContent(this.formObject.pane);\r
+               this.addOkCancel();\r
+               this.addListener("save", function(e){\r
+                       this.saveFormToSpec();\r
+               }, this);\r
+       },\r
+       \r
+       members : {\r
+               /**\r
+                * Builds the form from the BatchEntrySpec\r
+                */\r
+               createFormFromSpec : function(){\r
+                       var values = this.getBatchEntrySpec().getValues();\r
+                       for(var key in values){\r
+                               var valueObj = values[key];\r
+                               var label = key;\r
+                               var hidden = valueObj.getHidden();\r
+                               var disabled = valueObj.getFrozen();\r
+                               var value = valueObj.getValue();\r
+                               var type = valueObj.getSpecType();\r
+                               var subType = valueObj.getSpecSubType();\r
+                               if(type == "primitive" && !hidden){\r
+                                       this._addFormInputText(this.formObject, key, key, value, disabled, subType);\r
+                               }\r
+                       }\r
+               },\r
+               /**\r
+                * Gather data from the form\r
+                */\r
+               saveFormToSpec : function(){\r
+                       var values = this.getBatchEntrySpec().getValues();\r
+                       for(var key in values){\r
+                               var valueObj = values[key];\r
+                               var hidden = valueObj.getHidden();\r
+                               var disabled = valueObj.getFrozen();\r
+                               if(valueObj.getSpecType() == "primitive"){\r
+                                       if(!hidden && !disabled){\r
+                                               valueObj.setValue(this.formObject.fields[key].getValue());\r
+                                       }\r
+                               }\r
+                       }                       \r
+               },\r
+               \r
+               /**\r
+                * Display a component (panel) in the center of the popup\r
+                * @param panel {qx.ui.core.Widget} A gui component (will be set at width 100%).\r
+                */\r
+               addContent: function(panel){\r
+                       this.add(new qx.ui.container.Scroll(panel), {edge:'center', width:'100%'});\r
+               },\r
+               /**\r
+                * Automatically attach to the application root, then show.\r
+                */\r
+               attachAndShow:function(){\r
+                       org.argeo.ria.components.ViewsManager.getInstance().getApplicationRoot().add(this);                     \r
+                       this.show();\r
+               },\r
+               /**\r
+                * Init a form part : creates a pane, a set of fields, etc.\r
+                * @param label {String} A label\r
+                * @return {Map} The form part.\r
+                */\r
+               _initFormObject : function(label){\r
+                       this.formObject = {};\r
+                       this.formObject.hiddenFields = {};\r
+                       this.formObject.freeFields = [];\r
+                       this.formObject.fields = {};\r
+                       this.formObject.label = label;\r
+                       this.formObject.pane = new qx.ui.container.Composite(new qx.ui.layout.VBox(5));\r
+                       return this.formObject;\r
+               },\r
+                               \r
+               /**\r
+                * Creates a simple label/input form entry.\r
+                * @param formObject {Map} The form part\r
+                * @param fieldName {String} Name\r
+                * @param fieldLabel {String} Label of the field\r
+                * @param defaultValue {String} The default value\r
+                * @param choiceValues {Map} An map of values\r
+                * @param disabled {Boolean} The field is not writable\r
+                * @param subType {String} The type expected (string, integer, etc).\r
+                */\r
+               _addFormInputText : function(formObject, fieldName, fieldLabel, defaultValue, disabled, subType, choiceValues){\r
+                       var labelElement;\r
+                       if(choiceValues){\r
+                               var fieldElement = new qx.ui.form.SelectBox();\r
+                               for(var key in choiceValues){\r
+                                       fieldElement.add(new qx.ui.form.ListItem(choiceValues[key], null, key));\r
+                               }\r
+                               fieldElement.addListener("changeSelected", function(e){this.fireEvent("modified")}, this);\r
+                       }else{\r
+                               var fieldElement = new qx.ui.form.TextField();\r
+                               if(subType == "integer"){\r
+                                       fieldElement.addListener("changeValue", function(e){\r
+                                               var isNum = !isNaN(e.getData() * 1);\r
+                                               if(!isNum){\r
+                                                       alert("Warning, this field only accepts Integers!");\r
+                                               }\r
+                                       }, this);                                       \r
+                               }\r
+                               fieldElement.addListener("input", function(e){this.fireEvent("modified")}, this);                       \r
+                       }\r
+                       if(defaultValue){\r
+                               fieldElement.setValue(defaultValue);\r
+                       }\r
+                       if(fieldName && fieldLabel){\r
+                               labelElement = new qx.ui.basic.Label(fieldLabel);\r
+                               formObject.fields[fieldName] = fieldElement;\r
+                       }else{\r
+                               labelElement = new qx.ui.form.TextField();\r
+                               formObject.freeFields.push({\r
+                                       labelEl:labelElement, \r
+                                       valueEl:fieldElement\r
+                               });\r
+                       }\r
+                       if(disabled) fieldElement.setEnabled(false);\r
+                       this._addFormEntry(formObject, labelElement, fieldElement);\r
+               },\r
+               \r
+               /**\r
+                * Add an header\r
+                * @param formObject {Map} The form part\r
+                * @param content {Mixed} Content to add.\r
+                * @param additionnalButton {Mixed} Any widget to add on the east.\r
+                */\r
+               _addFormHeader : function(formObject, content, additionnalButton){\r
+                       var header = new qx.ui.basic.Label('<big><b>'+content+'</b></big>');\r
+                       header.setRich(true);           \r
+                       if(!additionnalButton){\r
+                               header.setPaddingBottom(10);\r
+                               formObject.pane.add(header);\r
+                       }else{\r
+                               var pane = new qx.ui.container.Composite(new qx.ui.layout.Dock());\r
+                               pane.setPaddingBottom(10);\r
+                               pane.setPaddingRight(10);\r
+                               pane.add(header, {edge:'center'});\r
+                               pane.add(additionnalButton, {edge:'east'});\r
+                               formObject.pane.add(pane);\r
+                       }\r
+               },\r
+               \r
+               /**\r
+                * Adds a label/input like entry in the form.\r
+                * @param formObject {Map} The form part\r
+                * @param labelElement {Object} Either a label or an input \r
+                * @param fieldElement {Object} Any form input.\r
+                */\r
+               _addFormEntry : function(formObject, labelElement, fieldElement){\r
+                       var entryPane = new qx.ui.container.Composite(new qx.ui.layout.HBox(5));\r
+                       labelElement.setWidth(150);\r
+                       labelElement.setTextAlign("right");             \r
+                       entryPane.add(labelElement);\r
+                       entryPane.add(new qx.ui.basic.Label(':'));\r
+                       fieldElement.setWidth(150);\r
+                       entryPane.add(fieldElement);\r
+                       formObject.pane.add(entryPane);\r
+               },\r
+                       \r
+               /**\r
+                * Adds a close button bottom-center aligned to the popup\r
+                */\r
+               addCloseButton : function(){\r
+                       this.closeButton = new qx.ui.form.Button("Close");\r
+                       this.closeButton.addListener("execute", this._closeAndDestroy, this);\r
+                       this.add(this.closeButton, {edge:'south'});                     \r
+               },\r
+               /**\r
+                * Adds two buttons bottom-center aligned (Ok and Cancel). \r
+                * Ok button has no listener by default, Cancel will close and destroy the popup.\r
+                */\r
+               addOkCancel : function(){\r
+                       var buttonPane = new qx.ui.container.Composite(new qx.ui.layout.HBox(5, 'right'));\r
+                       buttonPane.setAlignX("center");\r
+                       this.add(buttonPane, {edge:"south"});\r
+                       this.okButton = new qx.ui.form.Button("Save");\r
+                       this.okButton.setEnabled(false);\r
+                       this.addListener("modified", function(e){\r
+                               this.okButton.setEnabled(true);\r
+                       }, this);\r
+                       this.okButton.addListener("execute", function(e){\r
+                               this.fireEvent("save");\r
+                               this.okButton.setEnabled(false);\r
+                       }, this);\r
+                       this.cancelButton = new qx.ui.form.Button("Close");\r
+                       this.cancelButton.addListener("execute", this._closeAndDestroy, this);\r
+\r
+                       this.saveCloseButton = new qx.ui.form.Button("Save & Close");\r
+                       this.saveCloseButton.addListener("execute", function(e){\r
+                               this.fireEvent("save");\r
+                               this._closeAndDestroy();\r
+                       }, this);\r
+                       \r
+                       buttonPane.add(this.okButton);\r
+                       buttonPane.add(this.cancelButton);\r
+                       buttonPane.add(this.saveCloseButton);\r
+               },\r
+               /**\r
+                * Close this modal window and destroy it.\r
+                */\r
+               _closeAndDestroy : function(){\r
+                       this.hide();\r
+                       this.destroy();                 \r
+               }\r
+       }\r
+});
\ No newline at end of file