--- /dev/null
+/**\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