--- /dev/null
+qx.Class.define("org.argeo.jcr.ria.views.QueriesView", {\r
+ extend : qx.ui.container.Composite,\r
+ implement : [org.argeo.ria.components.IView], \r
+\r
+ properties : {\r
+ /**\r
+ * The commands definition Map that will be automatically added and wired to the menubar and toolbar.\r
+ * See {@link org.argeo.ria.event.CommandsManager#definitions} for the keys to use for defining commands.\r
+ */\r
+ commands : {\r
+ init : {\r
+ "remove_query" : {\r
+ label : "Remove",\r
+ icon : "org.argeo.slc.ria/media-playback-start.png",\r
+ shortcut : null,\r
+ enabled : true,\r
+ menu : "Queries",\r
+ toolbar : null,\r
+ callback : function(e) {\r
+ var selection = this.tree.getSelection();\r
+ if(!selection.length) return;\r
+ var treeNode = selection[0];\r
+ treeNode.getParent().remove(treeNode);\r
+ },\r
+ selectionChange : function(viewId, selection){\r
+ this.setEnabled(false);\r
+ if(selection && selection.length && !selection[0].getJcrNode){\r
+ this.setEnabled(true);\r
+ }\r
+ }\r
+ } \r
+ }\r
+ },\r
+ viewSelection : {\r
+ nullable:false, \r
+ check:"org.argeo.ria.components.ViewSelection"\r
+ },\r
+ instanceId : {\r
+ init:"queriesView",\r
+ event : "changeInstanceId"\r
+ },\r
+ instanceLabel : {\r
+ init:"Queries",\r
+ event : "changeInstanceLabel"\r
+ },\r
+ dataModel : {\r
+ \r
+ }\r
+ },\r
+ \r
+ construct : function(){\r
+ this.base(arguments);\r
+ },\r
+ \r
+ members : {\r
+ /**\r
+ * The implementation should contain the GUI initialisation.\r
+ * This is the role of the manager to actually add the graphical component to the pane, \r
+ * so it's not necessary to do it here. \r
+ * @param viewPane {org.argeo.ria.components.ViewPane} The pane manager\r
+ * @param data {Mixed} Any object or data passed by the initiator of the view\r
+ * @return {Boolean}\r
+ */\r
+ init : function(viewPane, dataModel){\r
+ this.setViewSelection(new org.argeo.ria.components.ViewSelection(viewPane.getViewId())); \r
+ this.setLayout(new qx.ui.layout.VBox());\r
+ this.setDataModel(dataModel);\r
+ \r
+ this.radio = new qx.ui.form.RadioButtonGroup(new qx.ui.layout.HBox(5));\r
+ var xPath = new qx.ui.form.RadioButton("XPath");\r
+ xPath.setModel("xpath");\r
+ var sql = new qx.ui.form.RadioButton("SQL");\r
+ sql.setModel("sql");\r
+ this.radio.add(xPath);\r
+ this.radio.add(sql);\r
+ \r
+ var topLayout = new qx.ui.container.Composite(new qx.ui.layout.HBox(5));\r
+ topLayout.add(new qx.ui.basic.Label("Query (Ctrl+Enter to submit):"));\r
+ topLayout.add(new qx.ui.core.Spacer(), {flex:1});\r
+ topLayout.add(this.radio);\r
+ topLayout.setPadding(0,2,2,2);\r
+ this.add(topLayout);\r
+ \r
+ this.textarea = new qx.ui.form.TextArea();\r
+ this.textarea.setHeight(60);\r
+ this.textarea.setMarginBottom(5);\r
+ this.add(this.textarea);\r
+ this.textarea.addListener("keypress", function(e){\r
+ if(e.getKeyIdentifier() == "Enter" && e.isCtrlOrCommandPressed()){\r
+ this._submitQuery();\r
+ }\r
+ }, this);\r
+ \r
+ \r
+ var resLabel = new qx.ui.basic.Label("Results");\r
+ resLabel.setPadding(0, 2, 2, 2);\r
+ this.add(resLabel);\r
+ \r
+ this.tree = new qx.ui.tree.Tree(); \r
+ this.add(this.tree, {flex:1});\r
+ },\r
+ /**\r
+ * The implementation should contain the real data loading (i.o. query...)\r
+ * @return {Boolean}\r
+ */\r
+ load : function(){\r
+ var dataModel = this.getDataModel();\r
+ \r
+ this.treeBase = new qx.ui.tree.TreeFolder("Queries");\r
+ this.tree.setRoot(this.treeBase);\r
+ this.tree.setHideRoot(true);\r
+ this.treeBase.setOpen(true);\r
+ \r
+ this.tree.addListener("changeSelection", function(e){\r
+ var sel = this.tree.getSelection();\r
+ var selection = [];\r
+ var viewSelection = this.getViewSelection();\r
+ viewSelection.clear(); \r
+ for(var i=0;i<sel.length;i++){\r
+ if(sel[i].getJcrNode){\r
+ selection.push(sel[i].getJcrNode());\r
+ }\r
+ viewSelection.addNode(sel[i]);\r
+ }\r
+ this.getDataModel().setSelectionWithSource(selection, this);\r
+ }, this);\r
+ dataModel.addListener("changeSelection", function(e){\r
+ if(this.getDataModel().getSelectionSource() == this) return;\r
+ var selection = this.getDataModel().getSelection();\r
+ // Arbitrary : for the moment, external select can only apply\r
+ // to children of the current selection\r
+ var crtSel = this.tree.getSelection();\r
+ if(!crtSel.length || !selection.length) return;\r
+ var crtTreeSel = crtSel[0];\r
+ if(!crtTreeSel.getJcrNode) return;\r
+ if(selection[0].getParent() && crtTreeSel.getJcrNode().getPath() == selection[0].getParent().getPath()){\r
+ crtTreeSel.setOpen(true);\r
+ var crtChildren =crtTreeSel.getChildren(); \r
+ for(var i=0;i<crtChildren.length;i++){\r
+ if(crtChildren[i].getJcrNode().getPath() == selection[0].getPath()){\r
+ this.tree.setSelection([crtChildren[i]]);\r
+ return;\r
+ }\r
+ }\r
+ }else if(crtTreeSel.getParent() && crtTreeSel.getJcrNode().getParent().getPath() == selection[0].getPath()){\r
+ this.tree.setSelection([crtTreeSel.getParent()]);\r
+ }\r
+ \r
+ }, this);\r
+ this.tree.setContextMenu(org.argeo.ria.event.CommandsManager\r
+ .getInstance().createMenuFromIds(["open", "remove_query"]));\r
+ \r
+ },\r
+ \r
+ _submitQuery : function(){\r
+ var query = this.textarea.getValue();\r
+ var language = this.radio.getModelSelection()[0];\r
+ var src = "/org.argeo.slc.webapp/queryJcrNodes.jcr?language="+language+"&statement="+query;\r
+ var conn = new org.argeo.ria.remote.Request(src, "GET", "application/json");\r
+ conn.addListener("completed", function(response){\r
+ var json = response.getContent();\r
+ this._addQueryResult(language, query, json);\r
+ }, this);\r
+ conn.send();\r
+ },\r
+ \r
+ _addQueryResult : function(language, query, results){\r
+ var treeQuery = new qx.ui.tree.TreeFolder((language=="xpath"?"XPath":"SQL") + " query : '"+query+"' ("+results.length+")");\r
+ this.treeBase.add(treeQuery); \r
+ var realRoot = this.getDataModel().getRootNode();\r
+ var provider = realRoot.getNodeProvider();\r
+ for(var i=0;i<results.length;i++){\r
+ var child = new org.argeo.jcr.ria.model.Node(results[i], provider, true);\r
+ child.setPath(results[i]);\r
+ var childTree = new org.argeo.jcr.ria.views.JcrTreeFolder(child);\r
+ treeQuery.add(childTree);\r
+ } \r
+ },\r
+ \r
+ /**\r
+ * Whether this component is already contained in a scroller (return false) or not (return true).\r
+ * @return {Boolean}\r
+ */\r
+ addScroll : function(){\r
+ return false;\r
+ },\r
+ /**\r
+ * Called at destruction time\r
+ * Perform all the clean operations (stopping polling queries, etc.) \r
+ */\r
+ close : function(){\r
+ \r
+ } \r
+ \r
+ }\r
+});
\ No newline at end of file