Commit 25cb4f8de732ca0ad1613c21a026e140a561fe64
Exists in
master
and in
95 other branches
Merge branch 'master' of https://gitlab.irap.omp.eu/CDPP/AMDA_IHM
Showing
38 changed files
with
3730 additions
and
2839 deletions
Show diff stats
help/plotHOWTO
1 | <li>1. To plot a parameter <i>drag</i> it from the Parameters tree and <i>drop</i> onto the panel | 1 | <li>1. To plot a parameter <i>drag</i> it from the Parameters tree and <i>drop</i> onto the panel |
2 | -<li>2. <i>Link to MultiPlot</i> replaces the individual plot tab TimeSelector with the common for all plot tabs "MultiTime" Selector | ||
3 | -<li>3. Check <i>Extended Plot Options</i> to get control over all available plot options | 2 | +<li>2. Check <i>Extended Plot Options</i> to get control over all available plot options |
3 | + | ||
4 | 4 | ||
5 | - | ||
6 | \ No newline at end of file | 5 | \ No newline at end of file |
js/app/controllers/InteractiveModule.js
@@ -37,12 +37,15 @@ Ext.define('amdaDesktop.InteractiveModule', { | @@ -37,12 +37,15 @@ Ext.define('amdaDesktop.InteractiveModule', { | ||
37 | /** | 37 | /** |
38 | * Window Creation method of the Module | 38 | * Window Creation method of the Module |
39 | */ | 39 | */ |
40 | - createWindow : function (onShowEvent) { | 40 | + createWindow : function (onShowEvent, onAfterCreateObject) { |
41 | 41 | ||
42 | if (this.linkedNode === null){ | 42 | if (this.linkedNode === null){ |
43 | this.createLinkedNode(); | 43 | this.createLinkedNode(); |
44 | } | 44 | } |
45 | - this.createObject(); | 45 | + this.createObject(); |
46 | + if (onAfterCreateObject) { | ||
47 | + onAfterCreateObject(); | ||
48 | + } | ||
46 | var desktop = this.app.getDesktop(); | 49 | var desktop = this.app.getDesktop(); |
47 | var win = desktop.getWindow(this.id); | 50 | var win = desktop.getWindow(this.id); |
48 | var me = this; | 51 | var me = this; |
js/app/controllers/PlotModule.js
@@ -13,8 +13,8 @@ Ext.define('amdaDesktop.PlotModule', { | @@ -13,8 +13,8 @@ Ext.define('amdaDesktop.PlotModule', { | ||
13 | 13 | ||
14 | requires: [ | 14 | requires: [ |
15 | 'amdaUI.PlotUI', | 15 | 'amdaUI.PlotUI', |
16 | - 'amdaPlotObj.PlotRequestObject', | ||
17 | - 'amdaModel.PlotNode', | 16 | + 'amdaPlotObj.MultiplotRequestObject', |
17 | + 'amdaModel.MultiplotNode', | ||
18 | 'amdaUI.PlotTabResultUI', | 18 | 'amdaUI.PlotTabResultUI', |
19 | 'amdaPlotComp.PlotPreviewUI' | 19 | 'amdaPlotComp.PlotPreviewUI' |
20 | ], | 20 | ], |
@@ -26,7 +26,7 @@ Ext.define('amdaDesktop.PlotModule', { | @@ -26,7 +26,7 @@ Ext.define('amdaDesktop.PlotModule', { | ||
26 | * @cfg {String} data models | 26 | * @cfg {String} data models |
27 | * @required | 27 | * @required |
28 | */ | 28 | */ |
29 | - nodeDataModel : 'amdaModel.PlotNode', | 29 | + nodeDataModel : 'amdaModel.MultiplotNode', |
30 | 30 | ||
31 | /** | 31 | /** |
32 | * @cfg {String} window definitions | 32 | * @cfg {String} window definitions |
@@ -40,173 +40,197 @@ Ext.define('amdaDesktop.PlotModule', { | @@ -40,173 +40,197 @@ Ext.define('amdaDesktop.PlotModule', { | ||
40 | 40 | ||
41 | plotResultWindowsManager : new Ext.AbstractManager(), | 41 | plotResultWindowsManager : new Ext.AbstractManager(), |
42 | 42 | ||
43 | - computeResultWindowSize : function(panelResult) | ||
44 | - { | ||
45 | - var size = panelResult.getImageSize(); | ||
46 | - size.width += 30; | ||
47 | - size.height += 95; | ||
48 | - | ||
49 | - return size; | ||
50 | - }, | 43 | + computeResultWindowSize : function(panelResult) { |
44 | + var size = panelResult.getImageSize(); | ||
45 | + size.width += 30; | ||
46 | + size.height += 95; | ||
47 | + return size; | ||
48 | + }, | ||
51 | 49 | ||
52 | - computePreviewWindowSize : function(previewContent) | ||
53 | - { | ||
54 | - var size = previewContent.getImageSize(); | ||
55 | - size.width += 30; | ||
56 | - size.height += 65; | ||
57 | - | ||
58 | - return size; | ||
59 | - }, | 50 | + computePreviewWindowSize : function(previewContent) { |
51 | + var size = previewContent.getImageSize(); | ||
52 | + size.width += 30; | ||
53 | + size.height += 65; | ||
54 | + return size; | ||
55 | + }, | ||
60 | 56 | ||
61 | updateInteractiveSession : function(session, newplot) { | 57 | updateInteractiveSession : function(session, newplot) { |
62 | - var me = this; | ||
63 | - | ||
64 | - | ||
65 | - | ||
66 | - Ext.each(session.result, function (tabResult, index) { | ||
67 | - if (logExecTime && tabResult.exectime) | ||
68 | - { | ||
69 | - console.log("CMD EXEC TIME FOR "+tabResult.plot+" = "+tabResult.exectime+"ms"); | ||
70 | - } | 58 | + var me = this; |
71 | 59 | ||
72 | - if (tabResult.preview) | ||
73 | - { | ||
74 | - var plotPreviewConfig = { | ||
75 | - folder : session.folder, | ||
76 | - plotFile : tabResult.plot, | ||
77 | - context : tabResult.context, | ||
78 | - tabId : tabResult.id | ||
79 | - }; | ||
80 | - me.updatePreview(plotPreviewConfig); | ||
81 | - return; | ||
82 | - } | ||
83 | - | ||
84 | - var winResultId = tabResult.id+"-win"; | ||
85 | - | ||
86 | - var winResult = me.getWindowResult(winResultId); | ||
87 | - | ||
88 | - var plotTabConfig = { | ||
89 | - folder : session.folder, | ||
90 | - plotFile : tabResult.plot, | ||
91 | - context : tabResult.context, | ||
92 | - tabId : tabResult.id, | ||
93 | - multiplot : tabResult.multiplot, | ||
94 | - isInterval: tabResult.isInterval, | ||
95 | - ttName : tabResult.ttName, | ||
96 | - ttIndex : tabResult.ttIndex, | ||
97 | - ttNbIntervals : tabResult.ttNbIntervals, | ||
98 | - ttFileIndex : tabResult.ttFileIndex | ||
99 | - }; | 60 | + |
61 | + Ext.each(session.result, function (tabResult, index) { | ||
62 | + if (logExecTime && tabResult.exectime) { | ||
63 | + console.log("CMD EXEC TIME FOR "+tabResult.plot+" = "+tabResult.exectime+"ms"); | ||
64 | + } | ||
65 | + | ||
66 | + if (tabResult.preview) { | ||
67 | + var plotPreviewConfig = { | ||
68 | + folder : session.folder, | ||
69 | + plotFile : tabResult.plot, | ||
70 | + context : tabResult.context, | ||
71 | + interactiveId : tabResult.id | ||
72 | + }; | ||
73 | + me.updatePreview(plotPreviewConfig); | ||
74 | + return; | ||
75 | + } | ||
76 | + | ||
77 | + var winResultId = tabResult.id+"-win"; | ||
100 | 78 | ||
101 | - if (winResult == null) { | ||
102 | - | ||
103 | - var x = 50 + tabResult.index * 50; | ||
104 | - var y = 100 + tabResult.index * 20; | ||
105 | - | ||
106 | - //create new result win | ||
107 | - var panelResult = new amdaUI.PlotTabResultUI(plotTabConfig); | 79 | + var winResult = me.getWindowResult(winResultId); |
108 | 80 | ||
109 | - var size = me.computeResultWindowSize(panelResult); | 81 | + var plotTabConfig = { |
82 | + folder : session.folder, | ||
83 | + plotFile : tabResult.plot, | ||
84 | + context : tabResult.context, | ||
85 | + interactiveId : tabResult.id, | ||
86 | + isInterval: tabResult.isInterval, | ||
87 | + ttName : tabResult.ttName, | ||
88 | + ttIndex : tabResult.ttIndex, | ||
89 | + ttNbIntervals : tabResult.ttNbIntervals, | ||
90 | + ttFileIndex : tabResult.ttFileIndex | ||
91 | + }; | ||
110 | 92 | ||
111 | - var win = myDesktopApp.getDesktop().createWindow({ | ||
112 | - id : tabResult.id+"-win", | ||
113 | - title : 'Plot '+(tabResult.index+1), | ||
114 | - width : size.width, | ||
115 | - height: size.height, | ||
116 | - x : x, | ||
117 | - y : y, | ||
118 | - layout: 'fit', | ||
119 | - items : [ | ||
120 | - panelResult | ||
121 | - ], | ||
122 | - listeners: { | ||
123 | - scope: me, | ||
124 | - beforeclose: function(win,opt) { | ||
125 | - me.plotResultWindowsManager.unregister(win); | ||
126 | - } | ||
127 | - }, | ||
128 | - getPanelResult: function() { | ||
129 | - return panelResult; | ||
130 | - } | ||
131 | - }); | ||
132 | - win.show(); | ||
133 | - me.plotResultWindowsManager.register(win); | ||
134 | - } | ||
135 | - else | ||
136 | - { | ||
137 | - //update result | ||
138 | - winResult.getPanelResult().updatePlotImage(plotTabConfig, newplot); | ||
139 | - //update window size | ||
140 | - var size = me.computeResultWindowSize(winResult.getPanelResult()); | ||
141 | - winResult.setSize(size.width, size.height); | ||
142 | - | ||
143 | - winResult.toFront(); | ||
144 | - } | ||
145 | - }); | 93 | + if (winResult == null) { |
94 | + var x = 50 + tabResult.index * 50; | ||
95 | + var y = 100 + tabResult.index * 20; | ||
96 | + //create new result win | ||
97 | + var panelResult = new amdaUI.PlotTabResultUI(plotTabConfig); | ||
98 | + | ||
99 | + var size = me.computeResultWindowSize(panelResult); | ||
100 | + | ||
101 | + var win = myDesktopApp.getDesktop().createWindow({ | ||
102 | + id : tabResult.id+"-win", | ||
103 | + title : tabResult.title, | ||
104 | + width : size.width, | ||
105 | + height: size.height, | ||
106 | + x : x, | ||
107 | + y : y, | ||
108 | + layout: 'fit', | ||
109 | + items : [ | ||
110 | + panelResult | ||
111 | + ], | ||
112 | + listeners: { | ||
113 | + scope: me, | ||
114 | + beforeclose: function(win,opt) { | ||
115 | + me.plotResultWindowsManager.unregister(win); | ||
116 | + } | ||
117 | + }, | ||
118 | + getPanelResult: function() { | ||
119 | + return panelResult; | ||
120 | + } | ||
121 | + }); | ||
122 | + win.show(); | ||
123 | + me.plotResultWindowsManager.register(win); | ||
124 | + } | ||
125 | + else { | ||
126 | + //update result | ||
127 | + winResult.getPanelResult().updatePlotImage(plotTabConfig, newplot); | ||
128 | + //update window size | ||
129 | + var size = me.computeResultWindowSize(winResult.getPanelResult()); | ||
130 | + winResult.setTitle(tabResult.title); | ||
131 | + winResult.setSize(size.width, size.height); | ||
132 | + winResult.toFront(); | ||
133 | + } | ||
134 | + }); | ||
146 | }, | 135 | }, |
147 | 136 | ||
148 | closeInteractiveSession : function() { | 137 | closeInteractiveSession : function() { |
149 | - var me = this; | ||
150 | - this.plotResultWindowsManager.each(function (key, value, length) { | ||
151 | - value.close(); | ||
152 | - }); | 138 | + var me = this; |
139 | + this.plotResultWindowsManager.each(function (key, value, length) { | ||
140 | + value.close(); | ||
141 | + }); | ||
153 | }, | 142 | }, |
154 | - | 143 | + |
155 | updatePreview : function(plotPreviewConfig) { | 144 | updatePreview : function(plotPreviewConfig) { |
156 | - var winPreviewId = "plot-preview-win"; | ||
157 | - | ||
158 | - var winPreview = this.getWindowResult(winPreviewId); | ||
159 | - | ||
160 | - if (winPreview == null) { | ||
161 | - //create new preview win | ||
162 | - var previewContent = new amdaPlotComp.PlotPreviewUI(plotPreviewConfig); | ||
163 | - | ||
164 | - var size = this.computePreviewWindowSize(previewContent); | ||
165 | - | ||
166 | - var win = myDesktopApp.getDesktop().createWindow({ | ||
167 | - id : winPreviewId, | ||
168 | - title : 'Plot Preview', | ||
169 | - width : size.width, | ||
170 | - height: size.height, | ||
171 | - layout: 'fit', | ||
172 | - items : [ | ||
173 | - previewContent | ||
174 | - ], | ||
175 | - listeners: { | ||
176 | - scope: this, | ||
177 | - beforeclose: function(win,opt) { | ||
178 | - this.plotResultWindowsManager.unregister(win); | ||
179 | - } | ||
180 | - }, | ||
181 | - getPreviewContent: function() { | ||
182 | - return previewContent; | ||
183 | - } | ||
184 | - }); | ||
185 | - win.show(); | ||
186 | - this.plotResultWindowsManager.register(win); | ||
187 | - } | ||
188 | - else | ||
189 | - { | ||
190 | - //update result | ||
191 | - winPreview.getPreviewContent().updatePlotImage(plotPreviewConfig); | ||
192 | - //update window size | ||
193 | - var size = this.computePreviewWindowSize(winPreview.getPreviewContent()); | ||
194 | - winPreview.setSize(size.width, size.height); | ||
195 | - winPreview.toFront(); | ||
196 | - } | ||
197 | - }, | ||
198 | - | ||
199 | - getInteractiveMultiPlotState : function() { | ||
200 | - var state = {}; | ||
201 | - this.plotResultWindowsManager.each(function (key, value, length) { | ||
202 | - if (value.getPanelResult) | ||
203 | - state[value.getPanelResult().tabId] = value.getPanelResult().getInteractiveMultiPlotState(); | ||
204 | - }); | ||
205 | - return state; | 145 | + var winPreviewId = "plot-preview-win"; |
146 | + | ||
147 | + var winPreview = this.getWindowResult(winPreviewId); | ||
148 | + | ||
149 | + if (winPreview == null) { | ||
150 | + //create new preview win | ||
151 | + var previewContent = new amdaPlotComp.PlotPreviewUI(plotPreviewConfig); | ||
152 | + | ||
153 | + var size = this.computePreviewWindowSize(previewContent); | ||
154 | + | ||
155 | + var win = myDesktopApp.getDesktop().createWindow({ | ||
156 | + id : winPreviewId, | ||
157 | + title : 'Plot Preview', | ||
158 | + width : size.width, | ||
159 | + height: size.height, | ||
160 | + layout: 'fit', | ||
161 | + items : [ | ||
162 | + previewContent | ||
163 | + ], | ||
164 | + listeners: { | ||
165 | + scope: this, | ||
166 | + beforeclose: function(win,opt) { | ||
167 | + this.plotResultWindowsManager.unregister(win); | ||
168 | + } | ||
169 | + }, | ||
170 | + getPreviewContent: function() { | ||
171 | + return previewContent; | ||
172 | + } | ||
173 | + }); | ||
174 | + win.show(); | ||
175 | + this.plotResultWindowsManager.register(win); | ||
176 | + } | ||
177 | + else { | ||
178 | + //update result | ||
179 | + winPreview.getPreviewContent().updatePlotImage(plotPreviewConfig); | ||
180 | + //update window size | ||
181 | + var size = this.computePreviewWindowSize(winPreview.getPreviewContent()); | ||
182 | + winPreview.setSize(size.width, size.height); | ||
183 | + winPreview.toFront(); | ||
184 | + } | ||
206 | }, | 185 | }, |
207 | 186 | ||
208 | getWindowResult: function(winResultId){ | 187 | getWindowResult: function(winResultId){ |
209 | if (!this.plotResultWindowsManager.get(winResultId)) return null; | 188 | if (!this.plotResultWindowsManager.get(winResultId)) return null; |
210 | return this.plotResultWindowsManager.get(winResultId); | 189 | return this.plotResultWindowsManager.get(winResultId); |
190 | + }, | ||
191 | + | ||
192 | + addParameter : function(paramNode) { | ||
193 | + var me = this; | ||
194 | + var desktop = this.app.getDesktop(); | ||
195 | + var win = desktop.getWindow(this.id); | ||
196 | + if (win) { | ||
197 | + me.getUiContent().addParameter(paramNode, false); | ||
198 | + win.show(); | ||
199 | + } | ||
200 | + else { | ||
201 | + this.createWindow(function () { | ||
202 | + me.getUiContent().addParameter(paramNode, true); | ||
203 | + }); | ||
204 | + } | ||
205 | + }, | ||
206 | + | ||
207 | + editPlot : function(plotNode) { | ||
208 | + var me = this; | ||
209 | + var desktop = this.app.getDesktop(); | ||
210 | + var win = desktop.getWindow(this.id); | ||
211 | + if (win) { | ||
212 | + // Plot UI is opened => add plot in a new tab | ||
213 | + me.getUiContent().editPlot(plotNode); | ||
214 | + win.show(); | ||
215 | + } | ||
216 | + else { | ||
217 | + // Plot UI is closed | ||
218 | + this.createWindow(null, function() { | ||
219 | + //This is the onAfterCreateObject callback | ||
220 | + //Add plot node to the multiplot object | ||
221 | + me.linkedNode.get('object').plots().removeAll(); | ||
222 | + me.linkedNode.get('object').plots().add(plotNode); | ||
223 | + }); | ||
224 | + } | ||
225 | + }, | ||
226 | + | ||
227 | + syncAfterRename: function(renamedNode) { | ||
228 | + var me = this; | ||
229 | + var desktop = this.app.getDesktop(); | ||
230 | + var win = desktop.getWindow(this.id); | ||
231 | + if (win) { | ||
232 | + me.getUiContent().updateTabs(); | ||
233 | + me.getUiContent().updateRequestName(renamedNode); | ||
234 | + } | ||
211 | } | 235 | } |
212 | }); | 236 | }); |
js/app/models/AmdaNode.js
@@ -128,20 +128,7 @@ Ext.define('amdaModel.AmdaNode', { | @@ -128,20 +128,7 @@ Ext.define('amdaModel.AmdaNode', { | ||
128 | } | 128 | } |
129 | // if this node is a leaf and have no child | 129 | // if this node is a leaf and have no child |
130 | else if (this.isLeaf() || this.get('nodeType' ) == 'derivedParam' ) { | 130 | else if (this.isLeaf() || this.get('nodeType' ) == 'derivedParam' ) { |
131 | - if (this.get('nodeType') == 'plottab') { | ||
132 | - itemKind = amdaUI.ExplorerUI.ITEM_KIND_PTAB; | ||
133 | - } | ||
134 | - else { | ||
135 | - itemKind = amdaUI.ExplorerUI.ITEM_KIND_LEAF; | ||
136 | - } | ||
137 | - } | ||
138 | - else if (this.get('nodeType') == 'request') { | ||
139 | - if (this.get('tabs') && (this.get('tabs').length > 0)) { | ||
140 | - itemKind = amdaUI.ExplorerUI.ITEM_KIND_LEAF; | ||
141 | - } | ||
142 | - else { | ||
143 | - itemKind = amdaUI.ExplorerUI.ITEM_KIND_DIRE; | ||
144 | - } | 131 | + itemKind = amdaUI.ExplorerUI.ITEM_KIND_LEAF; |
145 | } | 132 | } |
146 | else if (this.get('isParameter') && this.get('nodeType' ) != 'derivedParam' ) { | 133 | else if (this.get('isParameter') && this.get('nodeType' ) != 'derivedParam' ) { |
147 | itemKind = amdaUI.ExplorerUI.ITEM_KIND_PARA; | 134 | itemKind = amdaUI.ExplorerUI.ITEM_KIND_PARA; |
js/app/models/AmdaTimeObject.js
@@ -7,11 +7,7 @@ | @@ -7,11 +7,7 @@ | ||
7 | * | 7 | * |
8 | * @author elena | 8 | * @author elena |
9 | * @version $Id: AmdaTimeObject.js 1534 2013-05-24 13:30:26Z myriam $ | 9 | * @version $Id: AmdaTimeObject.js 1534 2013-05-24 13:30:26Z myriam $ |
10 | - * @todo Validations | ||
11 | - ****************************************************************************** | ||
12 | - * FT Id : Date : Name - Description | ||
13 | - ****************************************************************************** | ||
14 | - * : :07/07/2011: elena โ creation | 10 | + * @todo Validations |
15 | */ | 11 | */ |
16 | 12 | ||
17 | 13 | ||
@@ -26,66 +22,70 @@ Ext.define('amdaModel.TTobject', { | @@ -26,66 +22,70 @@ Ext.define('amdaModel.TTobject', { | ||
26 | } | 22 | } |
27 | }); | 23 | }); |
28 | 24 | ||
29 | - | ||
30 | Ext.define('amdaModel.AmdaTimeObject', { | 25 | Ext.define('amdaModel.AmdaTimeObject', { |
31 | extend: 'amdaModel.AmdaObject', | 26 | extend: 'amdaModel.AmdaObject', |
32 | statics:{ | 27 | statics:{ |
33 | inputTimeSrc: ['TimeTable','Interval','Catalog'] | 28 | inputTimeSrc: ['TimeTable','Interval','Catalog'] |
34 | - }, | 29 | + }, |
35 | fields : [ | 30 | fields : [ |
36 | - { name: 'resultId', type: 'string'}, | ||
37 | - { name: 'folderId', type: 'string'}, | ||
38 | - { name: 'processId', type: 'string'}, | ||
39 | - { name: 'timesrc', type: 'string'/*, defaultValue: amdaModel.AmdaTimeObject.inputTimeSrc[1] /*'Interval'*/ }, | ||
40 | - { name: 'startDate', type: 'date', defaultValue:Ext.Date.add(Ext.Date.clearTime(new Date()),Ext.Date.DAY,-1), | ||
41 | - convert: function(value,rec) { | ||
42 | - if (!Ext.isDate(value)) { | ||
43 | - var valueString = new String(value); | ||
44 | - var date = new Date(valueString.replace(/\-/g,'\/').replace(/[T|Z]/g,' ')); | ||
45 | - return date; | ||
46 | - } | ||
47 | - return value; | ||
48 | - } | ||
49 | - }, | ||
50 | - { name: 'stopDate', type: 'date', defaultValue: Ext.Date.clearTime (new Date()), persist: false, | ||
51 | - convert: function(value,rec) { | ||
52 | - if (!Ext.isDate(value)){ | ||
53 | - var valueString = new String(value); | ||
54 | - var date = new Date(valueString.replace(/\-/g,'\/').replace(/[T|Z]/g,' ')); | ||
55 | - return date; | ||
56 | - } | ||
57 | - return value; | ||
58 | - } | ||
59 | - | ||
60 | - }, | ||
61 | - { | ||
62 | - name: 'durationDay', type: 'int', | ||
63 | - convert: function(value, rec) { | ||
64 | - return Ext.String.leftPad(Math.floor((rec.get('stopDate') - rec.get('startDate'))/86400000),4,'0'); | ||
65 | - } | ||
66 | - }, | ||
67 | - { | ||
68 | - name: 'durationHour', type: 'int', | ||
69 | - convert: function(value, rec) { | ||
70 | - var diffH = (rec.get('stopDate') - rec.get('startDate'))/3600000 % 24; | ||
71 | - return Ext.String.leftPad(Math.floor(diffH), 2, '0'); | ||
72 | - } | ||
73 | - }, | ||
74 | - { | ||
75 | - name: 'durationMin', type: 'int', | ||
76 | - convert: function(value, rec) { | ||
77 | - var diffM = (rec.get('stopDate') - rec.get('startDate'))/60000 % 60; | ||
78 | - return Ext.String.leftPad(Math.floor(diffM), 2, '0'); | ||
79 | - } | ||
80 | - }, | ||
81 | - { | ||
82 | - name: 'durationSec', type: 'int', | ||
83 | - convert: function(value, rec) { | ||
84 | - var diffS = (rec.get('stopDate') - rec.get('startDate'))/1000 % 60; | ||
85 | - return Ext.String.leftPad(Math.floor(diffS), 2, '0'); | ||
86 | - } | ||
87 | - }, | ||
88 | - { name: 'timeTables', defaultValue: null } // array of TTobject | ||
89 | - ] | ||
90 | - | 31 | + { name: 'resultId', type: 'string'}, |
32 | + { name: 'folderId', type: 'string'}, | ||
33 | + { name: 'processId', type: 'string'}, | ||
34 | + { name: 'timesrc', type: 'string'/*, defaultValue: amdaModel.AmdaTimeObject.inputTimeSrc[1] /*'Interval'*/ }, | ||
35 | + { name: 'startDate', type: 'date', defaultValue:Ext.Date.add(Ext.Date.clearTime(new Date()),Ext.Date.DAY,-1), | ||
36 | + convert: function(value,rec) { | ||
37 | + if (!Ext.isDate(value)) { | ||
38 | + var valueString = new String(value); | ||
39 | + var date = new Date(valueString.replace(/\-/g,'\/').replace(/[T|Z]/g,' ')); | ||
40 | + return date; | ||
41 | + } | ||
42 | + return value; | ||
43 | + } | ||
44 | + }, | ||
45 | + { | ||
46 | + name: 'stopDate', type: 'date', defaultValue: Ext.Date.clearTime (new Date()), persist: false, | ||
47 | + convert: function(value,rec) { | ||
48 | + if (!Ext.isDate(value)){ | ||
49 | + var valueString = new String(value); | ||
50 | + var date = new Date(valueString.replace(/\-/g,'\/').replace(/[T|Z]/g,' ')); | ||
51 | + return date; | ||
52 | + } | ||
53 | + return value; | ||
54 | + } | ||
55 | + }, | ||
56 | + { | ||
57 | + name: 'durationDay', type: 'int', | ||
58 | + convert: function(value, rec) { | ||
59 | + var zoneOffset = rec.get('stopDate').getTimezoneOffset() - rec.get('startDate').getTimezoneOffset(); | ||
60 | + | ||
61 | + return Ext.String.leftPad(Math.floor((rec.get('stopDate') - rec.get('startDate') - zoneOffset*60000)/86400000),4,'0'); | ||
62 | + } | ||
63 | + }, | ||
64 | + { | ||
65 | + name: 'durationHour', type: 'int', | ||
66 | + convert: function(value, rec) { | ||
67 | + var zoneOffset = rec.get('stopDate').getTimezoneOffset() - rec.get('startDate').getTimezoneOffset(); | ||
68 | + var diffH = (rec.get('stopDate') - rec.get('startDate') - zoneOffset*60000)/3600000 % 24; | ||
69 | + | ||
70 | + return Ext.String.leftPad(Math.floor(diffH), 2, '0'); | ||
71 | + } | ||
72 | + }, | ||
73 | + { | ||
74 | + name: 'durationMin', type: 'int', | ||
75 | + convert: function(value, rec) { | ||
76 | + var diffM = (rec.get('stopDate') - rec.get('startDate'))/60000 % 60; | ||
77 | + | ||
78 | + return Ext.String.leftPad(Math.floor(diffM), 2, '0'); | ||
79 | + } | ||
80 | + }, | ||
81 | + { | ||
82 | + name: 'durationSec', type: 'int', | ||
83 | + convert: function(value, rec) { | ||
84 | + var diffS = (rec.get('stopDate') - rec.get('startDate'))/1000 % 60; | ||
85 | + | ||
86 | + return Ext.String.leftPad(Math.floor(diffS), 2, '0'); | ||
87 | + } | ||
88 | + }, | ||
89 | + { name: 'timeTables', defaultValue: null } // array of TTobject | ||
90 | + ] | ||
91 | }); | 91 | }); |
js/app/models/BkgJobNode.js
@@ -10,9 +10,6 @@ | @@ -10,9 +10,6 @@ | ||
10 | 10 | ||
11 | Ext.define('amdaModel.BkgJobNode', { | 11 | Ext.define('amdaModel.BkgJobNode', { |
12 | extend: 'amdaModel.ExecutableNode', | 12 | extend: 'amdaModel.ExecutableNode', |
13 | - requires: [ | ||
14 | - 'amdaPlotObj.PlotRequestObject' | ||
15 | - ], | ||
16 | action : null, | 13 | action : null, |
17 | 14 | ||
18 | statics: { | 15 | statics: { |
js/app/models/DownloadNode.js
@@ -62,90 +62,74 @@ Ext.define('amdaModel.DownloadNode', { | @@ -62,90 +62,74 @@ Ext.define('amdaModel.DownloadNode', { | ||
62 | }); | 62 | }); |
63 | }, | 63 | }, |
64 | 64 | ||
65 | - decodeObject: function(obj) { | ||
66 | - var myValues = new Object(); | ||
67 | - myValues.list=[]; | ||
68 | - | ||
69 | - if (!obj) { | ||
70 | - var fullObject = this.get('realLinkedNode').get('object'); | ||
71 | - } | ||
72 | - else { | ||
73 | - var fullObject = obj; | ||
74 | - } | ||
75 | - | ||
76 | - var i = 0; | ||
77 | - fullObject.tabs().each(function (tab) { | ||
78 | - // only active tab | ||
79 | - if (tab.get('id') == fullObject.get('last-plotted-tab')) | ||
80 | - { | ||
81 | - tab.panels().each(function (panel) { | ||
82 | - panel.params().each(function (param) { | ||
83 | - var myParam = new Object(); | ||
84 | - myParam.paramid = param.get('paramid'); | ||
85 | - myParam.type = param.get('type'); | ||
86 | - myParam['dim1-index'] = param.get('dim1-index'); | ||
87 | - myParam['dim1-sum-type'] = param.get('dim1-sum-type'); | ||
88 | - myParam['dim1-min-value'] = param.get('dim1-min-value'); | ||
89 | - myParam['dim1-max-value'] = param.get('dim1-max-value'); | ||
90 | - myParam['dim1-min-index'] = param.get('dim1-min-index'); | ||
91 | - myParam['dim1-max-index'] = param.get('dim1-max-index'); | ||
92 | - myParam['dim2-index'] = param.get('dim2-index'); | ||
93 | - myParam['dim2-sum-type'] = param.get('dim2-sum-type'); | ||
94 | - myParam['dim2-min-value'] = param.get('dim2-min-value'); | ||
95 | - myParam['dim2-max-value'] = param.get('dim2-max-value'); | ||
96 | - myParam['dim2-min-index'] = param.get('dim2-min-index'); | ||
97 | - myParam['dim2-max-index'] = param.get('dim2-max-index'); | ||
98 | - myParam.template_args = param.get('template_args'); | ||
99 | - if (!param.get('plotonly')) { | ||
100 | - myValues.list[i] = myParam; | ||
101 | - ++i; | ||
102 | - } | ||
103 | - else | ||
104 | - alert('Parameter '+ myParam.paramid + ' is PlotOnly'); | ||
105 | - }); | ||
106 | - }); | ||
107 | - if (tab.get('multi-plot-linked')) | ||
108 | - { | ||
109 | - var object = fullObject.data; | ||
110 | - } | ||
111 | - else | ||
112 | - { | ||
113 | - var object = tab.data; | ||
114 | - } | ||
115 | - myValues.timesrc = object.timesrc; | ||
116 | - // if there's at least one timeTable name into 'timeTables' collection | ||
117 | - if (myValues.timesrc == amdaModel.AmdaTimeObject.inputTimeSrc[0] | ||
118 | - && object.timeTables | ||
119 | - && object.timeTables.length ){ | ||
120 | - // get complete timeTables collection | ||
121 | - var timeTables = object.timeTables; | ||
122 | - // init an empty array for timeTables | ||
123 | - myValues.timeTables=[]; | ||
124 | - // for each interval record | ||
125 | - Ext.Array.each(timeTables, function(item, index, all){ | ||
126 | - if (!item.$className) { | ||
127 | - myValues.timeTables[index] = {timeTableName : item.timeTableName, id : item.id}; | ||
128 | - } | ||
129 | - // get Json simplified value | ||
130 | - else { | ||
131 | - myValues.timeTables[index] = item.getJsonValues(); | ||
132 | - } | ||
133 | - }); | ||
134 | - } | ||
135 | - else { | ||
136 | - myValues.startDate = object.startDate; | ||
137 | - myValues.stopDate = object.stopDate; | ||
138 | - myValues.durationDay = object.durationDay; | ||
139 | - myValues.durationHour = object.durationHour; | ||
140 | - myValues.durationMin = object.durationMin; | ||
141 | - myValues.durationSec = object.durationSec; | ||
142 | - } | ||
143 | - } | ||
144 | - }); | ||
145 | - | ||
146 | - myValues.name = fullObject.get('name'); | ||
147 | - return myValues; | ||
148 | - }, | 65 | + decodeObject: function(obj) { |
66 | + var myValues = new Object(); | ||
67 | + myValues.list=[]; | ||
68 | + | ||
69 | + if (!obj) { | ||
70 | + var fullObject = this.get('realLinkedNode').get('object'); | ||
71 | + } | ||
72 | + else { | ||
73 | + var fullObject = obj; | ||
74 | + } | ||
75 | + | ||
76 | + fullObject.panels().each(function (panel) { | ||
77 | + panel.params().each(function (param) { | ||
78 | + var myParam = new Object(); | ||
79 | + myParam.paramid = param.get('paramid'); | ||
80 | + myParam.type = param.get('type'); | ||
81 | + myParam['dim1-index'] = param.get('dim1-index'); | ||
82 | + myParam['dim1-sum-type'] = param.get('dim1-sum-type'); | ||
83 | + myParam['dim1-min-value'] = param.get('dim1-min-value'); | ||
84 | + myParam['dim1-max-value'] = param.get('dim1-max-value'); | ||
85 | + myParam['dim1-min-index'] = param.get('dim1-min-index'); | ||
86 | + myParam['dim1-max-index'] = param.get('dim1-max-index'); | ||
87 | + myParam['dim2-index'] = param.get('dim2-index'); | ||
88 | + myParam['dim2-sum-type'] = param.get('dim2-sum-type'); | ||
89 | + myParam['dim2-min-value'] = param.get('dim2-min-value'); | ||
90 | + myParam['dim2-max-value'] = param.get('dim2-max-value'); | ||
91 | + myParam['dim2-min-index'] = param.get('dim2-min-index'); | ||
92 | + myParam['dim2-max-index'] = param.get('dim2-max-index'); | ||
93 | + myParam.template_args = param.get('template_args'); | ||
94 | + if (!param.get('plotonly')) { | ||
95 | + myValues.list.push(myParam); | ||
96 | + } | ||
97 | + else | ||
98 | + alert('Parameter '+ myParam.paramid + ' is PlotOnly'); | ||
99 | + }); | ||
100 | + }); | ||
101 | + myValues.timesrc = fullObject.get('timesrc'); | ||
102 | + // if there's at least one timeTable name into 'timeTables' collection | ||
103 | + if (myValues.timesrc == amdaModel.AmdaTimeObject.inputTimeSrc[0] | ||
104 | + && fullObject.get('timeTables') | ||
105 | + && fullObject.get('timeTables').length){ | ||
106 | + // get complete timeTables collection | ||
107 | + var timeTables = fullObject.get('timeTables'); | ||
108 | + // init an empty array for timeTables | ||
109 | + myValues.timeTables=[]; | ||
110 | + // for each interval record | ||
111 | + Ext.Array.each(timeTables, function(item, index, all){ | ||
112 | + if (!item.$className) { | ||
113 | + myValues.timeTables[index] = {timeTableName : item.timeTableName, id : item.id}; | ||
114 | + } | ||
115 | + // get Json simplified value | ||
116 | + else { | ||
117 | + myValues.timeTables[index] = item.getJsonValues(); | ||
118 | + } | ||
119 | + }); | ||
120 | + } | ||
121 | + else { | ||
122 | + myValues.startDate = fullObject.get('startDate'); | ||
123 | + myValues.stopDate = fullObject.get('stopDate'); | ||
124 | + myValues.durationDay = fullObject.get('durationDay'); | ||
125 | + myValues.durationHour = fullObject.get('durationHour'); | ||
126 | + myValues.durationMin = fullObject.get('durationMin'); | ||
127 | + myValues.durationSec = fullObject.get('durationSec'); | ||
128 | + } | ||
129 | + | ||
130 | + myValues.name = fullObject.get('name'); | ||
131 | + return myValues; | ||
132 | + }, | ||
149 | 133 | ||
150 | encodeObject: function() { | 134 | encodeObject: function() { |
151 | }, | 135 | }, |
js/app/models/InteractiveNode.js
@@ -11,10 +11,6 @@ | @@ -11,10 +11,6 @@ | ||
11 | Ext.define('amdaModel.InteractiveNode', { | 11 | Ext.define('amdaModel.InteractiveNode', { |
12 | extend: 'amdaModel.AmdaNode', | 12 | extend: 'amdaModel.AmdaNode', |
13 | 13 | ||
14 | - requires: [ | ||
15 | - 'amdaPlotObj.PlotRequestObject' | ||
16 | - ], | ||
17 | - | ||
18 | fields: [ | 14 | fields: [ |
19 | {name: 'contextNode', type: 'amdaModel.AmdaNode', persist: false}, | 15 | {name: 'contextNode', type: 'amdaModel.AmdaNode', persist: false}, |
20 | {name: 'objectDataModel', type: 'string', persist: false}, | 16 | {name: 'objectDataModel', type: 'string', persist: false}, |
@@ -52,7 +48,7 @@ Ext.define('amdaModel.InteractiveNode', { | @@ -52,7 +48,7 @@ Ext.define('amdaModel.InteractiveNode', { | ||
52 | { | 48 | { |
53 | node.eachChild(function(n) | 49 | node.eachChild(function(n) |
54 | { | 50 | { |
55 | - if (!n.isLoaded() && !n.isRealLeaf()) | 51 | + if (!n.isLoaded() && !n.isLeaf()) |
56 | { | 52 | { |
57 | nodesToLoad.push(n); | 53 | nodesToLoad.push(n); |
58 | me.preloadTreeNode(n,nodesToLoad,onloaded); | 54 | me.preloadTreeNode(n,nodesToLoad,onloaded); |
@@ -70,7 +66,7 @@ Ext.define('amdaModel.InteractiveNode', { | @@ -70,7 +66,7 @@ Ext.define('amdaModel.InteractiveNode', { | ||
70 | { | 66 | { |
71 | records.forEach(function (record) | 67 | records.forEach(function (record) |
72 | { | 68 | { |
73 | - if (!record.isLoaded() && !record.isRealLeaf()) | 69 | + if (!record.isLoaded() && !record.isLeaf()) |
74 | { | 70 | { |
75 | nodesToLoad.push(record); | 71 | nodesToLoad.push(record); |
76 | me.preloadTreeNode(record,nodesToLoad,onloaded); | 72 | me.preloadTreeNode(record,nodesToLoad,onloaded); |
@@ -100,11 +96,6 @@ Ext.define('amdaModel.InteractiveNode', { | @@ -100,11 +96,6 @@ Ext.define('amdaModel.InteractiveNode', { | ||
100 | } | 96 | } |
101 | }, | 97 | }, |
102 | 98 | ||
103 | - isRealLeaf: function() | ||
104 | - { | ||
105 | - return this.isLeaf(); | ||
106 | - }, | ||
107 | - | ||
108 | /** | 99 | /** |
109 | * this method is overriden into ExecutableNode to return true | 100 | * this method is overriden into ExecutableNode to return true |
110 | */ | 101 | */ |
@@ -151,7 +142,7 @@ Ext.define('amdaModel.InteractiveNode', { | @@ -151,7 +142,7 @@ Ext.define('amdaModel.InteractiveNode', { | ||
151 | */ | 142 | */ |
152 | rename: function(value,callBackFn) | 143 | rename: function(value,callBackFn) |
153 | { | 144 | { |
154 | - var dataToSend = {id : this.get('id'), old_name: this.modified.text, name: value, parent : this.data.parentId, leaf: this.isRealLeaf(), nodeType: this.get('nodeType')}; | 145 | + var dataToSend = {id : this.get('id'), old_name: this.modified.text, name: value, parent : this.data.parentId, leaf: this.isLeaf(), nodeType: this.get('nodeType')}; |
155 | AmdaAction.renameObject(dataToSend, callBackFn); | 146 | AmdaAction.renameObject(dataToSend, callBackFn); |
156 | }, | 147 | }, |
157 | 148 | ||
@@ -160,7 +151,7 @@ Ext.define('amdaModel.InteractiveNode', { | @@ -160,7 +151,7 @@ Ext.define('amdaModel.InteractiveNode', { | ||
160 | */ | 151 | */ |
161 | renameDD: function(parentId, callBackFn) | 152 | renameDD: function(parentId, callBackFn) |
162 | { | 153 | { |
163 | - var dataToSend = {id : this.get('id'), old_name: this.get('name'), name: this.get('name'), parent : parentId, leaf: this.isRealLeaf(), nodeType: this.get('nodeType')}; | 154 | + var dataToSend = {id : this.get('id'), old_name: this.get('name'), name: this.get('name'), parent : parentId, leaf: this.isLeaf(), nodeType: this.get('nodeType')}; |
164 | AmdaAction.renameObject(dataToSend, callBackFn); | 155 | AmdaAction.renameObject(dataToSend, callBackFn); |
165 | }, | 156 | }, |
166 | 157 | ||
@@ -171,7 +162,7 @@ Ext.define('amdaModel.InteractiveNode', { | @@ -171,7 +162,7 @@ Ext.define('amdaModel.InteractiveNode', { | ||
171 | */ | 162 | */ |
172 | isValidName : function(name, callBackFn) | 163 | isValidName : function(name, callBackFn) |
173 | { | 164 | { |
174 | - var dataToSend = {name: name, nodeType: this.get('nodeType'), leaf: this.isRealLeaf()}; | 165 | + var dataToSend = {name: name, nodeType: this.get('nodeType'), leaf: this.isLeaf()}; |
175 | AmdaAction.validNameObject(dataToSend, callBackFn); | 166 | AmdaAction.validNameObject(dataToSend, callBackFn); |
176 | }, | 167 | }, |
177 | 168 | ||
@@ -219,7 +210,12 @@ Ext.define('amdaModel.InteractiveNode', { | @@ -219,7 +210,12 @@ Ext.define('amdaModel.InteractiveNode', { | ||
219 | // reload object into the view of corresponding Module | 210 | // reload object into the view of corresponding Module |
220 | var me = this; | 211 | var me = this; |
221 | myDesktopApp.getLoadedModule(this.get('moduleId'), true, function (module) { | 212 | myDesktopApp.getLoadedModule(this.get('moduleId'), true, function (module) { |
222 | - module.getUiContent().setObject(me.get('object')); | 213 | + if (!opt || !opt.plot) { |
214 | + module.getUiContent().setObject(me.get('object')); | ||
215 | + } | ||
216 | + else { | ||
217 | + module.getUiContent().reloadPlot(me); | ||
218 | + } | ||
223 | }); | 219 | }); |
224 | } | 220 | } |
225 | else { | 221 | else { |
@@ -459,16 +455,7 @@ Ext.define('amdaModel.InteractiveNode', { | @@ -459,16 +455,7 @@ Ext.define('amdaModel.InteractiveNode', { | ||
459 | { | 455 | { |
460 | if (node.get('disable')) return; | 456 | if (node.get('disable')) return; |
461 | myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.plot.id, true, function (module) { | 457 | myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.plot.id, true, function (module) { |
462 | - if (!myDesktopApp.desktop.getWindow(myDesktopApp.dynamicModules.plot.id)) { | ||
463 | - var request = Ext.create(amdaPlotObj.PlotRequestObject.$className); | ||
464 | - var newNode = Ext.create(amdaModel.PlotNode.$className, { object : request }); | ||
465 | - // edit newNode into Plot Module with node as contextNode | ||
466 | - newNode.editInModule(); | ||
467 | - if((node.get('globalStart') != null) && (node.get('globalStop') != null) && node.get('globalStart') != 'depending on mission' && node.get('isParameter')) { | ||
468 | - module.getUiContent().setTimeFromData(node.getTimeFromNode(node)); | ||
469 | - } | ||
470 | - } | ||
471 | - module.getUiContent().addParameter(node); | 458 | + module.addParameter(node); |
472 | }); | 459 | }); |
473 | }, | 460 | }, |
474 | 461 | ||
@@ -530,7 +517,7 @@ Ext.define('amdaModel.InteractiveNode', { | @@ -530,7 +517,7 @@ Ext.define('amdaModel.InteractiveNode', { | ||
530 | 517 | ||
531 | deleteNode: function() { | 518 | deleteNode: function() { |
532 | // if the target is a directory | 519 | // if the target is a directory |
533 | - if (!this.isRealLeaf()) { | 520 | + if (!this.isLeaf()) { |
534 | // determine if this directory is empty before launching the delete confirmation method | 521 | // determine if this directory is empty before launching the delete confirmation method |
535 | this.isNotEmptyDir(this.confirmDirectoryDeletion); | 522 | this.isNotEmptyDir(this.confirmDirectoryDeletion); |
536 | // else (the target is a leaf) | 523 | // else (the target is a leaf) |
@@ -583,14 +570,14 @@ Ext.define('amdaModel.InteractiveNode', { | @@ -583,14 +570,14 @@ Ext.define('amdaModel.InteractiveNode', { | ||
583 | */ | 570 | */ |
584 | realDelete : function() | 571 | realDelete : function() |
585 | { | 572 | { |
586 | - AmdaAction.deleteObject({id: this.get('id'), leaf: this.isRealLeaf(), nodeType: this.get('nodeType')}, function(res,e){ | 573 | + AmdaAction.deleteObject({id: this.get('id'), leaf: this.isLeaf(), nodeType: this.get('nodeType')}, function(res,e){ |
587 | //TODO proper errors handling | 574 | //TODO proper errors handling |
588 | // node deletion in tree | 575 | // node deletion in tree |
589 | if (res) { // if success | 576 | if (res) { // if success |
590 | if (res.id) { | 577 | if (res.id) { |
591 | //Ext.Msg.show({title:'Warning', msg: 'Requests with parameter '+node.data.text+' are deleted', icon: Ext.MessageBox.ERROR, buttons: Ext.Msg.OK}); | 578 | //Ext.Msg.show({title:'Warning', msg: 'Requests with parameter '+node.data.text+' are deleted', icon: Ext.MessageBox.ERROR, buttons: Ext.Msg.OK}); |
592 | if (this.parentNode) { | 579 | if (this.parentNode) { |
593 | - if (this.isRealLeaf()){ | 580 | + if (this.isLeaf()){ |
594 | var moduleId = this.get('moduleId'); | 581 | var moduleId = this.get('moduleId'); |
595 | // if really interactive node | 582 | // if really interactive node |
596 | if (moduleId) { | 583 | if (moduleId) { |
@@ -0,0 +1,25 @@ | @@ -0,0 +1,25 @@ | ||
1 | +/** | ||
2 | + * Project : AMDA-NG4 | ||
3 | + * Name : MultiplotNode.js | ||
4 | + * @class amdaModel.MutiplotNode | ||
5 | + * @extends amdaModel.ExecutableNode | ||
6 | + * @brief Basic Model of Node corresponding to a multi-plot request | ||
7 | + * @author Benjamin Renard | ||
8 | + */ | ||
9 | + | ||
10 | +Ext.define('amdaModel.MultiplotNode', { | ||
11 | + extend: 'amdaModel.ExecutableNode', | ||
12 | + | ||
13 | + statics: { | ||
14 | + nodeType: 'mutiplot' | ||
15 | + }, | ||
16 | + | ||
17 | + constructor : function(config){ | ||
18 | + this.callParent(arguments); | ||
19 | + this.set('moduleId',myDesktopApp.dynamicModules.plot.id); | ||
20 | + this.set('objectDataModel','amdaPlotObj.MultiplotRequestObject'); | ||
21 | + this.set('nodeType',this.self.nodeType); | ||
22 | + this.set('leaf', true); | ||
23 | + } | ||
24 | + | ||
25 | +}); |
js/app/models/PlotNode.js
@@ -8,49 +8,17 @@ | @@ -8,49 +8,17 @@ | ||
8 | */ | 8 | */ |
9 | 9 | ||
10 | Ext.define('amdaModel.PlotNode', { | 10 | Ext.define('amdaModel.PlotNode', { |
11 | - extend: 'amdaModel.ExecutableNode', | ||
12 | - | ||
13 | - fields : [ | ||
14 | - {name : 'tabs', type:'auto', defaultValue:false, persist: false} | ||
15 | - ], | 11 | + extend: 'amdaModel.ExecutableNode', |
16 | 12 | ||
17 | statics: { | 13 | statics: { |
18 | nodeType: 'request' | 14 | nodeType: 'request' |
19 | }, | 15 | }, |
20 | 16 | ||
21 | - requires:[ | ||
22 | - 'amdaModel.PlotTabNode' | ||
23 | - ], | ||
24 | - | ||
25 | constructor : function(config){ | 17 | constructor : function(config){ |
26 | this.callParent(arguments); | 18 | this.callParent(arguments); |
27 | this.set('moduleId',myDesktopApp.dynamicModules.plot.id); | 19 | this.set('moduleId',myDesktopApp.dynamicModules.plot.id); |
28 | this.set('objectDataModel','amdaPlotObj.PlotRequestObject'); | 20 | this.set('objectDataModel','amdaPlotObj.PlotRequestObject'); |
29 | this.set('nodeType',this.self.nodeType); | 21 | this.set('nodeType',this.self.nodeType); |
30 | - if (this.get('leaf')) { | ||
31 | - this.updateTabs(this.get('tabs')); | ||
32 | - } | ||
33 | - }, | ||
34 | - | ||
35 | - updateTabs : function(tabs) { | ||
36 | - if (tabs) { | ||
37 | - var oneTab = (tabs.length == 1); | ||
38 | - this.set('leaf', oneTab); | ||
39 | - this.set('iconCls', oneTab ? 'icon-plot-page' : 'icon-plot-pages'); | ||
40 | - this.removeAll(); | ||
41 | - if (tabs.length > 1) { | ||
42 | - var me = this; | ||
43 | - Ext.Array.each(tabs, function(tab) { | ||
44 | - var tabNode = new amdaModel.PlotTabNode({text: tab.name, tabid: tab.id}); | ||
45 | - me.appendChild(tabNode); | ||
46 | - }); | ||
47 | - } | ||
48 | - this.set('tabs', tabs); | ||
49 | - } | ||
50 | - }, | ||
51 | - | ||
52 | - specialUpdate : function(res) { | ||
53 | - this.updateTabs(res.tabs); | ||
54 | }, | 22 | }, |
55 | 23 | ||
56 | allMenuItems : function() { | 24 | allMenuItems : function() { |
@@ -76,10 +44,6 @@ Ext.define('amdaModel.PlotNode', { | @@ -76,10 +44,6 @@ Ext.define('amdaModel.PlotNode', { | ||
76 | }, { | 44 | }, { |
77 | fnId : 'leaf-deleteNode', | 45 | fnId : 'leaf-deleteNode', |
78 | text : 'Delete Request' | 46 | text : 'Delete Request' |
79 | - }, { | ||
80 | - fnId : 'leaf-insertTabs', | ||
81 | - text : 'Insert in current Plot Request' | ||
82 | - | ||
83 | }]; | 47 | }]; |
84 | 48 | ||
85 | return menuItems; | 49 | return menuItems; |
@@ -128,35 +92,33 @@ Ext.define('amdaModel.PlotNode', { | @@ -128,35 +92,33 @@ Ext.define('amdaModel.PlotNode', { | ||
128 | case 'deleteMulti': | 92 | case 'deleteMulti': |
129 | this.deleteMulti(); | 93 | this.deleteMulti(); |
130 | break; | 94 | break; |
131 | - case 'insertTabs': | ||
132 | - this.insertPlotTabsRequest(); | ||
133 | default: | 95 | default: |
134 | break; | 96 | break; |
135 | } | 97 | } |
136 | }, | 98 | }, |
137 | 99 | ||
138 | - isRealLeaf: function() | 100 | + //Override editInModule |
101 | + editInModule : function (contextNode, onReady) | ||
139 | { | 102 | { |
140 | - var isFolder = (!this.isLeaf()) && (this.get('tabs') === false); | ||
141 | - return !isFolder; | 103 | + // set the contextNode of this node |
104 | + this.set('contextNode',contextNode); | ||
105 | + | ||
106 | + var me = this; | ||
107 | + myDesktopApp.getLoadedModule(this.get('moduleId'),true, function (module) { | ||
108 | + module.editPlot(me); | ||
109 | + }); | ||
142 | }, | 110 | }, |
143 | 111 | ||
144 | - insertPlotTabsRequest: function() { | ||
145 | - var me = this; | ||
146 | - AmdaAction.getObject(me.get('id'), me.get('nodeType'), function (result,remoteEvent) { | ||
147 | - var paramObj = Ext.create(me.get('objectDataModel'), result); | ||
148 | - myDesktopApp.getLoadedModule(me.get('moduleId'), true, function (module) { | ||
149 | - module.createWindow(function () { | ||
150 | - var uiContent = module.getUiContent(); | ||
151 | - if (uiContent != null) { | ||
152 | - paramObj.tabs().each(function (tab) { | ||
153 | - var tabData = tab.getJsonValues(); | ||
154 | - uiContent.insertPlotTab(tabData); | ||
155 | - }); | ||
156 | - } | ||
157 | - }); | ||
158 | - }); | ||
159 | - }); | ||
160 | - } | ||
161 | - | 112 | + //Override rename |
113 | + rename: function(value,callBackFn) | ||
114 | + { | ||
115 | + var me = this; | ||
116 | + var dataToSend = {id : this.get('id'), old_name: this.modified.text, name: value, parent : this.data.parentId, leaf: this.isLeaf(), nodeType: this.get('nodeType')}; | ||
117 | + AmdaAction.renameObject(dataToSend, function(result) { | ||
118 | + callBackFn(result); | ||
119 | + myDesktopApp.getLoadedModule(me.get('moduleId'),true, function (module) { | ||
120 | + module.syncAfterRename(me); | ||
121 | + }); | ||
122 | + }); | ||
123 | + } | ||
162 | }); | 124 | }); |
@@ -0,0 +1,87 @@ | @@ -0,0 +1,87 @@ | ||
1 | +/** | ||
2 | + * Project : AMDA-NG | ||
3 | + * Name : MultiplotRequestObject.js | ||
4 | + * @class amdaPlotObj.MutiplotRequestObject | ||
5 | + * @extends amdaModel.AmdaTimeObject | ||
6 | + * @brief Multi-Plot Request Business Object Definition | ||
7 | + * @author Benjamin Renard | ||
8 | + * @version $Id: MultiplotRequestObject.js benjamin $ | ||
9 | + ****************************************************************************** | ||
10 | + * FT Id : Date : Name - Description | ||
11 | + ****************************************************************************** | ||
12 | + * : :28/02/2020: BRE - file creation | ||
13 | + */ | ||
14 | + | ||
15 | + | ||
16 | +Ext.define('amdaPlotObj.MultiplotRequestObject', { | ||
17 | + extend: 'amdaModel.AmdaTimeObject', | ||
18 | + idProperty: 'id', | ||
19 | + | ||
20 | + requires: [ | ||
21 | + 'amdaModel.PlotNode', | ||
22 | + 'amdaPlotObj.PlotRequestObject' | ||
23 | + ], | ||
24 | + | ||
25 | + hasMany: { | ||
26 | + model : 'amdaModel.PlotNode', | ||
27 | + name : 'plots', | ||
28 | + associationKey:'plots' | ||
29 | + }, | ||
30 | + | ||
31 | + constructor: function(){ | ||
32 | + var me = this; | ||
33 | + me.callParent(arguments); | ||
34 | + }, | ||
35 | + | ||
36 | + isDirty: function() { | ||
37 | + var dirty = false; | ||
38 | + this.plots().each(function(plotNode) { | ||
39 | + var plotObject = plotNode.get('object'); | ||
40 | + if (plotObject && (plotObject.get('id') != '') && plotObject.dirty) { | ||
41 | + dirty = true; | ||
42 | + } | ||
43 | + }); | ||
44 | + return dirty; | ||
45 | + }, | ||
46 | + | ||
47 | + createNewPlot: function() { | ||
48 | + var plotObject = Ext.create('amdaPlotObj.PlotRequestObject'); | ||
49 | + return this.createNewPlotFromObject(plotObject); | ||
50 | + }, | ||
51 | + | ||
52 | + duplicatePlot: function(plotNode) { | ||
53 | + var me = this; | ||
54 | + var newPlotNode = null; | ||
55 | + this.plots().each(function(node, index) { | ||
56 | + if (node == plotNode) { | ||
57 | + newPlotNode = Ext.create('amdaModel.PlotNode', { | ||
58 | + leaf : true | ||
59 | + }); | ||
60 | + var data = plotNode.get('object').getJsonValues(); | ||
61 | + newPlotNode.set('object', Ext.create('amdaPlotObj.PlotRequestObject', data)); | ||
62 | + plotNode.get('object').reject(); | ||
63 | + me.plots().remove(plotNode); | ||
64 | + me.plots().insert(index, [newPlotNode]); | ||
65 | + } | ||
66 | + }); | ||
67 | + return newPlotNode; | ||
68 | + }, | ||
69 | + | ||
70 | + createNewPlotFromObject: function(plotObject) { | ||
71 | + var plotNode = Ext.create('amdaModel.PlotNode', { | ||
72 | + leaf : true | ||
73 | + }); | ||
74 | + plotNode.set('object',plotObject); | ||
75 | + this.plots().add(plotNode); | ||
76 | + return this.plots().getAt(this.plots().count()-1); | ||
77 | + }, | ||
78 | + | ||
79 | + removePlotByInternalId: function(internalId) { | ||
80 | + var plotNode = this.plots().data.getByKey(internalId); | ||
81 | + if (plotNode) | ||
82 | + this.plots().remove(plotNode); | ||
83 | + }, | ||
84 | + | ||
85 | + addPlot: function(plotNode) { | ||
86 | + } | ||
87 | +}); |
js/app/models/PlotObjects/PlotRequestObject.js
@@ -5,11 +5,12 @@ | @@ -5,11 +5,12 @@ | ||
5 | * @extends amdaModel.AmdaTimeObject | 5 | * @extends amdaModel.AmdaTimeObject |
6 | * @brief Plot Request Business Object Definition | 6 | * @brief Plot Request Business Object Definition |
7 | * @author Benjamin Renard | 7 | * @author Benjamin Renard |
8 | - * @version $Id: PlotRequestObject.js benjamin $ | 8 | + * @version $Id: PlotTabObject.js benjamin $ |
9 | ****************************************************************************** | 9 | ****************************************************************************** |
10 | * FT Id : Date : Name - Description | 10 | * FT Id : Date : Name - Description |
11 | ****************************************************************************** | 11 | ****************************************************************************** |
12 | - * : :21/07/2015: BRE - file creation | 12 | + * : :22/07/2015: BRE - file creation |
13 | + * 20/03/2020: BRE - full rework | ||
13 | */ | 14 | */ |
14 | 15 | ||
15 | 16 | ||
@@ -19,122 +20,256 @@ Ext.define('amdaPlotObj.PlotRequestObject', { | @@ -19,122 +20,256 @@ Ext.define('amdaPlotObj.PlotRequestObject', { | ||
19 | 20 | ||
20 | requires: [ | 21 | requires: [ |
21 | 'amdaPlotObj.PlotObjectConfig', | 22 | 'amdaPlotObj.PlotObjectConfig', |
22 | - 'amdaPlotObj.PlotTabObject' | 23 | + 'amdaPlotObj.PlotPanelObject', |
24 | + 'amdaPlotObj.PlotLayoutVerticalObject', | ||
25 | + 'amdaPlotObj.PlotLayoutAutoObject', | ||
26 | + 'amdaPlotObj.PlotLayoutManualObject' | ||
23 | ], | 27 | ], |
24 | 28 | ||
25 | fields : [ | 29 | fields : [ |
26 | - {name: 'id', type:'string'}, | 30 | + {name: 'tab-index', type: 'int', defaultValue: 0, persist: false}, |
31 | + {name: 'tab-title', type: 'string', defaultValue: '', persist: false}, | ||
32 | + | ||
27 | {name: 'file-format', type: 'string'}, | 33 | {name: 'file-format', type: 'string'}, |
28 | {name: 'file-output', type: 'string'}, | 34 | {name: 'file-output', type: 'string'}, |
29 | {name: 'file-prefix', type: 'string'}, | 35 | {name: 'file-prefix', type: 'string'}, |
30 | {name: 'one-file-per-interval', type: 'boolean'}, | 36 | {name: 'one-file-per-interval', type: 'boolean'}, |
31 | - {name: 'last-plotted-tab', type: 'int', defaultValue: 0}, | ||
32 | - {name: 'last-tab-id', type: 'int', defaultValue: 0}, | ||
33 | - {name: 'active-tab-id', type: 'int', defaultValue: 1} | 37 | + |
38 | + {name: 'tree-full-view', type: 'boolean'}, | ||
39 | + {name: 'page-node-state', type: 'int', defaultValue: 2}, //0 : collapsed, 1 : expanded, 2 : not set | ||
40 | + {name: 'panels-node-state', type: 'int', defaultValue: 2}, //0 : collapsed, 1 : expanded, 2 : not set | ||
41 | + | ||
42 | + {name: 'page-title-text', type: 'string'}, | ||
43 | + {name: 'page-title-color', type: 'string'}, | ||
44 | + {name: 'page-title-position', type: 'string'}, | ||
45 | + {name: 'page-title-alignment', type: 'string'}, | ||
46 | + {name: 'page-title-font-activated', type: 'boolean'}, | ||
47 | + {name: 'page-title-font-name', type: 'string'}, | ||
48 | + {name: 'page-title-font-size', type: 'int'}, | ||
49 | + {name: 'page-title-font-bold', type: 'boolean'}, | ||
50 | + {name: 'page-title-font-italic', type: 'boolean'}, | ||
51 | + {name: 'page-margins-activated', type: 'boolean'}, | ||
52 | + {name: 'page-margin-x', type: 'float'}, | ||
53 | + {name: 'page-margin-y', type: 'float'}, | ||
54 | + {name: 'page-mode', type: 'string'}, | ||
55 | + {name: 'page-orientation', type: 'string'}, | ||
56 | + {name: 'page-dimension', type: 'string'}, | ||
57 | + {name: 'page-superpose-mode', type: 'boolean'}, | ||
58 | + {name: 'page-font-activated', type: 'boolean'}, | ||
59 | + {name: 'page-font-name', type: 'string'}, | ||
60 | + {name: 'page-font-size', type: 'int'}, | ||
61 | + {name: 'page-font-bold', type: 'boolean'}, | ||
62 | + {name: 'page-font-italic', type: 'boolean'}, | ||
63 | + {name: 'page-layout-type', type: 'string'}, | ||
64 | + {name: 'page-layout-object', type: 'auto', defaultValue: null}, | ||
65 | + {name: 'last-panel-id', type: 'int', defaultValue: 0} | ||
34 | ], | 66 | ], |
35 | 67 | ||
36 | - hasMany: { | ||
37 | - model : 'amdaPlotObj.PlotTabObject', | ||
38 | - name : 'tabs', | ||
39 | - associationKey:'tabs' | ||
40 | - }, | 68 | + associations : [ |
69 | + { | ||
70 | + type : 'hasMany', | ||
71 | + model : 'amdaPlotObj.PlotPanelObject', | ||
72 | + name : 'panels' | ||
73 | + } | ||
74 | + ], | ||
41 | 75 | ||
42 | constructor: function(){ | 76 | constructor: function(){ |
43 | - var me = this; | ||
44 | - me.callParent(arguments); | ||
45 | - if ((arguments.length > 0) && arguments[0] && arguments[0].tabs) | 77 | + var me = this; |
78 | + me.callParent(arguments); | ||
79 | + if ((arguments.length > 0) && arguments[0]) | ||
46 | { | 80 | { |
47 | - if (arguments[0].tabs) | ||
48 | - me.loadTabs(arguments[0].tabs); | 81 | + if (arguments[0].panels) |
82 | + me.loadPanels(arguments[0].panels); | ||
83 | + if (arguments[0]['page-layout-object']) | ||
84 | + me.loadLayoutObject(arguments[0]['page-layout-object']); | ||
49 | } | 85 | } |
50 | else | 86 | else |
51 | { | 87 | { |
52 | //new object, set default fields values | 88 | //new object, set default fields values |
53 | me.setDefaultValues(); | 89 | me.setDefaultValues(); |
54 | - //New object, force the creation of the first tab | ||
55 | - me.createNewTab(); | ||
56 | } | 90 | } |
91 | + this.dirty = false; | ||
57 | }, | 92 | }, |
58 | 93 | ||
59 | - loadTabs: function(tabs) | 94 | + loadPanels: function(panels) |
60 | { | 95 | { |
61 | - this.tabs().loadData(tabs); | 96 | + this.panels().loadData(panels); |
97 | + this.updatePanelIndex(); | ||
62 | }, | 98 | }, |
63 | 99 | ||
64 | - setDefaultValues: function() | 100 | + loadLayoutObject: function(layout) |
65 | { | 101 | { |
66 | - this.set('file-format', amdaPlotObj.PlotObjectConfig.defaultValues.file.format); | ||
67 | - this.set('file-output', amdaPlotObj.PlotObjectConfig.defaultValues.file.output); | ||
68 | - this.set('file-prefix', ''); | ||
69 | - this.set('one-file-per-interval', amdaPlotObj.PlotObjectConfig.defaultValues.file.oneFilePerInterval); | ||
70 | - this.set('last-plotted-tab', 0); | ||
71 | - this.set('name', ''); | 102 | + this.set('page-layout-object', this.createLayoutByType(this.get('page-layout-type'), layout)); |
103 | + if (this.get('page-layout-object') != null) | ||
104 | + this.get('page-layout-object').dirty = false; | ||
72 | }, | 105 | }, |
73 | 106 | ||
74 | - createNewTab: function() { | ||
75 | - this.set('last-tab-id', this.get('last-tab-id') + 1); | ||
76 | - var data = {id: this.get('last-tab-id')}; | ||
77 | - var applyDefault = true; | ||
78 | - if ((arguments.length > 0) && arguments[0]) { | ||
79 | - data = arguments[0]; | ||
80 | - data['id'] = this.get('last-tab-id'); | ||
81 | - applyDefault = false; | ||
82 | - } | ||
83 | - var recs = this.tabs().add(data); | ||
84 | - if (applyDefault) { | ||
85 | - recs[0].setDefaultValues(); | ||
86 | - } | 107 | + createNewPanel: function() { |
108 | + this.set('last-panel-id', this.get('last-panel-id') + 1); | ||
109 | + var recs = this.panels().add({id : this.get('last-panel-id')}); | ||
110 | + recs[0].setDefaultValues(); | ||
87 | this.dirty = true; | 111 | this.dirty = true; |
88 | - return recs[0]; | 112 | + this.updatePanelIndex(); |
113 | + return recs[0]; | ||
89 | }, | 114 | }, |
90 | 115 | ||
91 | - removeTabById: function(tabId) { | ||
92 | - //Retrieve tab record | ||
93 | - var tabRecord = this.tabs().getById(tabId); | ||
94 | - if (tabRecord == null) | 116 | + removePanelById: function(panelId) { |
117 | + //Retrieve panel record | ||
118 | + var panelRecord = this.panels().getById(panelId); | ||
119 | + if (panelRecord == null) | ||
95 | return false; | 120 | return false; |
96 | - this.tabs().remove(tabRecord); | 121 | + this.panels().remove(panelRecord); |
97 | this.dirty = true; | 122 | this.dirty = true; |
123 | + this.updatePanelIndex(); | ||
98 | return true; | 124 | return true; |
99 | }, | 125 | }, |
100 | 126 | ||
101 | - isDirty : function() | 127 | + updatePanelIndex: function() { |
128 | + this.panels().each(function(panel, index) { | ||
129 | + panel.set('panel-index', index); | ||
130 | + }); | ||
131 | + }, | ||
132 | + | ||
133 | + createLayoutByType : function(layoutType, data) | ||
102 | { | 134 | { |
103 | - if (this.get('id') == '') | ||
104 | - return false; | 135 | + //Create layout object in relation with the type |
136 | + switch (layoutType) | ||
137 | + { | ||
138 | + case 'vertical' : | ||
139 | + return new amdaPlotObj.PlotLayoutVerticalObject(data); | ||
140 | + case 'auto' : | ||
141 | + return new amdaPlotObj.PlotLayoutAutoObject(data); | ||
142 | + case 'manual' : | ||
143 | + return new amdaPlotObj.PlotLayoutManualObject(data); | ||
144 | + default : | ||
145 | + return null; | ||
146 | + } | ||
147 | + }, | ||
148 | + | ||
149 | + setLayout: function(layoutType) | ||
150 | + { | ||
151 | + if (layoutType == this.get('page-layout-type')) | ||
152 | + return; | ||
153 | + | ||
154 | + this.set('page-layout-type', layoutType); | ||
155 | + this.set('page-layout-object', this.createLayoutByType(layoutType)); | ||
156 | + }, | ||
157 | + | ||
158 | + setDefaultValues: function() | ||
159 | + { | ||
160 | + this.set('file-format', amdaPlotObj.PlotObjectConfig.defaultValues.file.format); | ||
161 | + this.set('file-output', amdaPlotObj.PlotObjectConfig.defaultValues.file.output); | ||
162 | + this.set('file-prefix', ''); | ||
163 | + this.set('one-file-per-interval', amdaPlotObj.PlotObjectConfig.defaultValues.file.oneFilePerInterval); | ||
164 | + this.set('name', ''); | ||
165 | + | ||
166 | + this.set('tree-full-view', amdaPlotObj.PlotObjectConfig.defaultValues.tree.fullView); | ||
105 | 167 | ||
168 | + this.set('page-title-text', ''); | ||
169 | + this.set('page-title-color', amdaPlotObj.PlotObjectConfig.defaultValues.page.title.color); | ||
170 | + this.set('page-title-position', amdaPlotObj.PlotObjectConfig.defaultValues.page.title.position); | ||
171 | + this.set('page-title-alignment', amdaPlotObj.PlotObjectConfig.defaultValues.page.title.alignment); | ||
172 | + | ||
173 | + this.set('page-title-font-activated', false); | ||
174 | + this.set('page-title-font-name', amdaPlotObj.PlotObjectConfig.defaultValues.page.font.name); | ||
175 | + this.set('page-title-font-size', amdaPlotObj.PlotObjectConfig.defaultValues.page.font.size); | ||
176 | + this.set('page-title-font-bold', false); | ||
177 | + this.set('page-title-font-italic', false); | ||
178 | + | ||
179 | + this.set('page-margins-activated', false); | ||
180 | + this.set('page-margin-x', amdaPlotObj.PlotObjectConfig.defaultValues.page.xMargin); | ||
181 | + this.set('page-margin-y', amdaPlotObj.PlotObjectConfig.defaultValues.page.yMargin); | ||
182 | + this.set('page-mode', amdaPlotObj.PlotObjectConfig.defaultValues.page.mode); | ||
183 | + this.set('page-orientation', amdaPlotObj.PlotObjectConfig.defaultValues.page.orientation); | ||
184 | + this.set('page-dimension', amdaPlotObj.PlotObjectConfig.defaultValues.page.dimension); | ||
185 | + this.set('page-superpose-mode', false); | ||
186 | + this.set('page-font-activated', false); | ||
187 | + this.set('page-font-name', amdaPlotObj.PlotObjectConfig.defaultValues.page.font.name); | ||
188 | + this.set('page-font-size', amdaPlotObj.PlotObjectConfig.defaultValues.page.font.size); | ||
189 | + this.set('page-font-bold', false); | ||
190 | + this.set('page-font-italic', false); | ||
191 | + | ||
192 | + this.setLayout(amdaPlotObj.PlotObjectConfig.defaultValues.page.layout.type); | ||
193 | + }, | ||
194 | + | ||
195 | + getPageShortInfo : function() | ||
196 | + { | ||
197 | + var dimension = amdaPlotObj.PlotObjectConfig.getValueByKey(amdaPlotObj.PlotObjectConfig.availablePageDimensions, this.get('page-dimension')); | ||
198 | + var orientation = amdaPlotObj.PlotObjectConfig.getValueByKey(amdaPlotObj.PlotObjectConfig.availablePageOrientations, this.get('page-orientation')); | ||
199 | + | ||
200 | + var info = dimension+', '+orientation; | ||
201 | + if (this.get('page-superpose-mode')) | ||
202 | + info += ', Epoch superposed mode'; | ||
203 | + return info; | ||
204 | + }, | ||
205 | + | ||
206 | + getLayoutShortInfo : function() | ||
207 | + { | ||
208 | + var type = amdaPlotObj.PlotObjectConfig.getValueByKey(amdaPlotObj.PlotObjectConfig.availablePageLayouts, this.get('page-layout-type')); | ||
209 | + return type; | ||
210 | + }, | ||
211 | + | ||
212 | + isDirty : function() | ||
213 | + { | ||
106 | if (this.dirty) | 214 | if (this.dirty) |
107 | return true; | 215 | return true; |
108 | 216 | ||
217 | + if (this.get('page-layout-object') != null) | ||
218 | + if (this.get('page-layout-object').dirty) | ||
219 | + return true; | ||
220 | + | ||
109 | var d = false; | 221 | var d = false; |
110 | - this.tabs().each(function (tab, index) { | ||
111 | - if (tab.isDirty()) | 222 | + this.panels().each(function (panel, index) { |
223 | + if (panel.isDirty()) | ||
112 | d = true; | 224 | d = true; |
113 | }); | 225 | }); |
114 | return d; | 226 | return d; |
115 | }, | 227 | }, |
116 | 228 | ||
117 | - getJsonValues : function(hasId) | 229 | + getJsonValues : function() |
118 | { | 230 | { |
119 | var requestValues = new Object(); | 231 | var requestValues = new Object(); |
232 | + | ||
233 | + requestValues['nodeType'] = 'request'; | ||
234 | + requestValues['leaf'] = true; | ||
120 | 235 | ||
121 | - requestValues['nodeType'] = 'request'; | ||
122 | - | ||
123 | - if (hasId) { | ||
124 | - requestValues['id'] = this.get('id'); | ||
125 | - } | ||
126 | - | ||
127 | - requestValues['leaf'] = true; | 236 | + requestValues['id'] = this.get('id'); |
237 | + requestValues['tab-index'] = this.get('tab-index'); | ||
238 | + requestValues['tab-title'] = this.get('tab-title'); | ||
239 | + requestValues['name'] = this.get('name'); | ||
240 | + | ||
241 | + requestValues['file-format'] = this.get('file-format'); | ||
242 | + requestValues['file-output'] = this.get('file-output'); | ||
243 | + requestValues['file-prefix'] = this.get('file-prefix'); | ||
244 | + requestValues['one-file-per-interval'] = this.get('one-file-per-interval'); | ||
245 | + | ||
246 | + requestValues['tree-full-view'] = this.get('tree-full-view'); | ||
247 | + requestValues['page-node-state'] = this.get('page-node-state'); | ||
248 | + requestValues['panels-node-state'] = this.get('panels-node-state'); | ||
249 | + | ||
250 | + requestValues['page-title-text'] = this.get('page-title-text'); | ||
251 | + requestValues['page-title-color'] = this.get('page-title-color'); | ||
252 | + requestValues['page-title-position'] = this.get('page-title-position'); | ||
253 | + requestValues['page-title-alignment'] = this.get('page-title-alignment'); | ||
254 | + requestValues['page-title-font-activated'] = this.get('page-title-font-activated'); | ||
255 | + requestValues['page-title-font-name'] = this.get('page-title-font-name'); | ||
256 | + requestValues['page-title-font-size'] = this.get('page-title-font-size'); | ||
257 | + requestValues['page-title-font-bold'] = this.get('page-title-font-bold'); | ||
258 | + requestValues['page-title-font-italic'] = this.get('page-title-font-italic'); | ||
259 | + requestValues['page-margins-activated'] = this.get('page-margins-activated'); | ||
260 | + requestValues['page-margin-x'] = this.get('page-margin-x'); | ||
261 | + requestValues['page-margin-y'] = this.get('page-margin-y'); | ||
262 | + requestValues['page-mode'] = this.get('page-mode'); | ||
263 | + requestValues['page-orientation'] = this.get('page-orientation'); | ||
264 | + requestValues['page-dimension'] = this.get('page-dimension'); | ||
265 | + requestValues['page-superpose-mode'] = this.get('page-superpose-mode'); | ||
266 | + requestValues['page-font-activated'] = this.get('page-font-activated'); | ||
267 | + requestValues['page-font-name'] = this.get('page-font-name'); | ||
268 | + requestValues['page-font-size'] = this.get('page-font-size'); | ||
269 | + requestValues['page-font-bold'] = this.get('page-font-bold'); | ||
270 | + requestValues['page-font-italic'] = this.get('page-font-italic'); | ||
128 | 271 | ||
129 | - requestValues['file-format'] = this.get('file-format'); | ||
130 | - requestValues['file-output'] = this.get('file-output'); | ||
131 | - requestValues['file-prefix'] = this.get('file-prefix'); | ||
132 | - requestValues['one-file-per-interval'] = this.get('one-file-per-interval'); | ||
133 | - requestValues['last-plotted-tab'] = this.get('last-plotted-tab'); | ||
134 | - requestValues['name'] = this.get('name'); | ||
135 | - | ||
136 | - requestValues['timesrc'] = this.get('timesrc'); | ||
137 | - | 272 | + requestValues['timesrc'] = this.get('timesrc'); |
138 | // if there's at least one timeTable name into 'timeTables' collection | 273 | // if there's at least one timeTable name into 'timeTables' collection |
139 | if (this.get('timesrc') == amdaModel.AmdaTimeObject.inputTimeSrc[0] && this.get('timeTables') && this.get('timeTables').length){ | 274 | if (this.get('timesrc') == amdaModel.AmdaTimeObject.inputTimeSrc[0] && this.get('timeTables') && this.get('timeTables').length){ |
140 | // get complete timeTables collection | 275 | // get complete timeTables collection |
@@ -152,23 +287,26 @@ Ext.define('amdaPlotObj.PlotRequestObject', { | @@ -152,23 +287,26 @@ Ext.define('amdaPlotObj.PlotRequestObject', { | ||
152 | } | 287 | } |
153 | }); | 288 | }); |
154 | } else { | 289 | } else { |
155 | - requestValues['startDate'] = this.get('startDate'); | ||
156 | - requestValues['stopDate'] = this.get('stopDate'); | ||
157 | - requestValues['durationDay'] = this.get('durationDay'); | ||
158 | - requestValues['durationHour'] = this.get('durationHour'); | ||
159 | - requestValues['durationMin'] = this.get('durationMin'); | ||
160 | - requestValues['durationSec'] = this.get('durationSec'); | ||
161 | - } | 290 | + requestValues['startDate'] = this.get('startDate'); |
291 | + requestValues['stopDate'] = this.get('stopDate'); | ||
292 | + requestValues['durationDay'] = this.get('durationDay'); | ||
293 | + requestValues['durationHour'] = this.get('durationHour'); | ||
294 | + requestValues['durationMin'] = this.get('durationMin'); | ||
295 | + requestValues['durationSec'] = this.get('durationSec'); | ||
296 | + } | ||
162 | 297 | ||
163 | - requestValues['tabs'] = []; | ||
164 | - | ||
165 | - this.tabs().each(function (tab, index) { | ||
166 | - requestValues['tabs'][index] = tab.getJsonValues(); | ||
167 | - }); | ||
168 | - | ||
169 | - requestValues['active-tab-id'] = this.get('active-tab-id'); | ||
170 | - requestValues['last-tab-id'] = this.get('last-tab-id'); | ||
171 | - | ||
172 | - return requestValues; | 298 | + requestValues['page-layout-type'] = this.get('page-layout-type'); |
299 | + if (this.get('page-layout-object') != null) | ||
300 | + requestValues['page-layout-object'] = this.get('page-layout-object').getJsonValues(); | ||
301 | + | ||
302 | + requestValues['panels'] = []; | ||
303 | + | ||
304 | + this.panels().each(function (panel, index) { | ||
305 | + requestValues['panels'][index] = panel.getJsonValues(); | ||
306 | + }); | ||
307 | + | ||
308 | + requestValues['last-panel-id'] = this.get('last-panel-id'); | ||
309 | + | ||
310 | + return requestValues; | ||
173 | } | 311 | } |
174 | }); | 312 | }); |
js/app/models/PlotObjects/PlotTabObject.js deleted
@@ -1,294 +0,0 @@ | @@ -1,294 +0,0 @@ | ||
1 | -/** | ||
2 | - * Project : AMDA-NG | ||
3 | - * Name : PlotTabObject.js | ||
4 | - * @class amdaPlotObj.PlotTabObject | ||
5 | - * @extends amdaModel.AmdaTimeObject | ||
6 | - * @brief Plot Tab Business Object Definition | ||
7 | - * @author Benjamin Renard | ||
8 | - * @version $Id: PlotTabObject.js benjamin $ | ||
9 | - ****************************************************************************** | ||
10 | - * FT Id : Date : Name - Description | ||
11 | - ****************************************************************************** | ||
12 | - * : :22/07/2015: BRE - file creation | ||
13 | - */ | ||
14 | - | ||
15 | - | ||
16 | -Ext.define('amdaPlotObj.PlotTabObject', { | ||
17 | - extend: 'amdaModel.AmdaTimeObject', | ||
18 | - idProperty: 'id', | ||
19 | - | ||
20 | - requires: [ | ||
21 | - 'amdaPlotObj.PlotObjectConfig', | ||
22 | - 'amdaPlotObj.PlotPanelObject', | ||
23 | - 'amdaPlotObj.PlotLayoutVerticalObject', | ||
24 | - 'amdaPlotObj.PlotLayoutAutoObject', | ||
25 | - 'amdaPlotObj.PlotLayoutManualObject' | ||
26 | - ], | ||
27 | - | ||
28 | - fields : [ | ||
29 | - {name: 'id', type: 'int'}, | ||
30 | - {name: 'tab-name', type: 'string', defaultValue: ''}, | ||
31 | - {name: 'tree-full-view', type: 'boolean'}, | ||
32 | - {name: 'multi-plot-linked', type: 'boolean'}, | ||
33 | - {name: 'page-node-state', type: 'int', defaultValue: 2}, //0 : collapsed, 1 : expanded, 2 : not set | ||
34 | - {name: 'panels-node-state', type: 'int', defaultValue: 2}, //0 : collapsed, 1 : expanded, 2 : not set | ||
35 | - {name: 'page-title-text', type: 'string'}, | ||
36 | - {name: 'page-title-color', type: 'string'}, | ||
37 | - {name: 'page-title-position', type: 'string'}, | ||
38 | - {name: 'page-title-alignment', type: 'string'}, | ||
39 | - {name: 'page-title-font-activated', type: 'boolean'}, | ||
40 | - {name: 'page-title-font-name', type: 'string'}, | ||
41 | - {name: 'page-title-font-size', type: 'int'}, | ||
42 | - {name: 'page-title-font-bold', type: 'boolean'}, | ||
43 | - {name: 'page-title-font-italic', type: 'boolean'}, | ||
44 | - {name: 'page-margins-activated', type: 'boolean'}, | ||
45 | - {name: 'page-margin-x', type: 'float'}, | ||
46 | - {name: 'page-margin-y', type: 'float'}, | ||
47 | - {name: 'page-mode', type: 'string'}, | ||
48 | - {name: 'page-orientation', type: 'string'}, | ||
49 | - {name: 'page-dimension', type: 'string'}, | ||
50 | - {name: 'page-superpose-mode', type: 'boolean'}, | ||
51 | - {name: 'page-font-activated', type: 'boolean'}, | ||
52 | - {name: 'page-font-name', type: 'string'}, | ||
53 | - {name: 'page-font-size', type: 'int'}, | ||
54 | - {name: 'page-font-bold', type: 'boolean'}, | ||
55 | - {name: 'page-font-italic', type: 'boolean'}, | ||
56 | - {name: 'page-layout-type', type: 'string'}, | ||
57 | - {name: 'page-layout-object', type: 'auto', defaultValue: null}, | ||
58 | - {name: 'last-panel-id', type: 'int', defaultValue: 0} | ||
59 | - ], | ||
60 | - | ||
61 | - associations : [ | ||
62 | - { | ||
63 | - type : 'hasMany', | ||
64 | - model : 'amdaPlotObj.PlotPanelObject', | ||
65 | - name : 'panels' | ||
66 | - }, | ||
67 | - { | ||
68 | - type : 'belongsTo', | ||
69 | - model : 'amdaPlotObj.PlotRequestObject' | ||
70 | - } | ||
71 | - ], | ||
72 | - | ||
73 | - constructor: function(){ | ||
74 | - var me = this; | ||
75 | - me.callParent(arguments); | ||
76 | - if ((arguments.length > 0) && arguments[0]) | ||
77 | - { | ||
78 | - if (arguments[0].panels) | ||
79 | - me.loadPanels(arguments[0].panels); | ||
80 | - if (arguments[0]['page-layout-object']) | ||
81 | - me.loadLayoutObject(arguments[0]['page-layout-object']); | ||
82 | - } | ||
83 | - else | ||
84 | - { | ||
85 | - //new object, set default fields values | ||
86 | - me.setDefaultValues(); | ||
87 | - } | ||
88 | - this.dirty = false; | ||
89 | - }, | ||
90 | - | ||
91 | - loadPanels: function(panels) | ||
92 | - { | ||
93 | - this.panels().loadData(panels); | ||
94 | - this.updatePanelIndex(); | ||
95 | - }, | ||
96 | - | ||
97 | - loadLayoutObject: function(layout) | ||
98 | - { | ||
99 | - this.set('page-layout-object', this.createLayoutByType(this.get('page-layout-type'), layout)); | ||
100 | - if (this.get('page-layout-object') != null) | ||
101 | - this.get('page-layout-object').dirty = false; | ||
102 | - }, | ||
103 | - | ||
104 | - createNewPanel: function() { | ||
105 | - this.set('last-panel-id', this.get('last-panel-id') + 1); | ||
106 | - var recs = this.panels().add({id : this.get('last-panel-id')}); | ||
107 | - recs[0].setDefaultValues(); | ||
108 | - this.dirty = true; | ||
109 | - this.updatePanelIndex(); | ||
110 | - return recs[0]; | ||
111 | - }, | ||
112 | - | ||
113 | - removePanelById: function(panelId) { | ||
114 | - //Retrieve panel record | ||
115 | - var panelRecord = this.panels().getById(panelId); | ||
116 | - if (panelRecord == null) | ||
117 | - return false; | ||
118 | - this.panels().remove(panelRecord); | ||
119 | - this.dirty = true; | ||
120 | - this.updatePanelIndex(); | ||
121 | - return true; | ||
122 | - }, | ||
123 | - | ||
124 | - updatePanelIndex: function() { | ||
125 | - this.panels().each(function(panel, index) { | ||
126 | - panel.set('panel-index', index); | ||
127 | - }); | ||
128 | - }, | ||
129 | - | ||
130 | - createLayoutByType : function(layoutType, data) | ||
131 | - { | ||
132 | - //Create layout object in relation with the type | ||
133 | - switch (layoutType) | ||
134 | - { | ||
135 | - case 'vertical' : | ||
136 | - return new amdaPlotObj.PlotLayoutVerticalObject(data); | ||
137 | - case 'auto' : | ||
138 | - return new amdaPlotObj.PlotLayoutAutoObject(data); | ||
139 | - case 'manual' : | ||
140 | - return new amdaPlotObj.PlotLayoutManualObject(data); | ||
141 | - default : | ||
142 | - return null; | ||
143 | - } | ||
144 | - }, | ||
145 | - | ||
146 | - setLayout: function(layoutType) | ||
147 | - { | ||
148 | - if (layoutType == this.get('page-layout-type')) | ||
149 | - return; | ||
150 | - | ||
151 | - this.set('page-layout-type', layoutType); | ||
152 | - this.set('page-layout-object', this.createLayoutByType(layoutType)); | ||
153 | - }, | ||
154 | - | ||
155 | - setDefaultValues: function() | ||
156 | - { | ||
157 | - this.set('tree-full-view', amdaPlotObj.PlotObjectConfig.defaultValues.tree.fullView); | ||
158 | - | ||
159 | - this.set('multi-plot-linked', false); | ||
160 | - | ||
161 | - this.set('page-title-text', ''); | ||
162 | - this.set('page-title-color', amdaPlotObj.PlotObjectConfig.defaultValues.page.title.color); | ||
163 | - this.set('page-title-position', amdaPlotObj.PlotObjectConfig.defaultValues.page.title.position); | ||
164 | - this.set('page-title-alignment', amdaPlotObj.PlotObjectConfig.defaultValues.page.title.alignment); | ||
165 | - | ||
166 | - this.set('page-title-font-activated', false); | ||
167 | - this.set('page-title-font-name', amdaPlotObj.PlotObjectConfig.defaultValues.page.font.name); | ||
168 | - this.set('page-title-font-size', amdaPlotObj.PlotObjectConfig.defaultValues.page.font.size); | ||
169 | - this.set('page-title-font-bold', false); | ||
170 | - this.set('page-title-font-italic', false); | ||
171 | - | ||
172 | - this.set('page-margins-activated', false); | ||
173 | - this.set('page-margin-x', amdaPlotObj.PlotObjectConfig.defaultValues.page.xMargin); | ||
174 | - this.set('page-margin-y', amdaPlotObj.PlotObjectConfig.defaultValues.page.yMargin); | ||
175 | - this.set('page-mode', amdaPlotObj.PlotObjectConfig.defaultValues.page.mode); | ||
176 | - this.set('page-orientation', amdaPlotObj.PlotObjectConfig.defaultValues.page.orientation); | ||
177 | - this.set('page-dimension', amdaPlotObj.PlotObjectConfig.defaultValues.page.dimension); | ||
178 | - this.set('page-superpose-mode', false); | ||
179 | - this.set('page-font-activated', false); | ||
180 | - this.set('page-font-name', amdaPlotObj.PlotObjectConfig.defaultValues.page.font.name); | ||
181 | - this.set('page-font-size', amdaPlotObj.PlotObjectConfig.defaultValues.page.font.size); | ||
182 | - this.set('page-font-bold', false); | ||
183 | - this.set('page-font-italic', false); | ||
184 | - | ||
185 | - this.setLayout(amdaPlotObj.PlotObjectConfig.defaultValues.page.layout.type); | ||
186 | - }, | ||
187 | - | ||
188 | - getPageShortInfo : function() | ||
189 | - { | ||
190 | - var dimension = amdaPlotObj.PlotObjectConfig.getValueByKey(amdaPlotObj.PlotObjectConfig.availablePageDimensions, this.get('page-dimension')); | ||
191 | - var orientation = amdaPlotObj.PlotObjectConfig.getValueByKey(amdaPlotObj.PlotObjectConfig.availablePageOrientations, this.get('page-orientation')); | ||
192 | - | ||
193 | - var info = dimension+', '+orientation; | ||
194 | - if (this.get('page-superpose-mode')) | ||
195 | - info += ', Epoch superposed mode'; | ||
196 | - return info; | ||
197 | - }, | ||
198 | - | ||
199 | - getLayoutShortInfo : function() | ||
200 | - { | ||
201 | - var type = amdaPlotObj.PlotObjectConfig.getValueByKey(amdaPlotObj.PlotObjectConfig.availablePageLayouts, this.get('page-layout-type')); | ||
202 | - return type; | ||
203 | - }, | ||
204 | - | ||
205 | - isDirty : function() | ||
206 | - { | ||
207 | - if (this.dirty) | ||
208 | - return true; | ||
209 | - | ||
210 | - if (this.get('page-layout-object') != null) | ||
211 | - if (this.get('page-layout-object').dirty) | ||
212 | - return true; | ||
213 | - | ||
214 | - var d = false; | ||
215 | - this.panels().each(function (panel, index) { | ||
216 | - if (panel.isDirty()) | ||
217 | - d = true; | ||
218 | - }); | ||
219 | - return d; | ||
220 | - }, | ||
221 | - | ||
222 | - getJsonValues : function() | ||
223 | - { | ||
224 | - var tabValues = new Object(); | ||
225 | - | ||
226 | - tabValues['id'] = this.get('id'); | ||
227 | - tabValues['tab-name'] = this.get('tab-name'); | ||
228 | - tabValues['tree-full-view'] = this.get('tree-full-view'); | ||
229 | - tabValues['multi-plot-linked'] = this.get('multi-plot-linked'); | ||
230 | - tabValues['page-node-state'] = this.get('page-node-state'); | ||
231 | - tabValues['panels-node-state'] = this.get('panels-node-state'); | ||
232 | - tabValues['page-title-text'] = this.get('page-title-text'); | ||
233 | - tabValues['page-title-color'] = this.get('page-title-color'); | ||
234 | - tabValues['page-title-position'] = this.get('page-title-position'); | ||
235 | - tabValues['page-title-alignment'] = this.get('page-title-alignment'); | ||
236 | - tabValues['page-title-font-activated'] = this.get('page-title-font-activated'); | ||
237 | - tabValues['page-title-font-name'] = this.get('page-title-font-name'); | ||
238 | - tabValues['page-title-font-size'] = this.get('page-title-font-size'); | ||
239 | - tabValues['page-title-font-bold'] = this.get('page-title-font-bold'); | ||
240 | - tabValues['page-title-font-italic'] = this.get('page-title-font-italic'); | ||
241 | - tabValues['page-margins-activated'] = this.get('page-margins-activated'); | ||
242 | - tabValues['page-margin-x'] = this.get('page-margin-x'); | ||
243 | - tabValues['page-margin-y'] = this.get('page-margin-y'); | ||
244 | - tabValues['page-mode'] = this.get('page-mode'); | ||
245 | - tabValues['page-orientation'] = this.get('page-orientation'); | ||
246 | - tabValues['page-dimension'] = this.get('page-dimension'); | ||
247 | - tabValues['page-superpose-mode'] = this.get('page-superpose-mode'); | ||
248 | - tabValues['page-font-activated'] = this.get('page-font-activated'); | ||
249 | - tabValues['page-font-name'] = this.get('page-font-name'); | ||
250 | - tabValues['page-font-size'] = this.get('page-font-size'); | ||
251 | - tabValues['page-font-bold'] = this.get('page-font-bold'); | ||
252 | - tabValues['page-font-italic'] = this.get('page-font-italic'); | ||
253 | - | ||
254 | - tabValues['timesrc'] = this.get('timesrc'); | ||
255 | - // if there's at least one timeTable name into 'timeTables' collection | ||
256 | - if (this.get('timesrc') == amdaModel.AmdaTimeObject.inputTimeSrc[0] && this.get('timeTables') && this.get('timeTables').length){ | ||
257 | - // get complete timeTables collection | ||
258 | - var timeTables = this.get('timeTables'); | ||
259 | - // init an empty array for timeTables | ||
260 | - tabValues['timeTables'] = []; | ||
261 | - // for each interval record | ||
262 | - Ext.Array.each(timeTables, function(item, index, all){ | ||
263 | - if (!item.$className) { | ||
264 | - tabValues['timeTables'][index] = {timeTableName : item.timeTableName, id : item.id}; | ||
265 | - } | ||
266 | - // get Json simplified value | ||
267 | - else { | ||
268 | - tabValues['timeTables'][index] = item.getJsonValues(); | ||
269 | - } | ||
270 | - }); | ||
271 | - } else { | ||
272 | - tabValues['startDate'] = this.get('startDate'); | ||
273 | - tabValues['stopDate'] = this.get('stopDate'); | ||
274 | - tabValues['durationDay'] = this.get('durationDay'); | ||
275 | - tabValues['durationHour'] = this.get('durationHour'); | ||
276 | - tabValues['durationMin'] = this.get('durationMin'); | ||
277 | - tabValues['durationSec'] = this.get('durationSec'); | ||
278 | - } | ||
279 | - | ||
280 | - tabValues['page-layout-type'] = this.get('page-layout-type'); | ||
281 | - if (this.get('page-layout-object') != null) | ||
282 | - tabValues['page-layout-object'] = this.get('page-layout-object').getJsonValues(); | ||
283 | - | ||
284 | - tabValues['panels'] = []; | ||
285 | - | ||
286 | - this.panels().each(function (panel, index) { | ||
287 | - tabValues['panels'][index] = panel.getJsonValues(); | ||
288 | - }); | ||
289 | - | ||
290 | - tabValues['last-panel-id'] = this.get('last-panel-id'); | ||
291 | - | ||
292 | - return tabValues; | ||
293 | - } | ||
294 | -}); |
js/app/models/PlotTabNode.js deleted
@@ -1,164 +0,0 @@ | @@ -1,164 +0,0 @@ | ||
1 | -/** | ||
2 | - * Project : AMDA-NG4 | ||
3 | - * Name : PlotTabNode.js | ||
4 | - * @class amdaModel.PlotTabNode | ||
5 | - * @extends amdaModel.ExecutableNode | ||
6 | - * @brief Basic Model of Node corresponding to a tab of a plot request | ||
7 | - * @author Benjamin Renard | ||
8 | - */ | ||
9 | - | ||
10 | -Ext.define('amdaModel.PlotTabNode', { | ||
11 | - extend: 'amdaModel.ExecutableNode', | ||
12 | - | ||
13 | - fields : [ | ||
14 | - {name : 'tabid', type:'string', defaultValue:'', persist: false} | ||
15 | - ], | ||
16 | - | ||
17 | - statics: { | ||
18 | - nodeType: 'plottab' | ||
19 | - }, | ||
20 | - | ||
21 | - constructor : function(config){ | ||
22 | - this.callParent(arguments); | ||
23 | - this.set('moduleId',myDesktopApp.dynamicModules.plot.id); | ||
24 | - //this.set('objectDataModel','amdaPlotObj.PlotRequestObject'); | ||
25 | - this.set('nodeType',this.self.nodeType); | ||
26 | - this.set('leaf',true); | ||
27 | - this.set('iconCls','icon-plot-page'); | ||
28 | - }, | ||
29 | - | ||
30 | - allMenuItems : function() { | ||
31 | - var menuItems = | ||
32 | - [ | ||
33 | - { | ||
34 | - fnId : 'ptab-openTab', | ||
35 | - text : 'Open in new Plot Request' | ||
36 | - }, { | ||
37 | - fnId : 'ptab-insertTab', | ||
38 | - text : 'Insert in current Plot Request' | ||
39 | - }, { | ||
40 | - fnId : 'ptab-renameTab', | ||
41 | - text : 'Rename Plot Tab' | ||
42 | - }]; | ||
43 | - | ||
44 | - return menuItems; | ||
45 | - }, | ||
46 | - | ||
47 | - allMenuMultiItems : function() { | ||
48 | - var menuMulti = [ | ||
49 | - ]; | ||
50 | - return menuMulti; | ||
51 | - }, | ||
52 | - | ||
53 | - getAllContextMenuItems: function(){ | ||
54 | - return this.allMenuItems(); | ||
55 | - }, | ||
56 | - | ||
57 | - getMultiContextMenuItems: function(){ | ||
58 | - return this.allMenuMultiItems(); | ||
59 | - }, | ||
60 | - | ||
61 | - onMenuItemClick : function(menu,item,event) { | ||
62 | - | ||
63 | - var fnId = Ext.util.Format.substr(item.fnId, 5, item.fnId.length); | ||
64 | - | ||
65 | - switch (fnId) { | ||
66 | - | ||
67 | - case 'openTab': | ||
68 | - this.insertPlotTabRequest(true); | ||
69 | - break; | ||
70 | - | ||
71 | - case 'insertTab': | ||
72 | - this.insertPlotTabRequest(false); | ||
73 | - break; | ||
74 | - | ||
75 | - case 'renameTab': | ||
76 | - this.renameTab(); | ||
77 | - break; | ||
78 | - default: | ||
79 | - break; | ||
80 | - } | ||
81 | - }, | ||
82 | - | ||
83 | - insertPlotTabRequest : function(inNewRequest) { | ||
84 | - var me = this; | ||
85 | - amdaModel.InteractiveNode.preloadNodes(this.parentNode.getRootNode(), function() { | ||
86 | - AmdaAction.getObject(me.parentNode.get('id'), me.parentNode.get('nodeType'), function (result,remoteEvent) { | ||
87 | - var paramObj = Ext.create(me.parentNode.get('objectDataModel'), result); | ||
88 | - var tabData = null; | ||
89 | - paramObj.tabs().each(function(tab) { | ||
90 | - if (tab.get('id') == me.get('tabid')) { | ||
91 | - tabData = tab.getJsonValues(); | ||
92 | - } | ||
93 | - }); | ||
94 | - if (tabData != null) { | ||
95 | - if (inNewRequest) { | ||
96 | - tabData['id'] = 1; | ||
97 | - paramObj.set('id',''); | ||
98 | - paramObj.set('name', ''); | ||
99 | - paramObj.set('folderId', ''); | ||
100 | - paramObj.set('active-tab-id', 1); | ||
101 | - paramObj.set('last-tab-id', 1); | ||
102 | - paramObj.set('last-plotted-tab', 1); | ||
103 | - paramObj.loadTabs([tabData]); | ||
104 | - myDesktopApp.getLoadedModule(me.get('moduleId'), true, function (module) { | ||
105 | - module.setContextNode(me.parentNode.getRootNode()); | ||
106 | - module.createWindow(function () { | ||
107 | - var uiContent = module.getUiContent(); | ||
108 | - if (uiContent != null) { | ||
109 | - uiContent.resetProcess(paramObj.getJsonValues()); | ||
110 | - } | ||
111 | - }); | ||
112 | - }); | ||
113 | - } | ||
114 | - else { | ||
115 | - myDesktopApp.getLoadedModule(me.get('moduleId'), true, function (module) { | ||
116 | - module.createWindow(function () { | ||
117 | - var uiContent = module.getUiContent(); | ||
118 | - if (uiContent != null) { | ||
119 | - var tabObj = new amdaPlotObj.PlotTabObject(tabData); | ||
120 | - uiContent.insertPlotTab(tabData); | ||
121 | - } | ||
122 | - }); | ||
123 | - }); | ||
124 | - } | ||
125 | - } | ||
126 | - }, me); | ||
127 | - }); | ||
128 | - }, | ||
129 | - | ||
130 | - editPlotTab : function() { | ||
131 | - var me = this; | ||
132 | - this.parentNode.editLeaf(function () { | ||
133 | - myDesktopApp.getLoadedModule(me.get('moduleId'), true, function (module) { | ||
134 | - var uiContent = module.getUiContent(); | ||
135 | - if (uiContent != null) { | ||
136 | - uiContent.forceActiveTab(me.get('tabid')); | ||
137 | - } | ||
138 | - }); | ||
139 | - }); | ||
140 | - }, | ||
141 | - | ||
142 | - renameTab: function() { | ||
143 | - if (this.myGetOwnerTree()) { | ||
144 | - var item = this.myGetOwnerTree().getSelectionModel().selected.items[0]; | ||
145 | - this.myGetOwnerTree().fireEvent('edition', this.myGetOwnerTree().view, item); | ||
146 | - } | ||
147 | - }, | ||
148 | - | ||
149 | - rename: function(value,callBackFn) { | ||
150 | - var me = this; | ||
151 | - var dataToSend = {id : this.get('tabid'), old_name: this.modified.text, name: value, parent : this.data.parentId, leaf: this.isLeaf(), nodeType: this.get('nodeType')}; | ||
152 | - AmdaAction.renameObject(dataToSend, function (result) { | ||
153 | - callBackFn(result); | ||
154 | - myDesktopApp.getLoadedModule(me.get('moduleId'), true, function (module) { | ||
155 | - var uiContent = module.getUiContent(); | ||
156 | - if (uiContent != null) { | ||
157 | - if ((module.linkedNode != null) && (module.linkedNode.get('id') == dataToSend.parent)) { | ||
158 | - uiContent.updatePlotTabName(dataToSend.id, dataToSend.name); | ||
159 | - } | ||
160 | - } | ||
161 | - }); | ||
162 | - }); | ||
163 | - }, | ||
164 | -}); |
js/app/views/ExplorerUI.js
@@ -102,7 +102,6 @@ Ext.define('amdaUI.ExplorerUI', { | @@ -102,7 +102,6 @@ Ext.define('amdaUI.ExplorerUI', { | ||
102 | ITEM_KIND_LEAF : 'leaf', | 102 | ITEM_KIND_LEAF : 'leaf', |
103 | ITEM_KIND_DIRE : 'dire', | 103 | ITEM_KIND_DIRE : 'dire', |
104 | ITEM_KIND_PARA : 'para', | 104 | ITEM_KIND_PARA : 'para', |
105 | - ITEM_KIND_PTAB : 'ptab', //plot tab | ||
106 | ITEM_KIND_MISS : 'miss' | 105 | ITEM_KIND_MISS : 'miss' |
107 | }, | 106 | }, |
108 | 107 | ||
@@ -354,7 +353,6 @@ Ext.define('amdaUI.ExplorerUI', { | @@ -354,7 +353,6 @@ Ext.define('amdaUI.ExplorerUI', { | ||
354 | case 'remoteParam' : | 353 | case 'remoteParam' : |
355 | case 'remoteSimuParam' : | 354 | case 'remoteSimuParam' : |
356 | case 'myData' : | 355 | case 'myData' : |
357 | - case 'plottab' : | ||
358 | return false; | 356 | return false; |
359 | default : | 357 | default : |
360 | if (draggedRecord.data.id == targetNode.data.nodeType+'-treeRootNode') | 358 | if (draggedRecord.data.id == targetNode.data.nodeType+'-treeRootNode') |
@@ -577,7 +575,7 @@ Ext.define('amdaUI.ExplorerUI', { | @@ -577,7 +575,7 @@ Ext.define('amdaUI.ExplorerUI', { | ||
577 | }); | 575 | }); |
578 | } | 576 | } |
579 | 577 | ||
580 | - if (record.isLeaf() || record.data.isParameter || (record.data.tabs && (record.data.tabs.length > 0))) | 578 | + if (record.isLeaf() || record.data.isParameter) |
581 | switch (record.get('nodeType')) | 579 | switch (record.get('nodeType')) |
582 | { | 580 | { |
583 | case 'myData' : | 581 | case 'myData' : |
@@ -591,9 +589,6 @@ Ext.define('amdaUI.ExplorerUI', { | @@ -591,9 +589,6 @@ Ext.define('amdaUI.ExplorerUI', { | ||
591 | case 'condition' : | 589 | case 'condition' : |
592 | record.editLeaf(); | 590 | record.editLeaf(); |
593 | break; | 591 | break; |
594 | - case 'plottab' : | ||
595 | - record.editPlotTab(); | ||
596 | - break; | ||
597 | case 'localParam' : | 592 | case 'localParam' : |
598 | case 'remoteParam': | 593 | case 'remoteParam': |
599 | case 'remoteSimuParam': | 594 | case 'remoteSimuParam': |
@@ -1029,7 +1024,7 @@ Ext.define( 'MyTreeEditor', { | @@ -1029,7 +1024,7 @@ Ext.define( 'MyTreeEditor', { | ||
1029 | event.record.commit(); | 1024 | event.record.commit(); |
1030 | var rec = event.record.data; | 1025 | var rec = event.record.data; |
1031 | // in case of directory | 1026 | // in case of directory |
1032 | - if (!rec.leaf && (rec.nodeType != 'plottab')){ | 1027 | + if (!rec.leaf){ |
1033 | // set folder's ID returned by server | 1028 | // set folder's ID returned by server |
1034 | rec.id = result.id; | 1029 | rec.id = result.id; |
1035 | } | 1030 | } |
js/app/views/IntervalUI.js
@@ -125,6 +125,9 @@ Ext.define('amdaUI.IntervalUI', { | @@ -125,6 +125,9 @@ Ext.define('amdaUI.IntervalUI', { | ||
125 | if (stop != null && start != null) { | 125 | if (stop != null && start != null) { |
126 | if ( stop <= start ) { | 126 | if ( stop <= start ) { |
127 | form.findField('stopDate').markInvalid('Stop Time must be after Start Time'); | 127 | form.findField('stopDate').markInvalid('Stop Time must be after Start Time'); |
128 | + } else { | ||
129 | + if (!form.findField('stopDate').isValid()) | ||
130 | + form.findField('stopDate').clearInvalid(); | ||
128 | } | 131 | } |
129 | // compute offset | 132 | // compute offset |
130 | var zoneOffset = stop.getTimezoneOffset() - start.getTimezoneOffset(); | 133 | var zoneOffset = stop.getTimezoneOffset() - start.getTimezoneOffset(); |
@@ -159,6 +162,21 @@ Ext.define('amdaUI.IntervalUI', { | @@ -159,6 +162,21 @@ Ext.define('amdaUI.IntervalUI', { | ||
159 | ); | 162 | ); |
160 | }, | 163 | }, |
161 | 164 | ||
165 | + isValid: function() { | ||
166 | + var form = this.findParentByType('form').getForm(); | ||
167 | + var startField = form.findField('startDate'); | ||
168 | + var stopField = form.findField('stopDate'); | ||
169 | + if (!startField.isValid() || !stopField.isValid()) | ||
170 | + return false; | ||
171 | + var start = this.getStartTime(); | ||
172 | + var stop = this.getStopTime(); | ||
173 | + if ( stop <= start ) { | ||
174 | + form.findField('stopDate').markInvalid('Stop Time must be after Start Time'); | ||
175 | + return false; | ||
176 | + } | ||
177 | + return true; | ||
178 | + }, | ||
179 | + | ||
162 | updateStop: function() { | 180 | updateStop: function() { |
163 | var form = this.findParentByType('form').getForm(); | 181 | var form = this.findParentByType('form').getForm(); |
164 | var start = form.findField('startDate').getValue(); | 182 | var start = form.findField('startDate').getValue(); |
js/app/views/PlotComponents/PlotElementPanel.js
@@ -10,6 +10,7 @@ | @@ -10,6 +10,7 @@ | ||
10 | 10 | ||
11 | Ext.define('amdaPlotComp.PlotElementPanel', { | 11 | Ext.define('amdaPlotComp.PlotElementPanel', { |
12 | extend: 'Ext.form.Panel', | 12 | extend: 'Ext.form.Panel', |
13 | + | ||
13 | 14 | ||
14 | elementFormsManager : new Ext.AbstractManager(), | 15 | elementFormsManager : new Ext.AbstractManager(), |
15 | 16 |
js/app/views/PlotComponents/PlotExtendShiftPlug.js
@@ -21,7 +21,7 @@ Ext.define('amdaPlotComp.PlotExtendShiftPlug', { | @@ -21,7 +21,7 @@ Ext.define('amdaPlotComp.PlotExtendShiftPlug', { | ||
21 | id: 'plot-extendshift-plug', | 21 | id: 'plot-extendshift-plug', |
22 | win : null, | 22 | win : null, |
23 | form : null, | 23 | form : null, |
24 | - tabId : '', | 24 | + interactiveId : '', |
25 | 25 | ||
26 | constructor: function(config) { | 26 | constructor: function(config) { |
27 | Ext.apply(this, config); | 27 | Ext.apply(this, config); |
@@ -39,7 +39,7 @@ Ext.define('amdaPlotComp.PlotExtendShiftPlug', { | @@ -39,7 +39,7 @@ Ext.define('amdaPlotComp.PlotExtendShiftPlug', { | ||
39 | /** | 39 | /** |
40 | * creation of the window | 40 | * creation of the window |
41 | */ | 41 | */ |
42 | - show : function(tabId) { | 42 | + show : function(interactiveId) { |
43 | if (!this.win) | 43 | if (!this.win) |
44 | { | 44 | { |
45 | this.win = new Ext.Window({ | 45 | this.win = new Ext.Window({ |
@@ -77,7 +77,7 @@ Ext.define('amdaPlotComp.PlotExtendShiftPlug', { | @@ -77,7 +77,7 @@ Ext.define('amdaPlotComp.PlotExtendShiftPlug', { | ||
77 | Ext.PluginManager.register(this); | 77 | Ext.PluginManager.register(this); |
78 | } | 78 | } |
79 | 79 | ||
80 | - this.tabId = tabId; | 80 | + this.interactiveId = interactiveId; |
81 | this.win.show(); | 81 | this.win.show(); |
82 | this.win.setPosition(0,0); | 82 | this.win.setPosition(0,0); |
83 | }, | 83 | }, |
@@ -111,7 +111,7 @@ Ext.define('amdaPlotComp.PlotExtendShiftPlug', { | @@ -111,7 +111,7 @@ Ext.define('amdaPlotComp.PlotExtendShiftPlug', { | ||
111 | var durationUnitField = this.form.getForm().findField('durationUnit'); | 111 | var durationUnitField = this.form.getForm().findField('durationUnit'); |
112 | var duration = this.toSec(durationField.getValue(), durationUnitField.getValue()); | 112 | var duration = this.toSec(durationField.getValue(), durationUnitField.getValue()); |
113 | if (duration) { | 113 | if (duration) { |
114 | - this.hostCmp.callInteractivePlot({'action' : actionType, 'tabId' : this.tabId, 'duration' : duration}); | 114 | + this.hostCmp.callInteractivePlot({'action' : actionType, 'interactiveId' : this.interactiveId, 'duration' : duration}); |
115 | } | 115 | } |
116 | else | 116 | else |
117 | myDesktopApp.errorMsg('No duration defined'); | 117 | myDesktopApp.errorMsg('No duration defined'); |
@@ -190,4 +190,4 @@ Ext.define('amdaPlotComp.PlotExtendShiftPlug', { | @@ -190,4 +190,4 @@ Ext.define('amdaPlotComp.PlotExtendShiftPlug', { | ||
190 | }); | 190 | }); |
191 | return this.form; | 191 | return this.form; |
192 | } | 192 | } |
193 | -}); | ||
194 | \ No newline at end of file | 193 | \ No newline at end of file |
194 | +}); |
js/app/views/PlotComponents/PlotPreviewUI.js
@@ -80,7 +80,7 @@ Ext.define('amdaPlotComp.PlotPreviewUI', { | @@ -80,7 +80,7 @@ Ext.define('amdaPlotComp.PlotPreviewUI', { | ||
80 | var me = this; | 80 | var me = this; |
81 | 81 | ||
82 | this.crtContext = configResult.context; | 82 | this.crtContext = configResult.context; |
83 | - this.tabId = configResult.tabId; | 83 | + this.interactiveId = configResult.interactiveId; |
84 | 84 | ||
85 | this.sliderPage = new Ext.slider.Single({ | 85 | this.sliderPage = new Ext.slider.Single({ |
86 | width: 130, | 86 | width: 130, |
@@ -136,7 +136,7 @@ Ext.define('amdaPlotComp.PlotPreviewUI', { | @@ -136,7 +136,7 @@ Ext.define('amdaPlotComp.PlotPreviewUI', { | ||
136 | me.hiddenForm.getForm().submit({ | 136 | me.hiddenForm.getForm().submit({ |
137 | params: { | 137 | params: { |
138 | sessionId: sessionID, | 138 | sessionId: sessionID, |
139 | - tabId : me.tabId, | 139 | + interactiveId : me.interactiveId, |
140 | preview: true | 140 | preview: true |
141 | }, | 141 | }, |
142 | success: function(form, action) {}, | 142 | success: function(form, action) {}, |
js/app/views/PlotComponents/PlotStandardForm.js
@@ -87,7 +87,6 @@ Ext.define('amdaPlotComp.PlotStandardForm', { | @@ -87,7 +87,6 @@ Ext.define('amdaPlotComp.PlotStandardForm', { | ||
87 | allowBlank = (typeof allowBlank !== 'undefined') ? allowBlank : false; | 87 | allowBlank = (typeof allowBlank !== 'undefined') ? allowBlank : false; |
88 | 88 | ||
89 | return { | 89 | return { |
90 | - id:name, | ||
91 | xtype: 'numberfield', | 90 | xtype: 'numberfield', |
92 | name: name, | 91 | name: name, |
93 | fieldLabel: label, | 92 | fieldLabel: label, |
@@ -112,7 +111,6 @@ Ext.define('amdaPlotComp.PlotStandardForm', { | @@ -112,7 +111,6 @@ Ext.define('amdaPlotComp.PlotStandardForm', { | ||
112 | allowBlank = (typeof allowBlank !== 'undefined') ? allowBlank : false; | 111 | allowBlank = (typeof allowBlank !== 'undefined') ? allowBlank : false; |
113 | 112 | ||
114 | return { | 113 | return { |
115 | - id:name, | ||
116 | xtype: 'textfield', | 114 | xtype: 'textfield', |
117 | name: name, | 115 | name: name, |
118 | fieldLabel: label, | 116 | fieldLabel: label, |
js/app/views/PlotComponents/PlotTabContent.js
@@ -9,86 +9,242 @@ | @@ -9,86 +9,242 @@ | ||
9 | */ | 9 | */ |
10 | 10 | ||
11 | Ext.define('amdaPlotComp.PlotTabContent', { | 11 | Ext.define('amdaPlotComp.PlotTabContent', { |
12 | - extend: 'Ext.form.Panel', | ||
13 | - | ||
14 | - requires: [ | ||
15 | - 'amdaUI.TimeSelectorUI', | ||
16 | - 'amdaPlotComp.PlotTree' | 12 | + extend: 'Ext.form.Panel', |
13 | + | ||
14 | + requires: [ | ||
15 | + 'amdaUI.TimeSelectorUI', | ||
16 | + 'amdaPlotComp.PlotTree', | ||
17 | + 'amdaPlotComp.PlotOutputForm', | ||
18 | + 'amdaPlotComp.PlotElementPanel' | ||
17 | ], | 19 | ], |
18 | 20 | ||
19 | - treePlot: null, | ||
20 | - | ||
21 | - //Link to the Plot Element Panel | ||
22 | - plotElementPanel: null, | ||
23 | - | ||
24 | - //linkk to the Plot Tab Panel | ||
25 | - plotTabPanel : null, | ||
26 | - | ||
27 | - //Link to the time selctor | ||
28 | - timeSelector : null, | ||
29 | - | ||
30 | - //Tab Object | ||
31 | - object: null, | 21 | + //Link to the Plot Node |
22 | + plotNode: null, | ||
23 | + | ||
24 | + //Save initial request data to have the possibility to reject all modifications | ||
25 | + initialObjectData: null, | ||
26 | + | ||
27 | + timeSelector: null, | ||
28 | + plotTree: null, | ||
29 | + plotElement: null, | ||
30 | + plotOutput: null, | ||
31 | + | ||
32 | + tabIndex: 0, | ||
33 | + plotTabPanel: null, | ||
32 | 34 | ||
33 | constructor: function(config) { | 35 | constructor: function(config) { |
34 | this.init(config); | 36 | this.init(config); |
35 | this.callParent(arguments); | 37 | this.callParent(arguments); |
36 | - }, | ||
37 | - | ||
38 | - setTabObject : function(object) { | ||
39 | - this.object = object; | ||
40 | - this.treePlot.buildTree(this.object); | ||
41 | - this.timeSelector.intervalSel.setInterval(this.object.get('startDate'), this.object.get('stopDate')); | ||
42 | - this.addTTs(this.object.get('timeTables')); | ||
43 | - }, | ||
44 | - | ||
45 | - addTTs : function(TTarray) { | ||
46 | - // set TTTab | ||
47 | - this.timeSelector.setTTTab(TTarray); | ||
48 | - }, | ||
49 | - | ||
50 | - updateLinkedToMultiPlotMode : function (isLinkedToMultiPlotMode) { | ||
51 | - this.timeSelector.setVisible(!isLinkedToMultiPlotMode); | ||
52 | - this.plotTabPanel.updateLinkedToMultiPlotMode(isLinkedToMultiPlotMode); | ||
53 | - }, | ||
54 | - | ||
55 | - updateTimeObject : function() { | ||
56 | - var timeSource = this.timeSelector.getActiveTimeSource(); | ||
57 | - var tabForm = this.getForm(); | ||
58 | - tabForm.updateRecord(this.object); | ||
59 | - this.object.set('timesrc', timeSource); | ||
60 | - if (timeSource === amdaModel.AmdaTimeObject.inputTimeSrc[0]) | ||
61 | - this.object.set('timeTables',this.timeSelector.TTGrid.getStore().data.items); | ||
62 | - }, | 38 | + }, |
39 | + | ||
40 | + setTime : function(startDate, stopDate) { | ||
41 | + this.timeSelector.intervalSel.setInterval(startDate, stopDate); | ||
42 | + | ||
43 | + }, | ||
63 | 44 | ||
64 | - init : function(config) { | ||
65 | - var me = this; | ||
66 | - | ||
67 | - this.plotElementPanel = config.plotElementPanel; | ||
68 | - this.plotTabPanel = config.plotTabPanel; | ||
69 | - | ||
70 | - this.timeSelector = new amdaUI.TimeSelectorUI( { id: 'plotTimeSelectorTab' + config.tabId, border : false, flex: 3, collapsible: true, collapseDirection : 'bottom', hidden: true} ); | ||
71 | - this.treePlot = new amdaPlotComp.PlotTree({flex: 5.6, plotElementPanel: this.plotElementPanel, plotTabContent: this}); | ||
72 | - | ||
73 | - var myConf = { | ||
74 | - bodyStyle: { background : '#dfe8f6' }, | ||
75 | - border : false, | ||
76 | - defaults: { | ||
77 | - border: false | ||
78 | - }, | ||
79 | - layout: { | ||
80 | - type: 'vbox', | ||
81 | - pack: 'start', | ||
82 | - align: 'stretch' | ||
83 | - }, | ||
84 | - items: [ | ||
85 | - this.treePlot, | ||
86 | - this.timeSelector | ||
87 | - ] | ||
88 | - }; | 45 | + updateTimeObject : function() { |
46 | + var timeSource = this.timeSelector.getActiveTimeSource(); | ||
47 | + var tabForm = this.getForm(); | ||
48 | + tabForm.updateRecord(this.plotNode.get('object')); | ||
49 | + this.plotNode.get('object').set('timesrc', timeSource); | ||
50 | + if (timeSource === amdaModel.AmdaTimeObject.inputTimeSrc[0]) | ||
51 | + this.plotNode.get('object').set('timeTables',this.timeSelector.TTGrid.getStore().data.items); | ||
52 | + }, | ||
53 | + | ||
54 | + doPlot : function() { | ||
55 | + this.plotNode.get('object').set('tab-index', this.tabIndex); | ||
56 | + this.plotNode.get('object').set('tab-title', this.getPlotTitle()); | ||
57 | + this.plotNode.execute(); | ||
58 | + }, | ||
59 | + | ||
60 | + getPlotTitle: function() { | ||
61 | + return (this.plotNode.get('text') != '') ? this.plotNode.get('text') : 'Plot '+(this.tabIndex + 1); | ||
62 | + }, | ||
63 | + | ||
64 | + savePlot : function() { | ||
65 | + var me = this; | ||
66 | + | ||
67 | + var object = this.plotNode.get('object'); | ||
68 | + if (!object) | ||
69 | + return; | ||
70 | + | ||
71 | + if ((object.get('id') != '') && (this.plotNode.get('text') == object.get('name'))) { | ||
72 | + //update existing request | ||
73 | + this.updateTimeObject(); | ||
74 | + this.plotNode.update({plot: true, callback: function() { | ||
75 | + me.setPlotNode(me.plotNode); //to update initial request data | ||
76 | + me.plotTabPanel.updatePlotTabs(); | ||
77 | + }}); | ||
78 | + return; | ||
79 | + } | ||
80 | + | ||
81 | + //save new request | ||
82 | + this.plotNode.isValidName(object.get('name'), function (res) { | ||
83 | + if (!res) { | ||
84 | + myDesktopApp.errorMsg('Error during object validation'); | ||
85 | + return; | ||
86 | + } | ||
87 | + if (!res.valid) { | ||
88 | + if (res.error) { | ||
89 | + if (res.error.search('subtree') != -1) { | ||
90 | + Ext.Msg.show( { title : 'Warning', | ||
91 | + msg: res.error + '<br/>Do you want to overwrite it?', | ||
92 | + width: 300, | ||
93 | + buttons: Ext.Msg.OKCANCEL, | ||
94 | + icon: Ext.Msg.WARNING, | ||
95 | + fn : function(btn) { | ||
96 | + if (btn == 'cancel') return; | ||
97 | + me.saveProcess(true); | ||
98 | + }, | ||
99 | + scope : me | ||
100 | + }); | ||
101 | + } | ||
102 | + else { | ||
103 | + myDesktopApp.errorMsg(res.error); | ||
104 | + } | ||
105 | + } | ||
106 | + else { | ||
107 | + myDesktopApp.errorMsg('Invalid object name'); | ||
108 | + } | ||
109 | + return; | ||
110 | + } | ||
111 | + me.saveProcess(false); | ||
112 | + }); | ||
113 | + }, | ||
114 | + | ||
115 | + saveProcess : function(toRename) { | ||
116 | + var me = this; | ||
117 | + if (toRename) { | ||
118 | + this.updateTimeObject(); | ||
119 | + this.plotNode.update({plot: true, callback: function() { | ||
120 | + me.setPlotNode(me.plotNode); //to update initial request data | ||
121 | + me.plotTabPanel.updatePlotTabs(); | ||
122 | + }}); | ||
123 | + } | ||
124 | + else { | ||
125 | + if (this.plotNode.get('object').get('id') != '') { | ||
126 | + //Duplicate request | ||
127 | + var plotModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.plot.id); | ||
128 | + if (!plotModule) | ||
129 | + return; | ||
130 | + var newPlotNode = plotModule.linkedNode.get('object').duplicatePlot(this.plotNode); | ||
131 | + if (newPlotNode) { | ||
132 | + //Reject modifications in old plot node | ||
133 | + this.plotNode.reject(); | ||
134 | + this.plotNode.set('object', Ext.create('amdaPlotObj.PlotRequestObject', this.initialObjectData)); | ||
135 | + //Set new plot node | ||
136 | + this.setPlotNode(newPlotNode); | ||
137 | + } | ||
138 | + } | ||
139 | + this.updateTimeObject(); | ||
140 | + this.plotNode.create({callback: function() { | ||
141 | + me.plotNode.commit(); | ||
142 | + me.setPlotNode(me.plotNode); //to update initial request data | ||
143 | + me.plotTabPanel.updatePlotTabs(); | ||
144 | + me.updateUI(); | ||
145 | + }}); | ||
146 | + } | ||
147 | + }, | ||
148 | + | ||
149 | + getDataProcess : function() { | ||
150 | + var downObject = amdaModel.DownloadNode.decodeObject(this.plotNode.get('object')); | ||
151 | + amdaModel.DownloadNode.set('object',Ext.create('amdaModel.Download',downObject)); | ||
152 | + amdaModel.DownloadNode.editInModule(); | ||
153 | + }, | ||
154 | + | ||
155 | + isValidRequest : function(acceptEmptyTTList = true) { | ||
156 | + this.updateTimeObject(); | ||
157 | + if (!this.timeSelector.isValid(acceptEmptyTTList)) { | ||
158 | + myDesktopApp.errorMsg('Error in Time definition'); | ||
159 | + return false; | ||
160 | + } | ||
161 | + return true; | ||
162 | + }, | ||
163 | + | ||
164 | + updateUI : function() { | ||
165 | + this.plotOutput.setObject(this.plotNode.get('object')); | ||
166 | + this.timeSelector.intervalSel.setInterval(this.plotNode.get('object').get('startDate'), this.plotNode.get('object').get('stopDate')); | ||
167 | + this.timeSelector.intervalSel.updateStop(); | ||
168 | + this.timeSelector.setTTTab(this.plotNode.get('object').get('timeTables')); | ||
169 | + this.timeSelector.timeSrc.setActiveTab(this.plotNode.get('object').get('timesrc')); | ||
170 | + this.treePlot.buildTree(this.plotNode.get('object')); | ||
171 | + }, | ||
172 | + | ||
173 | + setPlotNode : function(plotNode) { | ||
174 | + this.initialObjectData = plotNode.get('object').getJsonValues(); | ||
175 | + this.plotNode = plotNode; | ||
176 | + }, | ||
177 | + | ||
178 | + init : function(config) { | ||
179 | + this.setPlotNode(config.plotNode); | ||
180 | + this.tabIndex = config.tabIndex; | ||
181 | + this.plotTabPanel = config.plotTabPanel; | ||
182 | + | ||
183 | + this.timeSelector = new amdaUI.TimeSelectorUI( { id: Ext.id()/*'plotTimeSelectorTab' + this.plotNode.id*/, border : false, flex: 6, collapsible: true, collapseDirection : 'bottom'} ); | ||
184 | + this.plotElement = new amdaPlotComp.PlotElementPanel({flex: 11}); | ||
185 | + this.treePlot = new amdaPlotComp.PlotTree({flex: 11, plotElementPanel: this.plotElement}); | ||
186 | + this.plotOutput = new amdaPlotComp.PlotOutputForm({flex: 6, collapseDirection : 'bottom', collapsible : true }); | ||
187 | + | ||
188 | + var treePanel = new Ext.form.Panel({ | ||
189 | + flex: 1, | ||
190 | + layout: { | ||
191 | + type: 'vbox', | ||
192 | + pack: 'start', | ||
193 | + align: 'stretch' | ||
194 | + }, | ||
195 | + bodyStyle: { background : '#dfe8f6' }, | ||
196 | + defaults: { | ||
197 | + border: false | ||
198 | + }, | ||
199 | + items: [ | ||
200 | + this.treePlot, | ||
201 | + this.timeSelector | ||
202 | + ] | ||
203 | + }); | ||
204 | + | ||
205 | + var optionsPanel = new Ext.form.Panel({ | ||
206 | + flex: 1, | ||
207 | + layout: { | ||
208 | + type: 'vbox', | ||
209 | + pack: 'start', | ||
210 | + align: 'stretch' | ||
211 | + }, | ||
212 | + bodyStyle: { background : '#dfe8f6' }, | ||
213 | + defaults: { | ||
214 | + border: false | ||
215 | + }, | ||
216 | + items: [ | ||
217 | + this.plotElement, | ||
218 | + this.plotOutput | ||
219 | + ] | ||
220 | + }); | ||
221 | + | ||
89 | 222 | ||
90 | - Ext.apply (this , Ext.apply (arguments, myConf)); | 223 | + var myConf = { |
224 | + bodyStyle: { background : '#dfe8f6' }, | ||
225 | + border : false, | ||
226 | + defaults: { | ||
227 | + border: false | ||
228 | + }, | ||
229 | + layout: { | ||
230 | + type: 'hbox', | ||
231 | + pack: 'start', | ||
232 | + align: 'stretch' | ||
233 | + }, | ||
234 | + items: [ | ||
235 | + treePanel, | ||
236 | + optionsPanel | ||
237 | + ], | ||
238 | + listeners: { | ||
239 | + afterrender: function(comp, eOpts) { | ||
240 | + this.updateUI(); | ||
241 | + }, | ||
242 | + scope: this | ||
243 | + } | ||
244 | + }; | ||
245 | + | ||
246 | + Ext.apply (this , Ext.apply (arguments, myConf)); | ||
91 | 247 | ||
92 | 248 | ||
93 | - } | ||
94 | -}); | ||
95 | \ No newline at end of file | 249 | \ No newline at end of file |
250 | + } | ||
251 | +}); |
js/app/views/PlotComponents/PlotTabPanel.js
@@ -9,206 +9,178 @@ | @@ -9,206 +9,178 @@ | ||
9 | */ | 9 | */ |
10 | 10 | ||
11 | Ext.define('amdaPlotComp.PlotTabPanel', { | 11 | Ext.define('amdaPlotComp.PlotTabPanel', { |
12 | - extend: 'Ext.tab.Panel', | 12 | + extend: 'Ext.tab.Panel', |
13 | 13 | ||
14 | - requires: [ | ||
15 | - 'amdaPlotComp.PlotTabContent' | ||
16 | - ], | 14 | + requires: [ |
15 | + 'amdaPlotComp.PlotTabContent' | ||
16 | + ], | ||
17 | 17 | ||
18 | - //Link to the Plot Element Panel | ||
19 | - plotElementPanel: null, | ||
20 | - | ||
21 | //Link to the Plot UI | 18 | //Link to the Plot UI |
22 | plotUI : null, | 19 | plotUI : null, |
23 | 20 | ||
24 | - //Request object | ||
25 | - object: null, | 21 | + //Multiplot object |
22 | + multiplot_object: null, | ||
23 | + | ||
24 | + tabbar_destroy : false, | ||
26 | 25 | ||
27 | - constructor: function(config) { | ||
28 | - this.init(config); | ||
29 | - this.callParent(arguments); | ||
30 | - }, | 26 | + constructor: function(config) { |
27 | + this.init(config); | ||
28 | + this.callParent(arguments); | ||
29 | + }, | ||
31 | 30 | ||
32 | - setRequestObject: function(object) | ||
33 | - { | ||
34 | - var me = this; | ||
35 | - this.removeAll(); | ||
36 | - this.object = object; | 31 | + setMultiplotObject: function(multiplot_object) { |
32 | + var me = this; | ||
33 | + this.removeAll(); | ||
34 | + this.multiplot_object = multiplot_object; | ||
37 | 35 | ||
38 | - var haveSelectedTab = false; | ||
39 | - this.object.tabs().each(function (rec, index) { | ||
40 | - if (rec.get('id') == me.object.get('active-tab-id')) { | ||
41 | - haveSelectedTab = true; | ||
42 | - } | ||
43 | - }); | 36 | + this.multiplot_object.plots().each(function (rec, index) { |
37 | + this.addPlotNode(rec, index == 0); | ||
38 | + }, this); | ||
39 | + }, | ||
44 | 40 | ||
45 | - this.object.tabs().each(function (rec, index) { | ||
46 | - var isSelectedTab = haveSelectedTab ? (rec.get('id') == me.object.get('active-tab-id')) : (index == 0); | ||
47 | - this.addPlotTab(rec, isSelectedTab); | ||
48 | - }, this); | ||
49 | - }, | 41 | + reloadPlot : function(plotNode) { |
42 | + for (i = 0; i < this.items.getCount(); ++i) | ||
43 | + { | ||
44 | + var tabItem = this.items.getAt(i); | ||
45 | + var tabContent = tabItem.items.getAt(0); | ||
46 | + if (plotNode == tabContent.plotNode) { | ||
47 | + tabContent.updateUI(); | ||
48 | + } | ||
49 | + } | ||
50 | + }, | ||
50 | 51 | ||
51 | - addPlotTab: function(tabObject, selectTab) | ||
52 | - { | ||
53 | - var tabNumber = this.getTabBar().items.getCount(); | ||
54 | - var tabContent = new amdaPlotComp.PlotTabContent({plotElementPanel: this.plotElementPanel, plotTabPanel : this, tabId : tabObject.get('id')}); | ||
55 | - tabContent.setTabObject(tabObject); | ||
56 | - var me = this; | ||
57 | - var tabComp = this.add({ | ||
58 | - title: (tabObject.get('tab-name') != '') ? tabObject.get('tab-name') : 'Plot '+tabNumber, | ||
59 | - closable: true, | ||
60 | - layout: 'fit', | ||
61 | - bodyStyle: 'background: none', | ||
62 | - defaults: { | ||
63 | - border: false | ||
64 | - }, | ||
65 | - items: [ | ||
66 | - tabContent | ||
67 | - ], | ||
68 | - listeners : { | ||
69 | - scope : this, | ||
70 | - beforeclose: function( tab, eOpts ) { | ||
71 | - if (this.items.getCount() == 1) | ||
72 | - { | ||
73 | - myDesktopApp.warningMsg('You need to keep at least one plot definition'); | ||
74 | - return false; | ||
75 | - } | ||
76 | - return true; | ||
77 | - }, | ||
78 | - close: function( tab, eOpts ) { | ||
79 | - if (tab.items.getAt(0).object) | ||
80 | - this.object.removeTabById(tab.items.getAt(0).object.get('id')); | ||
81 | - }, | ||
82 | - destroy: function(tab, eOpts) { | ||
83 | - | ||
84 | - this.updatePlotTabs(); | ||
85 | - }, | ||
86 | - afterrender: function(tab, e0pts) { | ||
87 | - if (!tab.tab.el) { | ||
88 | - return; | ||
89 | - } | ||
90 | - tab.tab.el.on('contextmenu', function(e, t, eOpts) { | ||
91 | - var menu = new Ext.menu.Menu({ | ||
92 | - items: [ | ||
93 | - { | ||
94 | - text: 'Rename', | ||
95 | - handler: function() { | ||
96 | - Ext.Msg.prompt('Rename', 'Please enter new plot tab name:', function(btn, text){ | ||
97 | - if (btn == 'ok'){ | ||
98 | - tabObject.set('tab-name',text); | ||
99 | - me.updatePlotTabs(); | ||
100 | - } | ||
101 | - }, me); | ||
102 | - } | ||
103 | - } | ||
104 | - ] | ||
105 | - }); | ||
106 | - var position = e.getXY(); | ||
107 | - e.stopEvent(); | ||
108 | - menu.showAt(position); | ||
109 | - },this); | ||
110 | - } | ||
111 | - } | ||
112 | - }); | 52 | + addPlotNode: function(plotNode, selectTab) |
53 | + { | ||
54 | + for (i = 0; i < this.items.getCount(); ++i) | ||
55 | + { | ||
56 | + var tabItem = this.items.getAt(i); | ||
57 | + var tabContent = tabItem.items.getAt(0); | ||
58 | + if (plotNode == tabContent.plotNode) { | ||
59 | + //Already opened => select tab | ||
60 | + this.setActiveTab(tabItem); | ||
61 | + return; | ||
62 | + } | ||
63 | + } | ||
64 | + | ||
65 | + var tabNumber = this.getTabBar().items.getCount(); | ||
66 | + var tabContent = new amdaPlotComp.PlotTabContent({plotNode: plotNode, tabIndex: tabNumber-1, plotTabPanel: this}); | ||
67 | + var me = this; | ||
68 | + var tabComp = this.add({ | ||
69 | + title: tabContent.getPlotTitle(), | ||
70 | + closable: true, | ||
71 | + layout: 'fit', | ||
72 | + bodyStyle: 'background: none', | ||
73 | + defaults: { | ||
74 | + border: false | ||
75 | + }, | ||
76 | + items: [ | ||
77 | + tabContent | ||
78 | + ], | ||
79 | + listeners : { | ||
80 | + scope : this, | ||
81 | + beforeclose: function( tab, eOpts ) { | ||
82 | + if (this.items.getCount() == 1) | ||
83 | + { | ||
84 | + myDesktopApp.warningMsg('You need to keep at least one plot definition'); | ||
85 | + return false; | ||
86 | + } | ||
87 | + return true; | ||
88 | + }, | ||
89 | + close: function( tab, eOpts ) { | ||
90 | + if (tab.items.getAt(0).plotNode) { | ||
91 | + this.multiplot_object.removePlotByInternalId(tab.items.getAt(0).plotNode.internalId); | ||
92 | + } | ||
93 | + }, | ||
94 | + destroy: function(tab, eOpts) { | ||
95 | + if (!this.tabbar_destroy) | ||
96 | + this.updatePlotTabs(); | ||
97 | + } | ||
98 | + } | ||
99 | + }); | ||
113 | 100 | ||
114 | - if (selectTab) | ||
115 | - this.setActiveTab(tabComp); | 101 | + if (selectTab) |
102 | + this.setActiveTab(tabComp); | ||
116 | 103 | ||
117 | - return tabContent; | ||
118 | - }, | 104 | + return tabContent; |
105 | + }, | ||
119 | 106 | ||
120 | - updatePlotTabs: function() | ||
121 | - { | ||
122 | - var me = this; | ||
123 | - var haveSelectedTab = false; | ||
124 | - this.object.tabs().each(function (rec, index) { | ||
125 | - if (rec.get('id') == me.object.get('active-tab-id')) { | ||
126 | - haveSelectedTab = true; | ||
127 | - } | ||
128 | - }); | 107 | + updatePlotTabs: function() |
108 | + { | ||
109 | + for (i = 0; i < this.items.getCount(); ++i) | ||
110 | + { | ||
111 | + var tabItem = this.items.getAt(i); | ||
112 | + var tabContent = tabItem.items.getAt(0); | ||
113 | + tabContent.tabIndex = i; | ||
114 | + var plotNode = tabContent.plotNode; | ||
115 | + var title = tabContent.getPlotTitle(); | ||
116 | + tabItem.setTitle(title); | ||
117 | + if (!this.getActiveTab()) | ||
118 | + this.setActiveTab(tabItem); | ||
119 | + } | ||
120 | + }, | ||
129 | 121 | ||
130 | - var i = 0; | ||
131 | - for (i = 0; i < this.items.getCount(); ++i) | ||
132 | - { | ||
133 | - var tabItem = this.items.getAt(i); | ||
134 | - var tabContent = tabItem.items.getAt(0); | ||
135 | - var tabObj = this.object.tabs().getById(tabContent.tabId); | ||
136 | - if (!tabObj) { | ||
137 | - continue; | ||
138 | - } | ||
139 | - if (!haveSelectedTab) { | ||
140 | - //Set first tab as the selected one | ||
141 | - this.setActiveTab(tabItem); | ||
142 | - this.object.set('active-tab-id', tabObj.get('id')); | ||
143 | - haveSelectedTab = true; | ||
144 | - } | ||
145 | - var tabNumber = i+1; | ||
146 | - tabItem.setTitle((tabObj.get('tab-name') != '') ? tabObj.get('tab-name') : 'Plot '+tabNumber); | ||
147 | - tabContent.setTabObject(tabObj); | ||
148 | - } | ||
149 | - }, | ||
150 | - | ||
151 | - updateLinkedToMultiPlotMode : function(isLinkedToMultiPlotMode) { | ||
152 | - this.plotUI.updateLinkedToMultiPlotMode(isLinkedToMultiPlotMode); | ||
153 | - }, | ||
154 | - | ||
155 | - updateTimeObject : function() { | ||
156 | - for (i = 0; i < this.items.getCount(); ++i) | ||
157 | - { | ||
158 | - this.items.getAt(i).items.getAt(0).updateTimeObject(); | ||
159 | - } | ||
160 | - }, | 122 | + updateRequestName: function(renamedNode) |
123 | + { | ||
124 | + for (i = 0; i < this.items.getCount(); ++i) | ||
125 | + { | ||
126 | + var tabItem = this.items.getAt(i); | ||
127 | + var tabContent = tabItem.items.getAt(0); | ||
128 | + var plotNode = tabContent.plotNode; | ||
129 | + if (plotNode == renamedNode) { | ||
130 | + plotNode.get('object').set('name', renamedNode.get('text')); | ||
131 | + tabContent.updateUI(); | ||
132 | + } | ||
133 | + } | ||
134 | + }, | ||
135 | + | ||
136 | + getCurrentPlotTabContent : function() { | ||
137 | + if (this.getActiveTab()) | ||
138 | + return this.getActiveTab().child(); | ||
139 | + return null; | ||
140 | + }, | ||
161 | 141 | ||
162 | - getTreeFromPlotTab: function(plotTab) | ||
163 | - { | ||
164 | - return plotTab.child().treePlot; | ||
165 | - }, | 142 | + updateTimeObjects : function() { |
143 | + for (i = 0; i < this.items.getCount(); ++i) | ||
144 | + { | ||
145 | + this.items.getAt(i).items.getAt(0).updateTimeObject(); | ||
146 | + } | ||
147 | + }, | ||
166 | 148 | ||
167 | - getSelectedTabId: function() | ||
168 | - { | ||
169 | - if (this.getActiveTab()) | ||
170 | - return this.getActiveTab().child().tabId; | ||
171 | - return 0; | ||
172 | - }, | 149 | + getTreeFromPlotTab: function(plotTab) |
150 | + { | ||
151 | + return plotTab.child().treePlot; | ||
152 | + }, | ||
173 | 153 | ||
174 | - init : function(config) { | ||
175 | - var me = this; | ||
176 | - | ||
177 | - this.plotElementPanel = config.plotElementPanel; | ||
178 | - this.plotUI = config.plotUI; | ||
179 | - | ||
180 | - var myConf = { | ||
181 | - plain: true, | ||
182 | - bodyStyle: { background : '#dfe8f6' }, | ||
183 | - border : false, | ||
184 | - defaults: { | ||
185 | - border: false | ||
186 | - }, | ||
187 | - tabBar:{ | ||
188 | - items:[ | ||
189 | - { | ||
190 | - text:'+', | ||
191 | - closable: false, | ||
192 | - handler:function(btn,e){ | ||
193 | - var tabContent = me.addPlotTab(me.object.createNewTab(), true); | ||
194 | - } | ||
195 | - }] | ||
196 | - }, | ||
197 | - | ||
198 | - listeners: { | ||
199 | - tabchange: function(tabPanel, newCard, oldCard, eOpts ) { | ||
200 | - var newCardTree = this.getTreeFromPlotTab(newCard); | ||
201 | - var selectedNode = newCardTree.getSelectedNode(); | ||
202 | - if (selectedNode == null) | ||
203 | - me.plotElementPanel.resetElement(); | ||
204 | - else | ||
205 | - me.plotElementPanel.setElement(selectedNode.type,selectedNode.object, newCardTree); | ||
206 | - newCardTree.updateLinkedToMultiPlotMode(); | ||
207 | - }, | ||
208 | - scope: me | ||
209 | - } | ||
210 | - }; | ||
211 | - | ||
212 | - Ext.apply (this , Ext.apply (arguments, myConf)); | ||
213 | - } | 154 | + init : function(config) { |
155 | + var me = this; | ||
156 | + | ||
157 | + this.plotUI = config.plotUI; | ||
158 | + | ||
159 | + var myConf = { | ||
160 | + plain: true, | ||
161 | + bodyStyle: { background : '#dfe8f6' }, | ||
162 | + border : false, | ||
163 | + defaults: { | ||
164 | + border: false | ||
165 | + }, | ||
166 | + tabBar:{ | ||
167 | + items:[ | ||
168 | + { | ||
169 | + text:'+', | ||
170 | + closable: false, | ||
171 | + handler:function(btn,e){ | ||
172 | + var tabContent = me.addPlotNode(me.multiplot_object.createNewPlot(), true); | ||
173 | + } | ||
174 | + } | ||
175 | + ], | ||
176 | + listeners: { | ||
177 | + beforedestroy: function(tabbar, eOpts) { | ||
178 | + me.tabbar_destroy = true; | ||
179 | + } | ||
180 | + } | ||
181 | + } | ||
182 | + }; | ||
183 | + | ||
184 | + Ext.apply (this , Ext.apply (arguments, myConf)); | ||
185 | + } | ||
214 | }); | 186 | }); |
js/app/views/PlotComponents/PlotTree.js
@@ -18,7 +18,6 @@ Ext.define('amdaPlotComp.PlotTree', { | @@ -18,7 +18,6 @@ Ext.define('amdaPlotComp.PlotTree', { | ||
18 | //Link to the combo box to define the use of the simplified view | 18 | //Link to the combo box to define the use of the simplified view |
19 | simplifiedViewCombo : null, | 19 | simplifiedViewCombo : null, |
20 | 20 | ||
21 | - //Link to the combo to attach the tab to the multi plot mode | ||
22 | 21 | ||
23 | //Link to the Plot Element Panel | 22 | //Link to the Plot Element Panel |
24 | plotElementPanel: null, | 23 | plotElementPanel: null, |
@@ -63,7 +62,6 @@ Ext.define('amdaPlotComp.PlotTree', { | @@ -63,7 +62,6 @@ Ext.define('amdaPlotComp.PlotTree', { | ||
63 | this.suspendLayouts(); | 62 | this.suspendLayouts(); |
64 | this.buildPanelsNode(); | 63 | this.buildPanelsNode(); |
65 | this.simplifiedViewCombo.setValue(this.tabObject.get('tree-full-view')); | 64 | this.simplifiedViewCombo.setValue(this.tabObject.get('tree-full-view')); |
66 | - this.linkToMultiPlotCombo.setValue(this.tabObject.get('multi-plot-linked')); | ||
67 | this.resumeLayouts(true); | 65 | this.resumeLayouts(true); |
68 | }, | 66 | }, |
69 | 67 | ||
@@ -853,10 +851,6 @@ Ext.define('amdaPlotComp.PlotTree', { | @@ -853,10 +851,6 @@ Ext.define('amdaPlotComp.PlotTree', { | ||
853 | } | 851 | } |
854 | }, | 852 | }, |
855 | 853 | ||
856 | - updateLinkedToMultiPlotMode : function() { | ||
857 | - this.plotTabContent.updateLinkedToMultiPlotMode(this.tabObject.get('multi-plot-linked')); | ||
858 | - }, | ||
859 | - | ||
860 | init : function(config) { | 854 | init : function(config) { |
861 | var me = this; | 855 | var me = this; |
862 | 856 | ||
@@ -891,21 +885,6 @@ Ext.define('amdaPlotComp.PlotTree', { | @@ -891,21 +885,6 @@ Ext.define('amdaPlotComp.PlotTree', { | ||
891 | } | 885 | } |
892 | }); | 886 | }); |
893 | 887 | ||
894 | - this.linkToMultiPlotCombo = Ext.create('Ext.form.field.Checkbox', { | ||
895 | - xtype: 'checkbox', | ||
896 | - boxLabel: 'Link to MultiPlot', | ||
897 | - listeners: { | ||
898 | - change: function(combo, newValue, oldValue, eOpts) { | ||
899 | - if (this.tabObject) | ||
900 | - { | ||
901 | - this.tabObject.set('multi-plot-linked', newValue); | ||
902 | - this.updateLinkedToMultiPlotMode(); | ||
903 | - } | ||
904 | - }, | ||
905 | - scope: this | ||
906 | - } | ||
907 | - }); | ||
908 | - | ||
909 | var myConf = { | 888 | var myConf = { |
910 | store: store, | 889 | store: store, |
911 | rootVisible: false, | 890 | rootVisible: false, |
@@ -959,8 +938,6 @@ Ext.define('amdaPlotComp.PlotTree', { | @@ -959,8 +938,6 @@ Ext.define('amdaPlotComp.PlotTree', { | ||
959 | scope: this | 938 | scope: this |
960 | }, | 939 | }, |
961 | '-', '->', | 940 | '-', '->', |
962 | - this.linkToMultiPlotCombo, | ||
963 | - ' ', | ||
964 | this.simplifiedViewCombo | 941 | this.simplifiedViewCombo |
965 | ] | 942 | ] |
966 | }; | 943 | }; |
js/app/views/PlotComponents/PlotZoomPlug.js
@@ -26,7 +26,7 @@ Ext.define('amdaPlotComp.PlotZoomPlug', { | @@ -26,7 +26,7 @@ Ext.define('amdaPlotComp.PlotZoomPlug', { | ||
26 | win: null, | 26 | win: null, |
27 | form: null, | 27 | form: null, |
28 | zoomType: '', | 28 | zoomType: '', |
29 | - tabId: '', | 29 | + interactiveId: '', |
30 | panelId: -1, | 30 | panelId: -1, |
31 | 31 | ||
32 | linkedTTCatNode: null, | 32 | linkedTTCatNode: null, |
@@ -101,7 +101,7 @@ Ext.define('amdaPlotComp.PlotZoomPlug', { | @@ -101,7 +101,7 @@ Ext.define('amdaPlotComp.PlotZoomPlug', { | ||
101 | /** | 101 | /** |
102 | * creation of the window | 102 | * creation of the window |
103 | */ | 103 | */ |
104 | - show: function (tabId, zoomType, panelId) { | 104 | + show: function (interactiveId, zoomType, panelId) { |
105 | if (!this.win) { | 105 | if (!this.win) { |
106 | this.win = new Ext.Window({ | 106 | this.win = new Ext.Window({ |
107 | id: 'plot-zoom-win-' + this.hostCmp.ownerCt.getId(), // Plot window ID | 107 | id: 'plot-zoom-win-' + this.hostCmp.ownerCt.getId(), // Plot window ID |
@@ -136,7 +136,7 @@ Ext.define('amdaPlotComp.PlotZoomPlug', { | @@ -136,7 +136,7 @@ Ext.define('amdaPlotComp.PlotZoomPlug', { | ||
136 | Ext.PluginManager.register(this); | 136 | Ext.PluginManager.register(this); |
137 | } | 137 | } |
138 | 138 | ||
139 | - this.tabId = tabId; | 139 | + this.interactiveId = interactiveId; |
140 | this.updateWinByType(zoomType, panelId); | 140 | this.updateWinByType(zoomType, panelId); |
141 | this.win.show(); | 141 | this.win.show(); |
142 | this.win.setPosition(0, 0); | 142 | this.win.setPosition(0, 0); |
@@ -407,7 +407,7 @@ Ext.define('amdaPlotComp.PlotZoomPlug', { | @@ -407,7 +407,7 @@ Ext.define('amdaPlotComp.PlotZoomPlug', { | ||
407 | 407 | ||
408 | this.hostCmp.callInteractivePlot({ | 408 | this.hostCmp.callInteractivePlot({ |
409 | 'action': 'zoom', | 409 | 'action': 'zoom', |
410 | - 'tabId': this.tabId, | 410 | + 'interactiveId': this.interactiveId, |
411 | 'panelId': this.panelId, | 411 | 'panelId': this.panelId, |
412 | 'axeId': this.zoomType, | 412 | 'axeId': this.zoomType, |
413 | 'min': minZoom, | 413 | 'min': minZoom, |
@@ -423,7 +423,7 @@ Ext.define('amdaPlotComp.PlotZoomPlug', { | @@ -423,7 +423,7 @@ Ext.define('amdaPlotComp.PlotZoomPlug', { | ||
423 | handler: function () { | 423 | handler: function () { |
424 | this.hostCmp.callInteractivePlot({ | 424 | this.hostCmp.callInteractivePlot({ |
425 | 'action': 'undozoom', | 425 | 'action': 'undozoom', |
426 | - 'tabId': this.tabId, | 426 | + 'interactiveId': this.interactiveId, |
427 | 'panelId': this.panelId, | 427 | 'panelId': this.panelId, |
428 | 'axeId': this.zoomType | 428 | 'axeId': this.zoomType |
429 | }); | 429 | }); |
js/app/views/PlotTabResultUI.js
@@ -22,8 +22,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -22,8 +22,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
22 | 22 | ||
23 | panelImage : null, | 23 | panelImage : null, |
24 | crtContext : null, | 24 | crtContext : null, |
25 | - tabId : '', | ||
26 | - multiPlotCheck : null, | 25 | + interactiveId : '', |
27 | navToolBar : null, | 26 | navToolBar : null, |
28 | isTTNavBar : false, | 27 | isTTNavBar : false, |
29 | crtTTFileIndex : 0, | 28 | crtTTFileIndex : 0, |
@@ -55,12 +54,6 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -55,12 +54,6 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
55 | return 'data/'+sessionID +'/RES/'+resultFolder+ '/' + plotFile; | 54 | return 'data/'+sessionID +'/RES/'+resultFolder+ '/' + plotFile; |
56 | }, | 55 | }, |
57 | 56 | ||
58 | - getInteractiveMultiPlotState: function() { | ||
59 | - if (!this.multiPlotCheck) | ||
60 | - return false; | ||
61 | - return this.multiPlotCheck.getValue(); | ||
62 | - }, | ||
63 | - | ||
64 | toPixelOnSourceImage : function(value) { | 57 | toPixelOnSourceImage : function(value) { |
65 | return value*100/this.sliderPage.getValue(); | 58 | return value*100/this.sliderPage.getValue(); |
66 | }, | 59 | }, |
@@ -147,7 +140,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -147,7 +140,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
147 | me.contextualMenu.add({ | 140 | me.contextualMenu.add({ |
148 | text:'Zoom on Time Axis', | 141 | text:'Zoom on Time Axis', |
149 | handler : function(item, e) { | 142 | handler : function(item, e) { |
150 | - zoomPlugin.show(me.tabId, axis.id, panelContext.id); | 143 | + zoomPlugin.show(me.interactiveId, axis.id, panelContext.id); |
151 | zoomPlugin.resetMinMaxValue(); | 144 | zoomPlugin.resetMinMaxValue(); |
152 | me.panelImage.startZoom(true, 0/*me.toPixelOnResultImage(panelContext.y)*/, size.height /*me.toPixelOnResultImage(panelContext.height)*/, onMinTimeSelection, onMaxTimeSelection); | 145 | me.panelImage.startZoom(true, 0/*me.toPixelOnResultImage(panelContext.y)*/, size.height /*me.toPixelOnResultImage(panelContext.height)*/, onMinTimeSelection, onMaxTimeSelection); |
153 | }, | 146 | }, |
@@ -156,7 +149,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -156,7 +149,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
156 | insertIntervalItem = { | 149 | insertIntervalItem = { |
157 | text:'Insert Interval in TimeTable or Catalog', | 150 | text:'Insert Interval in TimeTable or Catalog', |
158 | handler : function(item, e) { | 151 | handler : function(item, e) { |
159 | - zoomPlugin.show(me.tabId, axis.id, panelContext.id); | 152 | + zoomPlugin.show(me.interactiveId, axis.id, panelContext.id); |
160 | zoomPlugin.resetMinMaxValue(); | 153 | zoomPlugin.resetMinMaxValue(); |
161 | me.panelImage.startZoom(true, 0/*me.toPixelOnResultImage(panelContext.y)*/, size.height /*me.toPixelOnResultImage(panelContext.height)*/, onMinTimeSelection, onMaxTimeSelection); | 154 | me.panelImage.startZoom(true, 0/*me.toPixelOnResultImage(panelContext.y)*/, size.height /*me.toPixelOnResultImage(panelContext.height)*/, onMinTimeSelection, onMaxTimeSelection); |
162 | }, | 155 | }, |
@@ -167,7 +160,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -167,7 +160,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
167 | me.contextualMenu.add({ | 160 | me.contextualMenu.add({ |
168 | text:'Zoom on Y Left Axis', | 161 | text:'Zoom on Y Left Axis', |
169 | handler : function(item, e) { | 162 | handler : function(item, e) { |
170 | - zoomPlugin.show(me.tabId, axis.id, panelContext.id); | 163 | + zoomPlugin.show(me.interactiveId, axis.id, panelContext.id); |
171 | zoomPlugin.resetMinMaxValue(); | 164 | zoomPlugin.resetMinMaxValue(); |
172 | me.panelImage.startZoom(false, me.toPixelOnResultImage(panelContext.x), me.toPixelOnResultImage(panelContext.width), onMinYValueSelection, onMaxYValueSelection); | 165 | me.panelImage.startZoom(false, me.toPixelOnResultImage(panelContext.x), me.toPixelOnResultImage(panelContext.width), onMinYValueSelection, onMaxYValueSelection); |
173 | } | 166 | } |
@@ -177,7 +170,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -177,7 +170,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
177 | me.contextualMenu.add({ | 170 | me.contextualMenu.add({ |
178 | text:'Zoom on Y Right Axis', | 171 | text:'Zoom on Y Right Axis', |
179 | handler : function(item, e) { | 172 | handler : function(item, e) { |
180 | - zoomPlugin.show(me.tabId, axis.id, panelContext.id); | 173 | + zoomPlugin.show(me.interactiveId, axis.id, panelContext.id); |
181 | zoomPlugin.resetMinMaxValue(); | 174 | zoomPlugin.resetMinMaxValue(); |
182 | me.panelImage.startZoom(false, me.toPixelOnResultImage(panelContext.x), me.toPixelOnResultImage(panelContext.width), onMinYValueSelection, onMaxYValueSelection); | 175 | me.panelImage.startZoom(false, me.toPixelOnResultImage(panelContext.x), me.toPixelOnResultImage(panelContext.width), onMinYValueSelection, onMaxYValueSelection); |
183 | } | 176 | } |
@@ -187,7 +180,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -187,7 +180,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
187 | me.contextualMenu.add({ | 180 | me.contextualMenu.add({ |
188 | text:'Zoom on X Axis', | 181 | text:'Zoom on X Axis', |
189 | handler : function(item, e) { | 182 | handler : function(item, e) { |
190 | - zoomPlugin.show(me.tabId, axis.id, panelContext.id); | 183 | + zoomPlugin.show(me.interactiveId, axis.id, panelContext.id); |
191 | zoomPlugin.resetMinMaxValue(); | 184 | zoomPlugin.resetMinMaxValue(); |
192 | me.panelImage.startZoom(true, me.toPixelOnResultImage(panelContext.y), me.toPixelOnResultImage(panelContext.height), onMinXValueSelection, onMaxXValueSelection); | 185 | me.panelImage.startZoom(true, me.toPixelOnResultImage(panelContext.y), me.toPixelOnResultImage(panelContext.height), onMinXValueSelection, onMaxXValueSelection); |
193 | } | 186 | } |
@@ -205,6 +198,11 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -205,6 +198,11 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
205 | me.contextualMenu.add(insertIntervalItem); | 198 | me.contextualMenu.add(insertIntervalItem); |
206 | } | 199 | } |
207 | }, | 200 | }, |
201 | + | ||
202 | + getAxisValue: function(axis, pixelMin, pixelMax, pixelVal) { | ||
203 | + var val = amdaPlotComp.PlotContextManager.toAxisValue(axis, pixelMin, pixelMax, pixelVal); | ||
204 | + return parseFloat(val).toPrecision(5); | ||
205 | + }, | ||
208 | 206 | ||
209 | createPlotImage: function(resultFolder, plotFile) { | 207 | createPlotImage: function(resultFolder, plotFile) { |
210 | var me = this; | 208 | var me = this; |
@@ -259,16 +257,16 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -259,16 +257,16 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
259 | xText = crtTime.toJSON(); | 257 | xText = crtTime.toJSON(); |
260 | break; | 258 | break; |
261 | case 'y-left' : | 259 | case 'y-left' : |
262 | - yLeftText = parseFloat(amdaPlotComp.PlotContextManager.toAxisValue(axis, panel.plotArea.y+panel.plotArea.height, panel.plotArea.y, sourceYPos).toFixed(2)); | 260 | + yLeftText = me.getAxisValue(axis, panel.plotArea.y+panel.plotArea.height, panel.plotArea.y, sourceYPos); |
263 | break; | 261 | break; |
264 | case 'y-right' : | 262 | case 'y-right' : |
265 | - yRightText = parseFloat(amdaPlotComp.PlotContextManager.toAxisValue(axis, panel.plotArea.y+panel.plotArea.height, panel.plotArea.y, sourceYPos).toFixed(2)); | 263 | + yRightText = me.getAxisValue(axis, panel.plotArea.y+panel.plotArea.height, panel.plotArea.y, sourceYPos); |
266 | break; | 264 | break; |
267 | case 'xaxis_id' : | 265 | case 'xaxis_id' : |
268 | - xText = parseFloat(amdaPlotComp.PlotContextManager.toAxisValue(axis, panel.plotArea.x, panel.plotArea.x+panel.plotArea.width, sourceXPos).toFixed(2)); | 266 | + xText = me.getAxisValue(axis, panel.plotArea.x, panel.plotArea.x+panel.plotArea.width, sourceXPos); |
269 | break; | 267 | break; |
270 | case 'epochAxis' : | 268 | case 'epochAxis' : |
271 | - xText = parseFloat(amdaPlotComp.PlotContextManager.toAxisValue(axis, panel.plotArea.x, panel.plotArea.x+panel.plotArea.width, sourceXPos).toFixed(2)); | 269 | + xText = me.getAxisValue(axis, panel.plotArea.x, panel.plotArea.x+panel.plotArea.width, sourceXPos); |
272 | break; | 270 | break; |
273 | } | 271 | } |
274 | 272 | ||
@@ -312,7 +310,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -312,7 +310,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
312 | var crtTimestamp = amdaPlotComp.PlotContextManager.toAxisValue(timeAxisContext, panel.plotArea.x, panel.plotArea.x+panel.plotArea.width, sourceXPos); | 310 | var crtTimestamp = amdaPlotComp.PlotContextManager.toAxisValue(timeAxisContext, panel.plotArea.x, panel.plotArea.x+panel.plotArea.width, sourceXPos); |
313 | var crtTime = new Date(crtTimestamp*1000); | 311 | var crtTime = new Date(crtTimestamp*1000); |
314 | crtTime = Ext.Date.add(crtTime, Ext.Date.MINUTE, crtTime.getTimezoneOffset()); | 312 | crtTime = Ext.Date.add(crtTime, Ext.Date.MINUTE, crtTime.getTimezoneOffset()); |
315 | - me.callInteractivePlot({'action' : 'instant', 'tabId' : this.tabId, 'panelId' : panel.id, 'time' : crtTime}); | 313 | + me.callInteractivePlot({'action' : 'instant', 'interactiveId' : this.interactiveId, 'panelId' : panel.id, 'time' : crtTime}); |
316 | }, | 314 | }, |
317 | scope: me | 315 | scope: me |
318 | }, | 316 | }, |
@@ -333,7 +331,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -333,7 +331,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
333 | handler : function () | 331 | handler : function () |
334 | { | 332 | { |
335 | var extendShiftPlugin = this.getPlugin('plot-extendshift-plugin-id'); | 333 | var extendShiftPlugin = this.getPlugin('plot-extendshift-plugin-id'); |
336 | - extendShiftPlugin.show(me.tabId); | 334 | + extendShiftPlugin.show(me.interactiveId); |
337 | }, | 335 | }, |
338 | scope: me | 336 | scope: me |
339 | }, | 337 | }, |
@@ -358,7 +356,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -358,7 +356,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
358 | me.hiddenForm.getForm().submit({ | 356 | me.hiddenForm.getForm().submit({ |
359 | params: { | 357 | params: { |
360 | sessionId: sessionID, | 358 | sessionId: sessionID, |
361 | - tabId : me.tabId | 359 | + interactiveId : me.interactiveId |
362 | }, | 360 | }, |
363 | success: function(form, action) {}, | 361 | success: function(form, action) {}, |
364 | failure: function(form, action) {} | 362 | failure: function(form, action) {} |
@@ -388,13 +386,6 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -388,13 +386,6 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
388 | 386 | ||
389 | this.updateTimeTableInfo(); | 387 | this.updateTimeTableInfo(); |
390 | 388 | ||
391 | - if (this.multiPlotCheck) | ||
392 | - { | ||
393 | - this.disableSynchronize = true; | ||
394 | - this.multiPlotCheck.setValue(configResult.multiplot); | ||
395 | - this.disableSynchronize = false; | ||
396 | - } | ||
397 | - | ||
398 | this.panelImage.setSrc(this.getImageUrl(configResult.folder, configResult.plotFile)); | 389 | this.panelImage.setSrc(this.getImageUrl(configResult.folder, configResult.plotFile)); |
399 | 390 | ||
400 | var size = this.getImageSize(); | 391 | var size = this.getImageSize(); |
@@ -408,15 +399,15 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -408,15 +399,15 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
408 | if (!this.navToolBar) | 399 | if (!this.navToolBar) |
409 | return; | 400 | return; |
410 | 401 | ||
411 | - var ttNameField = this.navToolBar.items.get('tt-table-'+this.tabId); | 402 | + var ttNameField = this.navToolBar.items.get('tt-table-'+this.interactiveId); |
412 | if (ttNameField) | 403 | if (ttNameField) |
413 | ttNameField.setValue(this.crtContext.page.ttName); | 404 | ttNameField.setValue(this.crtContext.page.ttName); |
414 | 405 | ||
415 | - var ttNumberField = this.navToolBar.items.get('tt-number-'+this.tabId); | 406 | + var ttNumberField = this.navToolBar.items.get('tt-number-'+this.interactiveId); |
416 | if (ttNumberField) | 407 | if (ttNumberField) |
417 | ttNumberField.setValue(this.crtContext.page.ttIndex + 1); | 408 | ttNumberField.setValue(this.crtContext.page.ttIndex + 1); |
418 | 409 | ||
419 | - var ttTotalField = this.navToolBar.items.get('tt-total-'+this.tabId); | 410 | + var ttTotalField = this.navToolBar.items.get('tt-total-'+this.interactiveId); |
420 | if (ttTotalField) | 411 | if (ttTotalField) |
421 | ttTotalField.setValue(this.crtContext.page.ttNbIntervals); | 412 | ttTotalField.setValue(this.crtContext.page.ttNbIntervals); |
422 | }, | 413 | }, |
@@ -425,9 +416,8 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -425,9 +416,8 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
425 | loadMask.show(true); | 416 | loadMask.show(true); |
426 | 417 | ||
427 | var plotModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.plot.id); | 418 | var plotModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.plot.id); |
428 | - var multiPlotState = plotModule.getInteractiveMultiPlotState(); | ||
429 | 419 | ||
430 | - AmdaAction.interactivePlot(obj, multiPlotState, function (result, e) { | 420 | + AmdaAction.interactivePlot(obj, function (result, e) { |
431 | loadMask.hide(); | 421 | loadMask.hide(); |
432 | var t = e.getTransaction(); | 422 | var t = e.getTransaction(); |
433 | if (e.status) | 423 | if (e.status) |
@@ -456,28 +446,12 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -456,28 +446,12 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
456 | if (this.navToolBar) | 446 | if (this.navToolBar) |
457 | this.navToolBar.removeAll(true); | 447 | this.navToolBar.removeAll(true); |
458 | 448 | ||
459 | - this.multiPlotCheck = Ext.create('Ext.form.field.Checkbox', { | ||
460 | - boxLabel : 'Linked to Multi Plot', | ||
461 | - scope: this, | ||
462 | - handler: function(check, checked) { | ||
463 | - if (!this.disableSynchronize) | ||
464 | - this.callInteractivePlot({'action' : 'synchronize', 'tabId' : this.tabId}); | ||
465 | - }, | ||
466 | - scope: this | ||
467 | - }); | ||
468 | - | ||
469 | var commonItemsCfg = [ | 449 | var commonItemsCfg = [ |
470 | '-', | 450 | '-', |
471 | { | 451 | { |
472 | xtype: 'tbspacer', | 452 | xtype: 'tbspacer', |
473 | width: 20 | 453 | width: 20 |
474 | }, | 454 | }, |
475 | - this.multiPlotCheck, | ||
476 | - { | ||
477 | - xtype: 'tbspacer', | ||
478 | - width: 2 | ||
479 | - }, | ||
480 | - '-', | ||
481 | '->', | 455 | '->', |
482 | { | 456 | { |
483 | text: 'Get HST Data', | 457 | text: 'Get HST Data', |
@@ -515,7 +489,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -515,7 +489,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
515 | } | 489 | } |
516 | else | 490 | else |
517 | --ttintervalIndex; | 491 | --ttintervalIndex; |
518 | - this.callInteractivePlot({'action' : 'goto', 'tabId' : this.tabId, 'ttFileIndex' : ttFileIndex, 'intIndex' : ttintervalIndex}); | 492 | + this.callInteractivePlot({'action' : 'goto', 'interactiveId' : this.interactiveId, 'ttFileIndex' : ttFileIndex, 'intIndex' : ttintervalIndex}); |
519 | } | 493 | } |
520 | }, | 494 | }, |
521 | '-', | 495 | '-', |
@@ -534,7 +508,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -534,7 +508,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
534 | else | 508 | else |
535 | ++ttintervalIndex; | 509 | ++ttintervalIndex; |
536 | 510 | ||
537 | - this.callInteractivePlot({'action' : 'goto', 'tabId' : this.tabId, 'ttFileIndex' : ttFileIndex, 'intIndex' : ttintervalIndex}); | 511 | + this.callInteractivePlot({'action' : 'goto', 'interactiveId' : this.interactiveId, 'ttFileIndex' : ttFileIndex, 'intIndex' : ttintervalIndex}); |
538 | } | 512 | } |
539 | }, | 513 | }, |
540 | '-', | 514 | '-', |
@@ -542,17 +516,17 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -542,17 +516,17 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
542 | text: 'Go to Interval #', | 516 | text: 'Go to Interval #', |
543 | scope: this, | 517 | scope: this, |
544 | handler: function(bt){ | 518 | handler: function(bt){ |
545 | - var ttGotoNumberField = this.navToolBar.items.get('tt-goto-number-'+this.tabId); | 519 | + var ttGotoNumberField = this.navToolBar.items.get('tt-goto-number-'+this.interactiveId); |
546 | var goToIndex = ttGotoNumberField.getValue() - 1; | 520 | var goToIndex = ttGotoNumberField.getValue() - 1; |
547 | if ((goToIndex < 0) || (goToIndex >= this.crtContext.page.ttNbIntervals)) | 521 | if ((goToIndex < 0) || (goToIndex >= this.crtContext.page.ttNbIntervals)) |
548 | myDesktopApp.errorMsg('This interval number is outside of the current timeTable'); | 522 | myDesktopApp.errorMsg('This interval number is outside of the current timeTable'); |
549 | else | 523 | else |
550 | - this.callInteractivePlot({'action' : 'goto', 'tabId' : this.tabId, 'ttFileIndex' : this.crtTTFileIndex, 'intIndex' : goToIndex}); | 524 | + this.callInteractivePlot({'action' : 'goto', 'interactiveId' : this.interactiveId, 'ttFileIndex' : this.crtTTFileIndex, 'intIndex' : goToIndex}); |
551 | } | 525 | } |
552 | }, | 526 | }, |
553 | { | 527 | { |
554 | xtype: 'numberfield', | 528 | xtype: 'numberfield', |
555 | - id : 'tt-goto-number-'+this.tabId, | 529 | + id : 'tt-goto-number-'+this.interactiveId, |
556 | hideTrigger: true, | 530 | hideTrigger: true, |
557 | width: 50, | 531 | width: 50, |
558 | minValue: 1 | 532 | minValue: 1 |
@@ -562,7 +536,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -562,7 +536,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
562 | ' ', | 536 | ' ', |
563 | { | 537 | { |
564 | xtype: 'textfield', | 538 | xtype: 'textfield', |
565 | - id: 'tt-table-'+this.tabId, | 539 | + id: 'tt-table-'+this.interactiveId, |
566 | labelAlign: 'right', | 540 | labelAlign: 'right', |
567 | labelWidth: 30, | 541 | labelWidth: 30, |
568 | fieldLabel: 'Table', | 542 | fieldLabel: 'Table', |
@@ -571,7 +545,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -571,7 +545,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
571 | }, | 545 | }, |
572 | { | 546 | { |
573 | xtype: 'textfield', | 547 | xtype: 'textfield', |
574 | - id: 'tt-number-'+this.tabId, | 548 | + id: 'tt-number-'+this.interactiveId, |
575 | labelAlign: 'right', | 549 | labelAlign: 'right', |
576 | labelWidth: 30, | 550 | labelWidth: 30, |
577 | fieldLabel: 'Int #', | 551 | fieldLabel: 'Int #', |
@@ -580,7 +554,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -580,7 +554,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
580 | }, | 554 | }, |
581 | { | 555 | { |
582 | xtype: 'textfield', | 556 | xtype: 'textfield', |
583 | - id: 'tt-total-'+this.tabId, | 557 | + id: 'tt-total-'+this.interactiveId, |
584 | labelAlign: 'right', | 558 | labelAlign: 'right', |
585 | labelWidth: 30, | 559 | labelWidth: 30, |
586 | fieldLabel: 'Total', | 560 | fieldLabel: 'Total', |
@@ -595,7 +569,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -595,7 +569,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
595 | text: 'Backward', | 569 | text: 'Backward', |
596 | scope: this, | 570 | scope: this, |
597 | handler: function(){ | 571 | handler: function(){ |
598 | - this.callInteractivePlot({'action' : 'backward', 'tabId' : this.tabId}); | 572 | + this.callInteractivePlot({'action' : 'backward', 'interactiveId' : this.interactiveId}); |
599 | } | 573 | } |
600 | }, | 574 | }, |
601 | '-', | 575 | '-', |
@@ -603,7 +577,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -603,7 +577,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
603 | text: '1/2 Backward', | 577 | text: '1/2 Backward', |
604 | scope: this, | 578 | scope: this, |
605 | handler: function(){ | 579 | handler: function(){ |
606 | - this.callInteractivePlot({'action' : 'halfbackward', 'tabId' : this.tabId}); | 580 | + this.callInteractivePlot({'action' : 'halfbackward', 'interactiveId' : this.interactiveId}); |
607 | } | 581 | } |
608 | }, | 582 | }, |
609 | '-', | 583 | '-', |
@@ -611,7 +585,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -611,7 +585,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
611 | text: '1/2 Forward', | 585 | text: '1/2 Forward', |
612 | scope: this, | 586 | scope: this, |
613 | handler: function(){ | 587 | handler: function(){ |
614 | - this.callInteractivePlot({'action' : 'halfforward', 'tabId' : this.tabId}); | 588 | + this.callInteractivePlot({'action' : 'halfforward', 'interactiveId' : this.interactiveId}); |
615 | } | 589 | } |
616 | }, | 590 | }, |
617 | '-', | 591 | '-', |
@@ -619,7 +593,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -619,7 +593,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
619 | text: 'Forward', | 593 | text: 'Forward', |
620 | scope: this, | 594 | scope: this, |
621 | handler: function(){ | 595 | handler: function(){ |
622 | - this.callInteractivePlot({'action' : 'forward', 'tabId' : this.tabId}); | 596 | + this.callInteractivePlot({'action' : 'forward', 'interactiveId' : this.interactiveId}); |
623 | } | 597 | } |
624 | }]; | 598 | }]; |
625 | } | 599 | } |
@@ -649,7 +623,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -649,7 +623,7 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
649 | 623 | ||
650 | init: function(configResult){ | 624 | init: function(configResult){ |
651 | this.crtContext = configResult.context; | 625 | this.crtContext = configResult.context; |
652 | - this.tabId = configResult.tabId; | 626 | + this.interactiveId = configResult.interactiveId; |
653 | 627 | ||
654 | this.coordinatesField = new Ext.toolbar.TextItem({ | 628 | this.coordinatesField = new Ext.toolbar.TextItem({ |
655 | width: 300, | 629 | width: 300, |
@@ -700,13 +674,6 @@ Ext.define('amdaUI.PlotTabResultUI', { | @@ -700,13 +674,6 @@ Ext.define('amdaUI.PlotTabResultUI', { | ||
700 | 674 | ||
701 | this.updateTimeTableInfo(); | 675 | this.updateTimeTableInfo(); |
702 | 676 | ||
703 | - if (this.multiPlotCheck) | ||
704 | - { | ||
705 | - this.disableSynchronize = true; | ||
706 | - this.multiPlotCheck.setValue(configResult.multiplot); | ||
707 | - this.disableSynchronize = false; | ||
708 | - } | ||
709 | - | ||
710 | var plotResultTabPanelConfig = { | 677 | var plotResultTabPanelConfig = { |
711 | preventHeader : true, | 678 | preventHeader : true, |
712 | autoScroll: true, | 679 | autoScroll: true, |
js/app/views/PlotUI.js
@@ -10,454 +10,210 @@ | @@ -10,454 +10,210 @@ | ||
10 | 10 | ||
11 | 11 | ||
12 | Ext.define('amdaUI.PlotUI', { | 12 | Ext.define('amdaUI.PlotUI', { |
13 | - extend: 'Ext.container.Container', | ||
14 | - alias: 'widget.newPanelPlot', | 13 | + extend: 'Ext.container.Container', |
14 | + alias: 'widget.newPanelPlot', | ||
15 | 15 | ||
16 | - requires: [ | ||
17 | - 'amdaModel.DownloadNode', | ||
18 | - 'amdaModel.Download', | ||
19 | - 'amdaUI.TimeSelectorUI', | ||
20 | - 'amdaPlotComp.PlotTabPanel', | ||
21 | - 'amdaPlotComp.PlotOutputForm', | ||
22 | - 'amdaPlotComp.PlotElementPanel' | 16 | + requires: [ |
17 | + 'amdaModel.DownloadNode', | ||
18 | + 'amdaModel.Download', | ||
19 | + 'amdaPlotComp.PlotTabPanel' | ||
23 | ], | 20 | ], |
24 | 21 | ||
25 | - formPanel: null, | ||
26 | - | ||
27 | - multiPlotIntervalPanel : null, | ||
28 | - | ||
29 | - plotOutput: null, | ||
30 | - | ||
31 | - plotTabs : null, | ||
32 | - | ||
33 | - plotElement : null, | ||
34 | - | ||
35 | - constructor: function(config) { | ||
36 | - this.init(config); | ||
37 | - this.callParent(arguments); | ||
38 | - if (this.object) | ||
39 | - this.setObject(this.object); | ||
40 | - }, | ||
41 | - | ||
42 | - setObject : function(object) { | ||
43 | - this.object = object; | ||
44 | - this.plotOutput.setObject(this.object); | ||
45 | - this.plotTabs.setRequestObject(this.object); | ||
46 | - this.timeSelector.intervalSel.setInterval(this.object.get('startDate'), this.object.get('stopDate')); | ||
47 | - this.addTTs(this.object.get('timeTables')); | ||
48 | - }, | ||
49 | - | ||
50 | - /** | ||
51 | - * overwrite metod called by Save button | ||
52 | - */ | ||
53 | - overwriteProcess : function(btn) | ||
54 | - { | ||
55 | - if (btn == 'cancel') return; | ||
56 | - | ||
57 | - this.saveProcess(true); | ||
58 | - }, | ||
59 | - | ||
60 | - | ||
61 | - /** | ||
62 | - * save method called by Save button to launch the save process | ||
63 | - */ | ||
64 | - saveProcess : function(toRename) { | ||
65 | - var plotModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.plot.id); | ||
66 | - if (!plotModule) | ||
67 | - return; | ||
68 | - | ||
69 | - if (toRename) { | ||
70 | - plotModule.linkedNode.set('object',this.object); | ||
71 | - plotModule.linkedNode.update(); | ||
72 | - } | ||
73 | - else { | ||
74 | - //Save | ||
75 | - if (this.object.get('id') != '') { | ||
76 | - //Duplicate request | ||
77 | - plotModule.createLinkedNode(); | ||
78 | - plotModule.linkedNode.set('object',this.object); | ||
79 | - } | ||
80 | - plotModule.linkedNode.create(); | ||
81 | - } | ||
82 | - }, | 22 | + formPanel: null, |
23 | + plotTabs : null, | ||
24 | + | ||
25 | + constructor: function(config) { | ||
26 | + this.init(config); | ||
27 | + this.callParent(arguments); | ||
28 | + if (this.object) | ||
29 | + this.setObject(this.object); | ||
30 | + }, | ||
31 | + | ||
32 | + setObject : function(object) { | ||
33 | + this.object = object; | ||
34 | + if (this.object.plots().count() == 0) { | ||
35 | + this.object.createNewPlot(); | ||
36 | + } | ||
37 | + this.plotTabs.setMultiplotObject(this.object); | ||
38 | + }, | ||
39 | + | ||
40 | + resetProcess : function(){ | ||
41 | + var plotModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.plot.id); | ||
42 | + plotModule.createLinkedNode(); | ||
43 | + var obj = null; | ||
44 | + if ((arguments.length > 0) && (arguments[0] != null)) { | ||
45 | + obj = arguments[0]; | ||
46 | + } | ||
47 | + plotModule.createObject(obj); | ||
48 | + this.setObject(plotModule.linkedNode.get('object')); | ||
49 | + }, | ||
50 | + | ||
51 | + getDataProcess : function(){ | ||
52 | + if ( this.updateObject() ) { | ||
53 | + var plotTab = this.plotTabs.getCurrentPlotTabContent(); | ||
54 | + if (!plotTab || !plotTab.plotNode) | ||
55 | + return; | ||
56 | + plotTab.getDataProcess(); | ||
57 | + } | ||
58 | + }, | ||
83 | 59 | ||
84 | - resetProcess : function(){ | ||
85 | - var plotModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.plot.id); | ||
86 | - plotModule.createLinkedNode(); | ||
87 | - var obj = null; | ||
88 | - if ((arguments.length > 0) && (arguments[0] != null)) { | ||
89 | - obj = arguments[0]; | ||
90 | - } | ||
91 | - plotModule.createObject(obj); | ||
92 | - this.setObject(plotModule.linkedNode.get('object')); | ||
93 | - }, | ||
94 | - | ||
95 | - getDataProcess : function(){ | ||
96 | - this.updateObject(); | ||
97 | - // plot was not called - form only | ||
98 | - if (this.object.get('last-plotted-tab') == 0) { | ||
99 | - this.object.set('last-plotted-tab', this.plotTabs.getSelectedTabId()); | ||
100 | - } | ||
101 | - var downObject = amdaModel.DownloadNode.decodeObject(this.object); | ||
102 | - amdaModel.DownloadNode.set('object',Ext.create('amdaModel.Download',downObject)); | ||
103 | - | ||
104 | - amdaModel.DownloadNode.editInModule(); | ||
105 | - }, | ||
106 | - | ||
107 | - addParameter : function(node){ | ||
108 | - var crtTree = this.plotTabs.getTreeFromPlotTab(this.plotTabs.getActiveTab()); | ||
109 | - crtTree.dropRecord(node,null,'append'); | ||
110 | - }, | 60 | + addParameter : function(node, updateTime){ |
61 | + var crtTree = this.plotTabs.getTreeFromPlotTab(this.plotTabs.getActiveTab()); | ||
62 | + if (crtTree) { | ||
63 | + crtTree.dropRecord(node,null,'append'); | ||
64 | + if (updateTime) { | ||
65 | + if((node.get('globalStart') != null) && (node.get('globalStop') != null) && node.get('globalStart') != 'depending on mission' && node.get('isParameter')) { | ||
66 | + this.setTimeFromData(node.getTimeFromNode(node)); | ||
67 | + } | ||
68 | + } | ||
69 | + } | ||
70 | + }, | ||
71 | + | ||
72 | + editPlot : function(plotNode) { | ||
73 | + this.plotTabs.addPlotNode(plotNode, true); | ||
74 | + }, | ||
75 | + | ||
76 | + reloadPlot : function(plotNode) { | ||
77 | + this.plotTabs.reloadPlot(plotNode); | ||
78 | + }, | ||
111 | 79 | ||
112 | - /** | 80 | + /** |
113 | * plot method called by 'Do Plot' button to launch the plot process | 81 | * plot method called by 'Do Plot' button to launch the plot process |
114 | */ | 82 | */ |
115 | - doPlot : function(){ | ||
116 | - | ||
117 | - this.updateObject(); | ||
118 | - this.object.set('last-plotted-tab', this.plotTabs.getSelectedTabId()); | ||
119 | - var plotModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.plot.id); | ||
120 | - if (plotModule) | ||
121 | - plotModule.linkedNode.execute(); | ||
122 | - }, | ||
123 | - | ||
124 | - /** | ||
125 | - * Check if changes were made before closing window | ||
126 | - * @return false | ||
127 | - */ | ||
128 | - fclose : function() { | ||
129 | - var module = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.plot.id); | ||
130 | - if (module) | ||
131 | - module.closeInteractiveSession(); | ||
132 | - | ||
133 | - return this.object.isDirty(); | ||
134 | - }, | ||
135 | - | ||
136 | - /** | ||
137 | - * update time selector of this.object from form | ||
138 | - */ | ||
139 | - updateObject : function(){ | ||
140 | - var timeSource = this.timeSelector.getActiveTimeSource(); | ||
141 | - | ||
142 | - var multiPlotForm = this.timeSelector.getForm(); | ||
143 | - multiPlotForm.updateRecord(this.object); | ||
144 | - this.object.set('timesrc', timeSource); | ||
145 | - if (timeSource === amdaModel.AmdaTimeObject.inputTimeSrc[0]) | ||
146 | - this.object.set('timeTables',this.timeSelector.TTGrid.getStore().data.items); | ||
147 | - this.plotTabs.updateTimeObject(); | ||
148 | - }, | ||
149 | - | ||
150 | - addTT : function(newTTName,newTTid,timeSelectorId) { | ||
151 | - var crtTimeSelector = Ext.getCmp(timeSelectorId); | ||
152 | - if (crtTimeSelector) | ||
153 | - crtTimeSelector.addTT(newTTName,newTTid); | ||
154 | - }, | ||
155 | - | ||
156 | - addTTs : function(TTarray) { | ||
157 | - // set TTTab | ||
158 | - this.timeSelector.setTTTab(TTarray); | ||
159 | - }, | ||
160 | - | ||
161 | - /** | ||
162 | - * Set Start-Stop from parameter info (Local & MyData) | ||
163 | - */ | ||
164 | - setTimeFromData : function(obj) { | ||
165 | - if (!obj.start || !obj.stop) | ||
166 | - return; | ||
167 | - var dateStart = new Date(obj.start.replace(/[T|Z]/g,' ').replace(/\-/g,'\/')); | ||
168 | - var dateStop = new Date(obj.stop.replace(/[T|Z]/g,' ').replace(/\-/g,'\/')); | ||
169 | - | ||
170 | - for (var i = 0; i < this.plotTabs.items.getCount(); ++i) { | ||
171 | - var plotTab = this.plotTabs.items.getAt(i).items.getAt(0); | ||
172 | - plotTab.items.getAt(1).intervalSel.setInterval(dateStart, dateStop); | ||
173 | - //TBD plotTab.updateTimeObject(); | ||
174 | - } | ||
175 | - | ||
176 | - this.timeSelector.intervalSel.setInterval(dateStart, dateStop); | ||
177 | - }, | ||
178 | - | ||
179 | - forceActiveTab : function(tabId) { | ||
180 | - for (var i = 0; i < this.plotTabs.items.getCount(); ++i) { | ||
181 | - var plotTab = this.plotTabs.items.getAt(i).items.getAt(0); | ||
182 | - if (plotTab.tabId == tabId) { | ||
183 | - this.plotTabs.setActiveTab(i); | ||
184 | - return; | ||
185 | - } | ||
186 | - } | ||
187 | - }, | ||
188 | - | ||
189 | - updatePlotTabName: function(tabId, name) { | ||
190 | - var me = this; | ||
191 | - this.object.tabs().each(function (tabObject) { | ||
192 | - if (tabId == tabObject.getId()) { | ||
193 | - tabObject.set('tab-name', name); | ||
194 | - me.plotTabs.updatePlotTabs(); | ||
195 | - } | ||
196 | - }); | ||
197 | - }, | ||
198 | - | ||
199 | - insertPlotTab : function(tabData) { | ||
200 | - var newTab = this.object.createNewTab(tabData); | ||
201 | - this.plotTabs.addPlotTab(newTab,true); | ||
202 | - }, | ||
203 | - | ||
204 | - updateLinkedToMultiPlotMode : function(isLinkedToMultiPlotMode) { | ||
205 | - this.timeSelector.setVisible(isLinkedToMultiPlotMode); | ||
206 | - }, | ||
207 | - | ||
208 | - keepOnlySelectedTabInObject: function(showWarning, onSuccess) { | ||
209 | - if (this.object.tabs().count() == 1) { | ||
210 | - if (onSuccess) { | ||
211 | - onSuccess(); | ||
212 | - } | ||
213 | - return; | ||
214 | - } | ||
215 | - | ||
216 | - var me = this; | ||
217 | - var removeFunc = function() { | ||
218 | - var tabsToRemove = []; | ||
219 | - var selectedTabFound = false; | ||
220 | - me.object.tabs().each(function(tab) { | ||
221 | - if (tab.get('id') != me.object.get('active-tab-id')) { | ||
222 | - tabsToRemove.push(tab); | ||
223 | - } | ||
224 | - else { | ||
225 | - selectedTabFound = true; | ||
226 | - } | ||
227 | - }); | ||
228 | - if (!selectedTabFound) { | ||
229 | - myDesktopApp.errorMsg('Cannot retrieve selected tab'); | ||
230 | - return false; | ||
231 | - } | ||
232 | - if (tabsToRemove.length > 0) { | ||
233 | - me.object.tabs().remove(tabsToRemove); | ||
234 | - } | ||
235 | - return true; | ||
236 | - }; | ||
237 | - | ||
238 | - if (!showWarning) { | ||
239 | - if (removeFunc()) { | ||
240 | - if (onSuccess) { | ||
241 | - onSuccess(); | ||
242 | - } | ||
243 | - } | ||
244 | - return; | ||
245 | - } | ||
246 | - | ||
247 | - | ||
248 | - Ext.Msg.show( { title : 'Warning', | ||
249 | - msg: 'Active plot will be saved, but other ones will be lost.<br/>Do you want to continue?', | ||
250 | - width: 300, | ||
251 | - buttons: Ext.Msg.OKCANCEL, | ||
252 | - fn: function(btn) { | ||
253 | - if (btn == 'cancel') return; | ||
254 | - | ||
255 | - if (removeFunc()) { | ||
256 | - if (onSuccess) { | ||
257 | - onSuccess(); | ||
258 | - } | ||
259 | - } | ||
260 | - return; | ||
261 | - }, | ||
262 | - scope: me | ||
263 | - }); | ||
264 | - }, | ||
265 | - | ||
266 | - savePlotRequest : function(allTabs) { | ||
267 | - var plotModule = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.plot.id); | ||
268 | - if (!plotModule) | ||
269 | - return; | ||
270 | - this.updateObject(); | ||
271 | - this.object.set('active-tab-id', this.plotTabs.getSelectedTabId()); | ||
272 | - var me = this; | ||
273 | - | ||
274 | - if ((this.object.get('id') != '') && (plotModule.linkedNode.get('text') == this.object.get('name'))) { | ||
275 | - //update existing request | ||
276 | - if (!allTabs) { | ||
277 | - this.keepOnlySelectedTabInObject(true, function() { | ||
278 | - plotModule.linkedNode.update(); | ||
279 | - }); | ||
280 | - } | ||
281 | - else { | ||
282 | - plotModule.linkedNode.update(); | ||
283 | - } | ||
284 | - return; | ||
285 | - } | ||
286 | - | ||
287 | - //save new request | ||
288 | - var me = this; | ||
289 | - plotModule.linkedNode.isValidName(this.object.get('name'), function (res) { | ||
290 | - if (!res) { | ||
291 | - myDesktopApp.errorMsg('Error during object validation'); | ||
292 | - return; | ||
293 | - } | ||
294 | - if (!res.valid) { | ||
295 | - if (res.error) { | ||
296 | - if (res.error.search('subtree') != -1) { | ||
297 | - Ext.Msg.show( { title : 'Warning', | ||
298 | - msg: res.error + '<br/>Do you want to overwrite it?', | ||
299 | - width: 300, | ||
300 | - buttons: Ext.Msg.OKCANCEL, | ||
301 | - icon: Ext.Msg.WARNING, | ||
302 | - fn : me.overwriteProcess, | ||
303 | - scope : me | ||
304 | - }); | ||
305 | - } | ||
306 | - else { | ||
307 | - myDesktopApp.errorMsg(res.error); | ||
308 | - } | ||
309 | - } | ||
310 | - else { | ||
311 | - myDesktopApp.errorMsg('Invalid object name'); | ||
312 | - } | ||
313 | - return; | ||
314 | - } | ||
315 | - if (!allTabs) { | ||
316 | - me.keepOnlySelectedTabInObject((me.object.get('id') == ''), function() { | ||
317 | - me.saveProcess(false); | ||
318 | - me.setObject(me.object); | ||
319 | - }); | ||
320 | - } | ||
321 | - else { | ||
322 | - me.saveProcess(false); | ||
323 | - } | ||
324 | - }); | ||
325 | - }, | 83 | + doPlot : function(){ |
84 | + if ( this.updateObject(false) ) { | ||
85 | + var plotTab = this.plotTabs.getCurrentPlotTabContent(); | ||
86 | + if (plotTab) | ||
87 | + plotTab.doPlot(); | ||
88 | + } | ||
89 | + }, | ||
90 | + | ||
91 | + /** | ||
92 | + * Check if changes were made before closing window | ||
93 | + * @return false | ||
94 | + */ | ||
95 | + fclose : function() { | ||
96 | + var module = myDesktopApp.getLoadedModule(myDesktopApp.dynamicModules.plot.id); | ||
97 | + if (module) | ||
98 | + module.closeInteractiveSession(); | ||
99 | + | ||
100 | + return this.object.isDirty(); | ||
101 | + }, | ||
102 | + | ||
103 | + /** | ||
104 | + * update time selector of this.object from form | ||
105 | + */ | ||
106 | + updateObject : function(acceptEmptyTTList = true){ | ||
107 | + var plotTab = this.plotTabs.getCurrentPlotTabContent(); | ||
108 | + if (plotTab) | ||
109 | + return plotTab.isValidRequest(acceptEmptyTTList); | ||
110 | + return false; | ||
111 | + }, | ||
112 | + | ||
113 | + updateTabs : function() { | ||
114 | + this.plotTabs.updatePlotTabs(); | ||
115 | + }, | ||
116 | + | ||
117 | + updateRequestName : function(renamedNode) { | ||
118 | + this.plotTabs.updateRequestName(renamedNode); | ||
119 | + }, | ||
120 | + | ||
121 | + addTT : function(newTTName,newTTid,timeSelectorId) { | ||
122 | + var crtTimeSelector = Ext.getCmp(timeSelectorId); | ||
123 | + if (crtTimeSelector) | ||
124 | + crtTimeSelector.addTT(newTTName,newTTid); | ||
125 | + }, | ||
126 | + | ||
127 | + /** | ||
128 | + * Set Start-Stop from parameter info (Local & MyData) | ||
129 | + */ | ||
130 | + setTimeFromData : function(obj) { | ||
131 | + if (!obj.start || !obj.stop) | ||
132 | + return; | ||
133 | + var dateStart = new Date(obj.start.replace(/[T|Z]/g,' ').replace(/\-/g,'\/')); | ||
134 | + var dateStop = new Date(obj.stop.replace(/[T|Z]/g,' ').replace(/\-/g,'\/')); | ||
135 | + | ||
136 | + var plotTab = this.plotTabs.getCurrentPlotTabContent(); | ||
137 | + if (plotTab) | ||
138 | + plotTab.setTime(dateStart, dateStop); | ||
139 | + }, | ||
140 | + | ||
141 | + savePlotRequest : function() { | ||
142 | + if (this.updateObject(true)) { | ||
143 | + var plotTab = this.plotTabs.getCurrentPlotTabContent(); | ||
144 | + if (plotTab) | ||
145 | + plotTab.savePlot(); | ||
146 | + } | ||
147 | + }, | ||
326 | 148 | ||
327 | - init : function(config) { | ||
328 | - this.timeSelector = new amdaUI.TimeSelectorUI( { id: 'multiPlotTimeSelector' + config.id, title : 'MultiPlot Time Selection', border : false, collapsible : true, collapseDirection : 'bottom', visible : false, flex: 2 } ); | ||
329 | - | ||
330 | - this.plotOutput = new amdaPlotComp.PlotOutputForm({flex: 2, collapseDirection : 'bottom', collapsible : true }); | ||
331 | - | ||
332 | - this.plotElement = new amdaPlotComp.PlotElementPanel({flex: 4}); | ||
333 | - | ||
334 | - this.plotTabs = new amdaPlotComp.PlotTabPanel({flex: 4, plotElementPanel : this.plotElement, plotUI : this}); | ||
335 | - | ||
336 | - this.optionsPanel = new Ext.form.Panel({ | ||
337 | - layout: { | ||
338 | - type: 'vbox', | ||
339 | - pack: 'start', | ||
340 | - align: 'stretch' | ||
341 | - }, | ||
342 | - bodyStyle: { background : '#dfe8f6' }, | ||
343 | - defaults: { | ||
344 | - border: false | ||
345 | - }, | ||
346 | - items: [ | ||
347 | - this.plotElement, | ||
348 | - this.plotOutput | ||
349 | - ] | ||
350 | - }); | ||
351 | - | ||
352 | - this.formPanel = new Ext.form.Panel({ | ||
353 | - region: 'center', | ||
354 | - layout: { | ||
355 | - type: 'hbox', | ||
356 | - pack: 'start', | ||
357 | - align: 'stretch' | ||
358 | - }, | ||
359 | - bodyStyle: { background : '#dfe8f6' }, | ||
360 | - defaults: { | ||
361 | - border: false | ||
362 | - }, | ||
363 | - items: [ | ||
364 | - { | ||
365 | - xtype : 'panel', | ||
366 | - layout: { | ||
367 | - type: 'vbox', | ||
368 | - pack: 'start', | ||
369 | - align: 'stretch' | ||
370 | - }, | ||
371 | - bodyStyle: { background : '#dfe8f6' }, | ||
372 | - defaults: { | ||
373 | - border: false | ||
374 | - }, | ||
375 | - flex: 1, | ||
376 | - items: [ | ||
377 | - this.plotTabs, | ||
378 | - this.timeSelector // this.multiPlotIntervalPanel | ||
379 | - ] | ||
380 | - }, | ||
381 | - { | ||
382 | - xtype : 'panel', | ||
383 | - layout: 'fit', | ||
384 | - bodyStyle: { background : '#dfe8f6' }, | ||
385 | - defaults: { | ||
386 | - border: false | ||
387 | - }, | ||
388 | - flex: 1, | ||
389 | - items: [ | ||
390 | - this.optionsPanel | ||
391 | - ] | ||
392 | - } | ||
393 | - ], | ||
394 | - fbar: [ | ||
395 | - { | ||
396 | - xtype: 'button', | ||
397 | - text: 'Plot', | ||
398 | - scope: this, | ||
399 | - handler: function(button) { | ||
400 | - this.doPlot(); | ||
401 | - } | ||
402 | - },' ', { | ||
403 | - xtype: 'button', | ||
404 | - text: 'Get Data', | ||
405 | - scope: this, | ||
406 | - handler: function(button) { | ||
407 | - this.getDataProcess(); | ||
408 | - } | ||
409 | - },' ', { | ||
410 | - xtype: 'button', | ||
411 | - text: 'Reset', | ||
412 | - scope: this, | ||
413 | - handler: function(button) { | ||
414 | - this.resetProcess(); | ||
415 | - } | ||
416 | - }, | ||
417 | - '->', '-', { | ||
418 | - xtype: 'splitbutton', | ||
419 | - text: 'Save All Tabs', | ||
420 | - menu: { | ||
421 | - items: [ | ||
422 | - { | ||
423 | - text: 'Save Current Tab', | ||
424 | - scope: this, | ||
425 | - handler: function() { | ||
426 | - this.savePlotRequest(false); | ||
427 | - } | ||
428 | - }, | ||
429 | - ] | ||
430 | - }, | ||
431 | - scope: this, | ||
432 | - handler: function(button) { | ||
433 | - this.savePlotRequest(true); | ||
434 | - } | ||
435 | - } | ||
436 | - ] | ||
437 | - }); | ||
438 | - | ||
439 | - var myConf = { | ||
440 | - layout: 'border', | ||
441 | - items: [ | ||
442 | - this.formPanel, | ||
443 | - { | ||
444 | - xtype: 'panel', | ||
445 | - region: 'south', | ||
446 | - title: 'Information', | ||
447 | - collapsible: true, | ||
448 | - collapseMode: 'header', | ||
449 | - height: 100, | ||
450 | - autoHide: false, | ||
451 | - bodyStyle: 'padding:5px', | ||
452 | - iconCls: 'icon-information', | ||
453 | - loader: { | ||
454 | - autoLoad: true, | ||
455 | - url: helpDir+'plotHOWTO' | ||
456 | - } | ||
457 | - } | ||
458 | - ] | ||
459 | - }; | ||
460 | - | ||
461 | - Ext.apply(this, Ext.apply(arguments, myConf)); | ||
462 | - } | 149 | + init : function(config) { |
150 | + this.plotTabs = new amdaPlotComp.PlotTabPanel({plotUI : this}); | ||
151 | + | ||
152 | + this.formPanel = new Ext.form.Panel({ | ||
153 | + region: 'center', | ||
154 | + layout: 'fit', | ||
155 | + bodyStyle: { background : '#dfe8f6' }, | ||
156 | + defaults: { | ||
157 | + border: false | ||
158 | + }, | ||
159 | + items: [ | ||
160 | + this.plotTabs | ||
161 | + ], | ||
162 | + fbar: [ | ||
163 | + { | ||
164 | + xtype: 'button', | ||
165 | + text: 'Plot', | ||
166 | + scope: this, | ||
167 | + handler: function(button) { | ||
168 | + this.doPlot(); | ||
169 | + } | ||
170 | + },' ', { | ||
171 | + xtype: 'button', | ||
172 | + text: 'Get Data', | ||
173 | + scope: this, | ||
174 | + handler: function(button) { | ||
175 | + this.getDataProcess(); | ||
176 | + } | ||
177 | + },' ', { | ||
178 | + xtype: 'button', | ||
179 | + text: 'Reset', | ||
180 | + scope: this, | ||
181 | + handler: function(button) { | ||
182 | + this.resetProcess(); | ||
183 | + } | ||
184 | + },'->', '-', { | ||
185 | + xtype: 'button', | ||
186 | + text: 'Save', | ||
187 | + scope: this, | ||
188 | + handler: function(button) { | ||
189 | + this.savePlotRequest(); | ||
190 | + } | ||
191 | + } | ||
192 | + ] | ||
193 | + }); | ||
194 | + | ||
195 | + var myConf = { | ||
196 | + layout: 'border', | ||
197 | + items: [ | ||
198 | + this.formPanel, | ||
199 | + { | ||
200 | + xtype: 'panel', | ||
201 | + region: 'south', | ||
202 | + title: 'Information', | ||
203 | + collapsible: true, | ||
204 | + collapseMode: 'header', | ||
205 | + height: 100, | ||
206 | + autoHide: false, | ||
207 | + bodyStyle: 'padding:5px', | ||
208 | + iconCls: 'icon-information', | ||
209 | + loader: { | ||
210 | + autoLoad: true, | ||
211 | + url: helpDir+'plotHOWTO' | ||
212 | + } | ||
213 | + } | ||
214 | + ] | ||
215 | + }; | ||
216 | + | ||
217 | + Ext.apply(this, Ext.apply(arguments, myConf)); | ||
218 | + } | ||
463 | }); | 219 | }); |
js/app/views/TimeSelectorUI.js
@@ -61,6 +61,20 @@ Ext.define('amdaUI.TimeSelectorUI', { | @@ -61,6 +61,20 @@ Ext.define('amdaUI.TimeSelectorUI', { | ||
61 | getActiveTimeSource: function() { | 61 | getActiveTimeSource: function() { |
62 | return this.timeSrc.getActiveTab().getItemId(); | 62 | return this.timeSrc.getActiveTab().getItemId(); |
63 | }, | 63 | }, |
64 | + | ||
65 | + isValid: function(acceptEmptyTTList = true) { | ||
66 | + if (this.getActiveTimeSource() === amdaModel.AmdaTimeObject.inputTimeSrc[0]) { | ||
67 | + //TimeTables | ||
68 | + if (acceptEmptyTTList) | ||
69 | + return true; | ||
70 | + return (this.TTGrid.getStore().count() > 0); | ||
71 | + } | ||
72 | + else { | ||
73 | + //Interval | ||
74 | + return this.intervalSel.isValid(); | ||
75 | + } | ||
76 | + return true; | ||
77 | + }, | ||
64 | 78 | ||
65 | initComponent: function() { | 79 | initComponent: function() { |
66 | this.activeField = null; | 80 | this.activeField = null; |
js/resources/css/AccueilAmda.css
@@ -192,7 +192,6 @@ body{ | @@ -192,7 +192,6 @@ body{ | ||
192 | font-family: orbitronbold; | 192 | font-family: orbitronbold; |
193 | font-size: 16px; | 193 | font-size: 16px; |
194 | color: rgba(0, 107, 179, 0.7); | 194 | color: rgba(0, 107, 179, 0.7); |
195 | - font-weight: bold; | ||
196 | } | 195 | } |
197 | #userLogin { | 196 | #userLogin { |
198 | position: relative; | 197 | position: relative; |
@@ -217,7 +216,6 @@ body{ | @@ -217,7 +216,6 @@ body{ | ||
217 | font-family: orbitronbold; | 216 | font-family: orbitronbold; |
218 | font-size: 16px; | 217 | font-size: 16px; |
219 | color: rgba(0, 107, 179, 0.9); | 218 | color: rgba(0, 107, 179, 0.9); |
220 | - font-weight: bold; | ||
221 | } | 219 | } |
222 | /* โขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโข ANNOUCEMENTSโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโข*/ | 220 | /* โขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโข ANNOUCEMENTSโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโขโข*/ |
223 | #textAbout { | 221 | #textAbout { |
js/resources/css/amda.css
@@ -462,10 +462,6 @@ p + p { | @@ -462,10 +462,6 @@ p + p { | ||
462 | background-image:url( ../images/16x16/plot_page.png ) !important; | 462 | background-image:url( ../images/16x16/plot_page.png ) !important; |
463 | } | 463 | } |
464 | 464 | ||
465 | -.icon-plot-pages { | ||
466 | - background-image:url( ../images/16x16/plot_pages.png ) !important; | ||
467 | -} | ||
468 | - | ||
469 | .icon-plot-layout { | 465 | .icon-plot-layout { |
470 | background-image:url( ../images/16x16/plot_layout.png ) !important; | 466 | background-image:url( ../images/16x16/plot_layout.png ) !important; |
471 | } | 467 | } |
js/resources/images/16x16/plot_pages.png deleted
150 Bytes
php/classes/AmdaAction.php
@@ -151,7 +151,6 @@ class AmdaAction | @@ -151,7 +151,6 @@ class AmdaAction | ||
151 | $isParameter = false; | 151 | $isParameter = false; |
152 | $isAddable = false; | 152 | $isAddable = false; |
153 | $isSimulation = false; | 153 | $isSimulation = false; |
154 | - $plotTabs = FALSE; | ||
155 | $rank = null; | 154 | $rank = null; |
156 | $skip = FALSE; | 155 | $skip = FALSE; |
157 | 156 | ||
@@ -185,19 +184,6 @@ class AmdaAction | @@ -185,19 +184,6 @@ class AmdaAction | ||
185 | else { | 184 | else { |
186 | $info = $id; | 185 | $info = $id; |
187 | } | 186 | } |
188 | - | ||
189 | - $isLeaf = isset($objplot->tabs); | ||
190 | - if ($isLeaf) { | ||
191 | - $plotTabs = array(); | ||
192 | - foreach ($objplot->tabs as $index => $tab) { | ||
193 | - $plotTabs[$index] = array( | ||
194 | - "name" => (!empty($tab->{'tab-name'})) ? $tab->{'tab-name'} : "Plot ".($index+1), | ||
195 | - "id" => $tab->id, | ||
196 | - ); | ||
197 | - } | ||
198 | - } | ||
199 | - else | ||
200 | - $plotTabs = FALSE; | ||
201 | break; | 187 | break; |
202 | 188 | ||
203 | // case 'alias': | 189 | // case 'alias': |
@@ -597,7 +583,7 @@ class AmdaAction | @@ -597,7 +583,7 @@ class AmdaAction | ||
597 | } | 583 | } |
598 | 584 | ||
599 | $childrenToReturn[] = array('text' => $name, 'id' => $id, 'nodeType' => $nodeType, 'info' => $info, | 585 | $childrenToReturn[] = array('text' => $name, 'id' => $id, 'nodeType' => $nodeType, 'info' => $info, |
600 | - 'help' => $help, 'leaf' => $isLeaf, 'isParameter' => $isParameter, 'dim_1' => $dim_1, 'dim_2' => $dim_2, 'tabs' => $plotTabs, | 586 | + 'help' => $help, 'leaf' => $isLeaf, 'isParameter' => $isParameter, 'dim_1' => $dim_1, 'dim_2' => $dim_2, |
601 | 'component_info' => isset($component_info) ? $component_info : NULL, | 587 | 'component_info' => isset($component_info) ? $component_info : NULL, |
602 | 'iconCls' => isset($iconCls) ? $iconCls : NULL ); | 588 | 'iconCls' => isset($iconCls) ? $iconCls : NULL ); |
603 | } | 589 | } |
@@ -826,7 +812,6 @@ class AmdaAction | @@ -826,7 +812,6 @@ class AmdaAction | ||
826 | break; | 812 | break; |
827 | case 'condition' : | 813 | case 'condition' : |
828 | case 'request' : | 814 | case 'request' : |
829 | - case 'plottab' : | ||
830 | $objectMgr = new RequestMgr($obj->nodeType); | 815 | $objectMgr = new RequestMgr($obj->nodeType); |
831 | break; | 816 | break; |
832 | case 'alias' : | 817 | case 'alias' : |
@@ -916,7 +901,6 @@ class AmdaAction | @@ -916,7 +901,6 @@ class AmdaAction | ||
916 | break; | 901 | break; |
917 | case 'condition' : | 902 | case 'condition' : |
918 | case 'request' : | 903 | case 'request' : |
919 | - case 'plottab' : | ||
920 | $objectMgr = new RequestMgr($obj->nodeType); | 904 | $objectMgr = new RequestMgr($obj->nodeType); |
921 | break; | 905 | break; |
922 | default: | 906 | default: |
@@ -1437,11 +1421,10 @@ class AmdaAction | @@ -1437,11 +1421,10 @@ class AmdaAction | ||
1437 | return array('success' => true); | 1421 | return array('success' => true); |
1438 | } | 1422 | } |
1439 | 1423 | ||
1440 | - public function interactivePlot($obj, $multiPlotState) | 1424 | + public function interactivePlot($obj) |
1441 | { | 1425 | { |
1442 | $inputobj = (Object)array( | 1426 | $inputobj = (Object)array( |
1443 | 'action' => $obj, | 1427 | 'action' => $obj, |
1444 | - 'multiPlotState' => $multiPlotState | ||
1445 | ); | 1428 | ); |
1446 | return $this->executeRequest($inputobj, FunctionTypeEnumClass::ACTION); | 1429 | return $this->executeRequest($inputobj, FunctionTypeEnumClass::ACTION); |
1447 | } | 1430 | } |
php/classes/RequestMgr.php
@@ -30,7 +30,7 @@ class RequestMgr extends AmdaObjectMgr | @@ -30,7 +30,7 @@ class RequestMgr extends AmdaObjectMgr | ||
30 | $this->attributes = array('name' => ''); | 30 | $this->attributes = array('name' => ''); |
31 | $this->optionalAttributes = array(); | 31 | $this->optionalAttributes = array(); |
32 | 32 | ||
33 | - if ($type == 'request' || $type == 'plottab') | 33 | + if ($type == 'request' ) |
34 | { | 34 | { |
35 | $this->id_prefix = 'req_'; | 35 | $this->id_prefix = 'req_'; |
36 | } | 36 | } |
@@ -73,47 +73,11 @@ class RequestMgr extends AmdaObjectMgr | @@ -73,47 +73,11 @@ class RequestMgr extends AmdaObjectMgr | ||
73 | 73 | ||
74 | public function validNameObject($p) | 74 | public function validNameObject($p) |
75 | { | 75 | { |
76 | - if ($this->type == 'plottab') { | ||
77 | - if (empty($p->name)) { | ||
78 | - return array('valid' => false, 'error' => 'Name is required'); | ||
79 | - } | ||
80 | - return array('valid' => true); | ||
81 | - } | ||
82 | return parent::validNameObject($p); | 76 | return parent::validNameObject($p); |
83 | } | 77 | } |
84 | 78 | ||
85 | public function renameObject($p) | 79 | public function renameObject($p) |
86 | { | 80 | { |
87 | - if ($this->type == 'plottab') { | ||
88 | - //Rename a plot tab | ||
89 | - if (!isset($p->parent) || empty($p->parent)) { | ||
90 | - return array('error' => 'Missing parent definition'); | ||
91 | - } | ||
92 | - $plotObj = $this->getObject($p->parent); | ||
93 | - if (is_array($plotObj) && isset($plotObj['error'])) { | ||
94 | - return array('error' => $plotObj['error']); | ||
95 | - } | ||
96 | - if (!isset($plotObj->tabs)) { | ||
97 | - return array('error' => 'Cannot retrieve tab in plot request'); | ||
98 | - } | ||
99 | - $renameOK = FALSE; | ||
100 | - foreach ($plotObj->tabs as &$tab) { | ||
101 | - if ($tab->id == $p->id) { | ||
102 | - $tab->{'tab-name'} = $p->name; | ||
103 | - $renameOK = TRUE; | ||
104 | - break; | ||
105 | - } | ||
106 | - } | ||
107 | - if (!$renameOK) { | ||
108 | - return array('error' => 'Cannot retrieve tab in plot request 2'); | ||
109 | - } | ||
110 | - //Save modification | ||
111 | - $file = fopen(USERREQDIR.$p->parent, 'w'); | ||
112 | - fwrite($file, json_encode($plotObj)); | ||
113 | - fclose($file); | ||
114 | - | ||
115 | - return array('id' => $p->id); | ||
116 | - } | ||
117 | return parent::renameObject($p); | 81 | return parent::renameObject($p); |
118 | } | 82 | } |
119 | 83 | ||
@@ -225,17 +189,6 @@ class RequestMgr extends AmdaObjectMgr | @@ -225,17 +189,6 @@ class RequestMgr extends AmdaObjectMgr | ||
225 | } | 189 | } |
226 | 190 | ||
227 | $additional = array(); | 191 | $additional = array(); |
228 | - if ($this->type == 'request') { | ||
229 | - $additional['tabs'] = array(); | ||
230 | - if (isset($p->tabs)) { | ||
231 | - foreach ($p->tabs as $index => $tab) { | ||
232 | - $additional['tabs'][$index] = array( | ||
233 | - "name" => (!empty($tab->{'tab-name'})) ? $tab->{'tab-name'} : "Plot ".($index+1), | ||
234 | - "id" => $tab->id, | ||
235 | - ); | ||
236 | - } | ||
237 | - } | ||
238 | - } | ||
239 | 192 | ||
240 | $this->descFileName = USERREQDIR.$this->id; | 193 | $this->descFileName = USERREQDIR.$this->id; |
241 | $p->id = $this->id; | 194 | $p->id = $this->id; |
@@ -258,17 +211,12 @@ class RequestMgr extends AmdaObjectMgr | @@ -258,17 +211,12 @@ class RequestMgr extends AmdaObjectMgr | ||
258 | switch ($obj->nodeType) | 211 | switch ($obj->nodeType) |
259 | { | 212 | { |
260 | case 'request' : | 213 | case 'request' : |
261 | - foreach ($obj->tabs as $tab) | ||
262 | - { | ||
263 | - $timesrc = $tab->{'multi-plot-linked'} ? $obj->timesrc : $tab->timesrc; | ||
264 | - | 214 | + |
265 | //TODO check TT as well (first start and last stop ?) | 215 | //TODO check TT as well (first start and last stop ?) |
266 | - if ($timesrc != 'Interval') continue; | ||
267 | - // select active tab | ||
268 | - if (!$tab->{'multi-plot-linked'} && $tab->id != $obj->{'last-plotted-tab'}) continue; | 216 | + if ($obj->timesrc != 'Interval') continue; |
269 | 217 | ||
270 | $argsTab = array(); | 218 | $argsTab = array(); |
271 | - foreach ($tab->panels as $panel) | 219 | + foreach ($obj->panels as $panel) |
272 | { | 220 | { |
273 | $params = array(); | 221 | $params = array(); |
274 | foreach ($panel->params as $param) | 222 | foreach ($panel->params as $param) |
@@ -283,12 +231,11 @@ class RequestMgr extends AmdaObjectMgr | @@ -283,12 +231,11 @@ class RequestMgr extends AmdaObjectMgr | ||
283 | if (count($params) > 0) | 231 | if (count($params) > 0) |
284 | { | 232 | { |
285 | $argsTab['param'] = array_unique($params); | 233 | $argsTab['param'] = array_unique($params); |
286 | - $argsTab['startTime'] = $tab->{'multi-plot-linked'} ? $obj->startDate : $tab->startDate; | ||
287 | - $argsTab['stopTime'] = $tab->{'multi-plot-linked'} ? $obj->stopDate : $tab->stopDate; | 234 | + $argsTab['startTime'] = $obj->startDate; |
235 | + $argsTab['stopTime'] = $$obj->stopDate; | ||
288 | } | 236 | } |
289 | } | 237 | } |
290 | if (count($argsTab) > 0) $args[] = $argsTab; | 238 | if (count($argsTab) > 0) $args[] = $argsTab; |
291 | - } | ||
292 | break; | 239 | break; |
293 | case 'condition' : | 240 | case 'condition' : |
294 | //$argsTab = array(); | 241 | //$argsTab = array(); |
php/classes/UserMgr.php
@@ -517,6 +517,13 @@ class UserMgr | @@ -517,6 +517,13 @@ class UserMgr | ||
517 | $this->isFirst = true; | 517 | $this->isFirst = true; |
518 | } | 518 | } |
519 | 519 | ||
520 | + $requestManager = new RequestManagerClass(); | ||
521 | + try { | ||
522 | + $res = $requestManager->runIHMRequest($this->user, $this->getIPclient(), FunctionTypeEnumClass::USERWSINIT, array()); | ||
523 | + } catch (Exception $e) { | ||
524 | + die("Login for ".$this->user." failed: Error in WS dirs - ".$e->getMessage()); | ||
525 | + } | ||
526 | + | ||
520 | if (file_exists($this->userdir.'newLogin')) { | 527 | if (file_exists($this->userdir.'newLogin')) { |
521 | touch($this->userdir.'lastLogin', filemtime($this->userdir.'newLogin')); | 528 | touch($this->userdir.'lastLogin', filemtime($this->userdir.'newLogin')); |
522 | } | 529 | } |
php/classes/simple_html_dom.php
1 | -<?php | ||
2 | -/******************************************************************************* | ||
3 | -Version: 1.11 ($Rev: 175 $) | ||
4 | -Website: http://sourceforge.net/projects/simplehtmldom/ | ||
5 | -Author: S.C. Chen <me578022@gmail.com> | ||
6 | -Acknowledge: Jose Solorzano (https://sourceforge.net/projects/php-html/) | ||
7 | -Contributions by: | ||
8 | - Yousuke Kumakura (Attribute filters) | ||
9 | - Vadim Voituk (Negative indexes supports of "find" method) | ||
10 | - Antcs (Constructor with automatically load contents either text or file/url) | ||
11 | -Licensed under The MIT License | ||
12 | -Redistributions of files must retain the above copyright notice. | ||
13 | -*******************************************************************************/ | ||
14 | - | ||
15 | -define('HDOM_TYPE_ELEMENT', 1); | ||
16 | -define('HDOM_TYPE_COMMENT', 2); | ||
17 | -define('HDOM_TYPE_TEXT', 3); | ||
18 | -define('HDOM_TYPE_ENDTAG', 4); | ||
19 | -define('HDOM_TYPE_ROOT', 5); | ||
20 | -define('HDOM_TYPE_UNKNOWN', 6); | ||
21 | -define('HDOM_QUOTE_DOUBLE', 0); | ||
22 | -define('HDOM_QUOTE_SINGLE', 1); | ||
23 | -define('HDOM_QUOTE_NO', 3); | ||
24 | -define('HDOM_INFO_BEGIN', 0); | ||
25 | -define('HDOM_INFO_END', 1); | ||
26 | -define('HDOM_INFO_QUOTE', 2); | ||
27 | -define('HDOM_INFO_SPACE', 3); | ||
28 | -define('HDOM_INFO_TEXT', 4); | ||
29 | -define('HDOM_INFO_INNER', 5); | ||
30 | -define('HDOM_INFO_OUTER', 6); | ||
31 | -define('HDOM_INFO_ENDSPACE',7); | ||
32 | - | ||
33 | -// helper functions | ||
34 | -// ----------------------------------------------------------------------------- | ||
35 | -// get html dom form file | ||
36 | -function file_get_html() { | ||
37 | - $dom = new simple_html_dom; | ||
38 | - $args = func_get_args(); | ||
39 | - $dom->load(call_user_func_array('file_get_contents', $args), true); | ||
40 | - return $dom; | ||
41 | -} | ||
42 | - | ||
43 | -// get html dom form string | ||
44 | -function str_get_html($str, $lowercase=true) { | ||
45 | - $dom = new simple_html_dom; | ||
46 | - $dom->load($str, $lowercase); | ||
47 | - return $dom; | ||
48 | -} | ||
49 | - | ||
50 | -// dump html dom tree | ||
51 | -function dump_html_tree($node, $show_attr=true, $deep=0) { | ||
52 | - $lead = str_repeat(' ', $deep); | ||
53 | - echo $lead.$node->tag; | ||
54 | - if ($show_attr && count($node->attr)>0) { | ||
55 | - echo '('; | ||
56 | - foreach($node->attr as $k=>$v) | ||
57 | - echo "[$k]=>\"".$node->$k.'", '; | ||
58 | - echo ')'; | ||
59 | - } | ||
60 | - echo "\n"; | ||
61 | - | ||
62 | - foreach($node->nodes as $c) | ||
63 | - dump_html_tree($c, $show_attr, $deep+1); | ||
64 | -} | ||
65 | - | ||
66 | -// get dom form file (deprecated) | ||
67 | -function file_get_dom() { | ||
68 | - $dom = new simple_html_dom; | ||
69 | - $args = func_get_args(); | ||
70 | - $dom->load(call_user_func_array('file_get_contents', $args), true); | ||
71 | - return $dom; | ||
72 | -} | ||
73 | - | ||
74 | -// get dom form string (deprecated) | ||
75 | -function str_get_dom($str, $lowercase=true) { | ||
76 | - $dom = new simple_html_dom; | ||
77 | - $dom->load($str, $lowercase); | ||
78 | - return $dom; | ||
79 | -} | ||
80 | - | ||
81 | -// simple html dom node | ||
82 | -// ----------------------------------------------------------------------------- | ||
83 | -class simple_html_dom_node { | ||
84 | - public $nodetype = HDOM_TYPE_TEXT; | ||
85 | - public $tag = 'text'; | ||
86 | - public $attr = array(); | ||
87 | - public $children = array(); | ||
88 | - public $nodes = array(); | ||
89 | - public $parent = null; | ||
90 | - public $_ = array(); | ||
91 | - private $dom = null; | ||
92 | - | ||
93 | - function __construct($dom) { | ||
94 | - $this->dom = $dom; | ||
95 | - $dom->nodes[] = $this; | ||
96 | - } | ||
97 | - | ||
98 | - function __destruct() { | ||
99 | - $this->clear(); | ||
100 | - } | ||
101 | - | ||
102 | - function __toString() { | ||
103 | - return $this->outertext(); | ||
104 | - } | ||
105 | - | ||
106 | - // clean up memory due to php5 circular references memory leak... | ||
107 | - function clear() { | ||
108 | - $this->dom = null; | ||
109 | - $this->nodes = null; | ||
110 | - $this->parent = null; | ||
111 | - $this->children = null; | ||
112 | - } | ||
113 | - | ||
114 | - // dump node's tree | ||
115 | - function dump($show_attr=true) { | ||
116 | - dump_html_tree($this, $show_attr); | ||
117 | - } | ||
118 | - | ||
119 | - // returns the parent of node | ||
120 | - function parent() { | ||
121 | - return $this->parent; | ||
122 | - } | ||
123 | - | ||
124 | - // returns children of node | ||
125 | - function children($idx=-1) { | ||
126 | - if ($idx===-1) return $this->children; | ||
127 | - if (isset($this->children[$idx])) return $this->children[$idx]; | ||
128 | - return null; | ||
129 | - } | ||
130 | - | ||
131 | - // returns the first child of node | ||
132 | - function first_child() { | ||
133 | - if (count($this->children)>0) return $this->children[0]; | ||
134 | - return null; | ||
135 | - } | ||
136 | - | ||
137 | - // returns the last child of node | ||
138 | - function last_child() { | ||
139 | - if (($count=count($this->children))>0) return $this->children[$count-1]; | ||
140 | - return null; | ||
141 | - } | ||
142 | - | ||
143 | - // returns the next sibling of node | ||
144 | - function next_sibling() { | ||
145 | - if ($this->parent===null) return null; | ||
146 | - $idx = 0; | ||
147 | - $count = count($this->parent->children); | ||
148 | - while ($idx<$count && $this!==$this->parent->children[$idx]) | ||
149 | - ++$idx; | ||
150 | - if (++$idx>=$count) return null; | ||
151 | - return $this->parent->children[$idx]; | ||
152 | - } | ||
153 | - | ||
154 | - // returns the previous sibling of node | ||
155 | - function prev_sibling() { | ||
156 | - if ($this->parent===null) return null; | ||
157 | - $idx = 0; | ||
158 | - $count = count($this->parent->children); | ||
159 | - while ($idx<$count && $this!==$this->parent->children[$idx]) | ||
160 | - ++$idx; | ||
161 | - if (--$idx<0) return null; | ||
162 | - return $this->parent->children[$idx]; | ||
163 | - } | ||
164 | - | ||
165 | - // get dom node's inner html | ||
166 | - function innertext() { | ||
167 | - if (isset($this->_[HDOM_INFO_INNER])) return $this->_[HDOM_INFO_INNER]; | ||
168 | - if (isset($this->_[HDOM_INFO_TEXT])) return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]); | ||
169 | - | ||
170 | - $ret = ''; | ||
171 | - foreach($this->nodes as $n) | ||
172 | - $ret .= $n->outertext(); | ||
173 | - return $ret; | ||
174 | - } | ||
175 | - | ||
176 | - // get dom node's outer text (with tag) | ||
177 | - function outertext() { | ||
178 | - if ($this->tag==='root') return $this->innertext(); | ||
179 | - | ||
180 | - // trigger callback | ||
181 | - if ($this->dom->callback!==null) | ||
182 | - call_user_func_array($this->dom->callback, array($this)); | ||
183 | - | ||
184 | - if (isset($this->_[HDOM_INFO_OUTER])) return $this->_[HDOM_INFO_OUTER]; | ||
185 | - if (isset($this->_[HDOM_INFO_TEXT])) return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]); | ||
186 | - | ||
187 | - // render begin tag | ||
188 | - $ret = $this->dom->nodes[$this->_[HDOM_INFO_BEGIN]]->makeup(); | ||
189 | - | ||
190 | - // render inner text | ||
191 | - if (isset($this->_[HDOM_INFO_INNER])) | ||
192 | - $ret .= $this->_[HDOM_INFO_INNER]; | ||
193 | - else { | ||
194 | - foreach($this->nodes as $n) | ||
195 | - $ret .= $n->outertext(); | ||
196 | - } | ||
197 | - | ||
198 | - // render end tag | ||
199 | - if(isset($this->_[HDOM_INFO_END]) && $this->_[HDOM_INFO_END]!=0) | ||
200 | - $ret .= '</'.$this->tag.'>'; | ||
201 | - return $ret; | ||
202 | - } | ||
203 | - | ||
204 | - // get dom node's plain text | ||
205 | - function text() { | ||
206 | - if (isset($this->_[HDOM_INFO_INNER])) return $this->_[HDOM_INFO_INNER]; | ||
207 | - switch ($this->nodetype) { | ||
208 | - case HDOM_TYPE_TEXT: return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]); | ||
209 | - case HDOM_TYPE_COMMENT: return ''; | ||
210 | - case HDOM_TYPE_UNKNOWN: return ''; | ||
211 | - } | ||
212 | - if (strcasecmp($this->tag, 'script')===0) return ''; | ||
213 | - if (strcasecmp($this->tag, 'style')===0) return ''; | ||
214 | - | ||
215 | - $ret = ''; | ||
216 | - foreach($this->nodes as $n) | ||
217 | - $ret .= $n->text(); | ||
218 | - return $ret; | ||
219 | - } | ||
220 | - | ||
221 | - function xmltext() { | ||
222 | - $ret = $this->innertext(); | ||
223 | - $ret = str_ireplace('<![CDATA[', '', $ret); | ||
224 | - $ret = str_replace(']]>', '', $ret); | ||
225 | - return $ret; | ||
226 | - } | ||
227 | - | ||
228 | - // build node's text with tag | ||
229 | - function makeup() { | ||
230 | - // text, comment, unknown | ||
231 | - if (isset($this->_[HDOM_INFO_TEXT])) return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]); | ||
232 | - | ||
233 | - $ret = '<'.$this->tag; | ||
234 | - $i = -1; | ||
235 | - | ||
236 | - foreach($this->attr as $key=>$val) { | ||
237 | - ++$i; | ||
238 | - | ||
239 | - // skip removed attribute | ||
240 | - if ($val===null || $val===false) | ||
241 | - continue; | ||
242 | - | ||
243 | - $ret .= $this->_[HDOM_INFO_SPACE][$i][0]; | ||
244 | - //no value attr: nowrap, checked selected... | ||
245 | - if ($val===true) | ||
246 | - $ret .= $key; | ||
247 | - else { | ||
248 | - switch($this->_[HDOM_INFO_QUOTE][$i]) { | ||
249 | - case HDOM_QUOTE_DOUBLE: $quote = '"'; break; | ||
250 | - case HDOM_QUOTE_SINGLE: $quote = '\''; break; | ||
251 | - default: $quote = ''; | ||
252 | - } | ||
253 | - $ret .= $key.$this->_[HDOM_INFO_SPACE][$i][1].'='.$this->_[HDOM_INFO_SPACE][$i][2].$quote.$val.$quote; | ||
254 | - } | ||
255 | - } | ||
256 | - $ret = $this->dom->restore_noise($ret); | ||
257 | - return $ret . $this->_[HDOM_INFO_ENDSPACE] . '>'; | ||
258 | - } | ||
259 | - | ||
260 | - // find elements by css selector | ||
261 | - function find($selector, $idx=null) { | ||
262 | - $selectors = $this->parse_selector($selector); | ||
263 | - if (($count=count($selectors))===0) return array(); | ||
264 | - $found_keys = array(); | ||
265 | - | ||
266 | - // find each selector | ||
267 | - for ($c=0; $c<$count; ++$c) { | ||
268 | - if (($levle=count($selectors[0]))===0) return array(); | ||
269 | - if (!isset($this->_[HDOM_INFO_BEGIN])) return array(); | ||
270 | - | ||
271 | - $head = array($this->_[HDOM_INFO_BEGIN]=>1); | ||
272 | - | ||
273 | - // handle descendant selectors, no recursive! | ||
274 | - for ($l=0; $l<$levle; ++$l) { | ||
275 | - $ret = array(); | ||
276 | - foreach($head as $k=>$v) { | ||
277 | - $n = ($k===-1) ? $this->dom->root : $this->dom->nodes[$k]; | ||
278 | - $n->seek($selectors[$c][$l], $ret); | ||
279 | - } | ||
280 | - $head = $ret; | ||
281 | - } | ||
282 | - | ||
283 | - foreach($head as $k=>$v) { | ||
284 | - if (!isset($found_keys[$k])) | ||
285 | - $found_keys[$k] = 1; | ||
286 | - } | ||
287 | - } | ||
288 | - | ||
289 | - // sort keys | ||
290 | - ksort($found_keys); | ||
291 | - | ||
292 | - $found = array(); | ||
293 | - foreach($found_keys as $k=>$v) | ||
294 | - $found[] = $this->dom->nodes[$k]; | ||
295 | - | ||
296 | - // return nth-element or array | ||
297 | - if (is_null($idx)) return $found; | ||
298 | - else if ($idx<0) $idx = count($found) + $idx; | ||
299 | - return (isset($found[$idx])) ? $found[$idx] : null; | ||
300 | - } | ||
301 | - | ||
302 | - // seek for given conditions | ||
303 | - protected function seek($selector, &$ret) { | ||
304 | - list($tag, $key, $val, $exp, $no_key) = $selector; | ||
305 | - | ||
306 | - // xpath index | ||
307 | - if ($tag && $key && is_numeric($key)) { | ||
308 | - $count = 0; | ||
309 | - foreach ($this->children as $c) { | ||
310 | - if ($tag==='*' || $tag===$c->tag) { | ||
311 | - if (++$count==$key) { | ||
312 | - $ret[$c->_[HDOM_INFO_BEGIN]] = 1; | ||
313 | - return; | ||
314 | - } | ||
315 | - } | ||
316 | - } | ||
317 | - return; | ||
318 | - } | ||
319 | - | ||
320 | - $end = (!empty($this->_[HDOM_INFO_END])) ? $this->_[HDOM_INFO_END] : 0; | ||
321 | - if ($end==0) { | ||
322 | - $parent = $this->parent; | ||
323 | - while (!isset($parent->_[HDOM_INFO_END]) && $parent!==null) { | ||
324 | - $end -= 1; | ||
325 | - $parent = $parent->parent; | ||
326 | - } | ||
327 | - $end += $parent->_[HDOM_INFO_END]; | ||
328 | - } | ||
329 | - | ||
330 | - for($i=$this->_[HDOM_INFO_BEGIN]+1; $i<$end; ++$i) { | ||
331 | - $node = $this->dom->nodes[$i]; | ||
332 | - $pass = true; | ||
333 | - | ||
334 | - if ($tag==='*' && !$key) { | ||
335 | - if (in_array($node, $this->children, true)) | ||
336 | - $ret[$i] = 1; | ||
337 | - continue; | ||
338 | - } | ||
339 | - | ||
340 | - // compare tag | ||
341 | - if ($tag && $tag!=$node->tag && $tag!=='*') {$pass=false;} | ||
342 | - // compare key | ||
343 | - if ($pass && $key) { | ||
344 | - if ($no_key) { | ||
345 | - if (isset($node->attr[$key])) $pass=false; | ||
346 | - } | ||
347 | - else if (!isset($node->attr[$key])) $pass=false; | ||
348 | - } | ||
349 | - // compare value | ||
350 | - if ($pass && $key && $val && $val!=='*') { | ||
351 | - $check = $this->match($exp, $val, $node->attr[$key]); | ||
352 | - // handle multiple class | ||
353 | - if (!$check && strcasecmp($key, 'class')===0) { | ||
354 | - foreach(explode(' ',$node->attr[$key]) as $k) { | ||
355 | - $check = $this->match($exp, $val, $k); | ||
356 | - if ($check) break; | ||
357 | - } | ||
358 | - } | ||
359 | - if (!$check) $pass = false; | ||
360 | - } | ||
361 | - if ($pass) $ret[$i] = 1; | ||
362 | - unset($node); | ||
363 | - } | ||
364 | - } | ||
365 | - | ||
366 | - protected function match($exp, $pattern, $value) { | ||
367 | - switch ($exp) { | ||
368 | - case '=': | ||
369 | - return ($value===$pattern); | ||
370 | - case '!=': | ||
371 | - return ($value!==$pattern); | ||
372 | - case '^=': | ||
373 | - return preg_match("/^".preg_quote($pattern,'/')."/", $value); | ||
374 | - case '$=': | ||
375 | - return preg_match("/".preg_quote($pattern,'/')."$/", $value); | ||
376 | - case '*=': | ||
377 | - if ($pattern[0]=='/') | ||
378 | - return preg_match($pattern, $value); | ||
379 | - return preg_match("/".$pattern."/i", $value); | ||
380 | - } | ||
381 | - return false; | ||
382 | - } | ||
383 | - | ||
384 | - protected function parse_selector($selector_string) { | ||
385 | - // pattern of CSS selectors, modified from mootools | ||
386 | - $pattern = "/([\w-:\*]*)(?:\#([\w-]+)|\.([\w-]+))?(?:\[@?(!?[\w-]+)(?:([!*^$]?=)[\"']?(.*?)[\"']?)?\])?([\/, ]+)/is"; | ||
387 | - preg_match_all($pattern, trim($selector_string).' ', $matches, PREG_SET_ORDER); | ||
388 | - $selectors = array(); | ||
389 | - $result = array(); | ||
390 | - //print_r($matches); | ||
391 | - | ||
392 | - foreach ($matches as $m) { | ||
393 | - $m[0] = trim($m[0]); | ||
394 | - if ($m[0]==='' || $m[0]==='/' || $m[0]==='//') continue; | ||
395 | - // for borwser grnreated xpath | ||
396 | - if ($m[1]==='tbody') continue; | ||
397 | - | ||
398 | - list($tag, $key, $val, $exp, $no_key) = array($m[1], null, null, '=', false); | ||
399 | - if(!empty($m[2])) {$key='id'; $val=$m[2];} | ||
400 | - if(!empty($m[3])) {$key='class'; $val=$m[3];} | ||
401 | - if(!empty($m[4])) {$key=$m[4];} | ||
402 | - if(!empty($m[5])) {$exp=$m[5];} | ||
403 | - if(!empty($m[6])) {$val=$m[6];} | ||
404 | - | ||
405 | - // convert to lowercase | ||
406 | - if ($this->dom->lowercase) {$tag=strtolower($tag); $key=strtolower($key);} | ||
407 | - //elements that do NOT have the specified attribute | ||
408 | - if (isset($key[0]) && $key[0]==='!') {$key=substr($key, 1); $no_key=true;} | ||
409 | - | ||
410 | - $result[] = array($tag, $key, $val, $exp, $no_key); | ||
411 | - if (trim($m[7])===',') { | ||
412 | - $selectors[] = $result; | ||
413 | - $result = array(); | ||
414 | - } | ||
415 | - } | ||
416 | - if (count($result)>0) | ||
417 | - $selectors[] = $result; | ||
418 | - return $selectors; | ||
419 | - } | ||
420 | - | ||
421 | - function __get($name) { | ||
422 | - if (isset($this->attr[$name])) return $this->attr[$name]; | ||
423 | - switch($name) { | ||
424 | - case 'outertext': return $this->outertext(); | ||
425 | - case 'innertext': return $this->innertext(); | ||
426 | - case 'plaintext': return $this->text(); | ||
427 | - case 'xmltext': return $this->xmltext(); | ||
428 | - default: return array_key_exists($name, $this->attr); | ||
429 | - } | ||
430 | - } | ||
431 | - | ||
432 | - function __set($name, $value) { | ||
433 | - switch($name) { | ||
434 | - case 'outertext': return $this->_[HDOM_INFO_OUTER] = $value; | ||
435 | - case 'innertext': | ||
436 | - if (isset($this->_[HDOM_INFO_TEXT])) return $this->_[HDOM_INFO_TEXT] = $value; | ||
437 | - return $this->_[HDOM_INFO_INNER] = $value; | ||
438 | - } | ||
439 | - if (!isset($this->attr[$name])) { | ||
440 | - $this->_[HDOM_INFO_SPACE][] = array(' ', '', ''); | ||
441 | - $this->_[HDOM_INFO_QUOTE][] = HDOM_QUOTE_DOUBLE; | ||
442 | - } | ||
443 | - $this->attr[$name] = $value; | ||
444 | - } | ||
445 | - | ||
446 | - function __isset($name) { | ||
447 | - switch($name) { | ||
448 | - case 'outertext': return true; | ||
449 | - case 'innertext': return true; | ||
450 | - case 'plaintext': return true; | ||
451 | - } | ||
452 | - //no value attr: nowrap, checked selected... | ||
453 | - return (array_key_exists($name, $this->attr)) ? true : isset($this->attr[$name]); | ||
454 | - } | ||
455 | - | ||
456 | - function __unset($name) { | ||
457 | - if (isset($this->attr[$name])) | ||
458 | - unset($this->attr[$name]); | ||
459 | - } | ||
460 | - | ||
461 | - // camel naming conventions | ||
462 | - function getAllAttributes() {return $this->attr;} | ||
463 | - function getAttribute($name) {return $this->__get($name);} | ||
464 | - function setAttribute($name, $value) {$this->__set($name, $value);} | ||
465 | - function hasAttribute($name) {return $this->__isset($name);} | ||
466 | - function removeAttribute($name) {$this->__set($name, null);} | ||
467 | - function getElementById($id) {return $this->find("#$id", 0);} | ||
468 | - function getElementsById($id, $idx=null) {return $this->find("#$id", $idx);} | ||
469 | - function getElementByTagName($name) {return $this->find($name, 0);} | ||
470 | - function getElementsByTagName($name, $idx=null) {return $this->find($name, $idx);} | ||
471 | - function parentNode() {return $this->parent();} | ||
472 | - function childNodes($idx=-1) {return $this->children($idx);} | ||
473 | - function firstChild() {return $this->first_child();} | ||
474 | - function lastChild() {return $this->last_child();} | ||
475 | - function nextSibling() {return $this->next_sibling();} | ||
476 | - function previousSibling() {return $this->prev_sibling();} | ||
477 | -} | ||
478 | - | ||
479 | -// simple html dom parser | ||
480 | -// ----------------------------------------------------------------------------- | ||
481 | -class simple_html_dom { | ||
482 | - public $root = null; | ||
483 | - public $nodes = array(); | ||
484 | - public $callback = null; | ||
485 | - public $lowercase = false; | ||
486 | - protected $pos; | ||
487 | - protected $doc; | ||
488 | - protected $char; | ||
489 | - protected $size; | ||
490 | - protected $cursor; | ||
491 | - protected $parent; | ||
492 | - protected $noise = array(); | ||
493 | - protected $token_blank = " \t\r\n"; | ||
494 | - protected $token_equal = ' =/>'; | ||
495 | - protected $token_slash = " />\r\n\t"; | ||
496 | - protected $token_attr = ' >'; | ||
497 | - // use isset instead of in_array, performance boost about 30%... | ||
498 | - protected $self_closing_tags = array('img'=>1, 'br'=>1, 'input'=>1, 'meta'=>1, 'link'=>1, 'hr'=>1, 'base'=>1, 'embed'=>1, 'spacer'=>1); | ||
499 | - protected $block_tags = array('root'=>1, 'body'=>1, 'form'=>1, 'div'=>1, 'span'=>1, 'table'=>1); | ||
500 | - protected $optional_closing_tags = array( | ||
501 | - 'tr'=>array('tr'=>1, 'td'=>1, 'th'=>1), | ||
502 | - 'th'=>array('th'=>1), | ||
503 | - 'td'=>array('td'=>1), | ||
504 | - 'li'=>array('li'=>1), | ||
505 | - 'dt'=>array('dt'=>1, 'dd'=>1), | ||
506 | - 'dd'=>array('dd'=>1, 'dt'=>1), | ||
507 | - 'dl'=>array('dd'=>1, 'dt'=>1), | ||
508 | - 'p'=>array('p'=>1), | ||
509 | - 'nobr'=>array('nobr'=>1), | ||
510 | - ); | ||
511 | - | ||
512 | - function __construct($str=null) { | ||
513 | - if ($str) { | ||
514 | - if (preg_match("/^http:\/\//i",$str) || is_file($str)) | ||
515 | - $this->load_file($str); | ||
516 | - else | ||
517 | - $this->load($str); | ||
518 | - } | ||
519 | - } | ||
520 | - | ||
521 | - function __destruct() { | ||
522 | - $this->clear(); | ||
523 | - } | ||
524 | - | ||
525 | - // load html from string | ||
526 | - function load($str, $lowercase=true) { | ||
527 | - // prepare | ||
528 | - $this->prepare($str, $lowercase); | ||
529 | - // strip out comments | ||
530 | - $this->remove_noise("'<!--(.*?)-->'is"); | ||
531 | - // strip out cdata | ||
532 | - $this->remove_noise("'<!\[CDATA\[(.*?)\]\]>'is", true); | ||
533 | - // strip out <style> tags | ||
534 | - $this->remove_noise("'<\s*style[^>]*[^/]>(.*?)<\s*/\s*style\s*>'is"); | ||
535 | - $this->remove_noise("'<\s*style\s*>(.*?)<\s*/\s*style\s*>'is"); | ||
536 | - // strip out <script> tags | ||
537 | - $this->remove_noise("'<\s*script[^>]*[^/]>(.*?)<\s*/\s*script\s*>'is"); | ||
538 | - $this->remove_noise("'<\s*script\s*>(.*?)<\s*/\s*script\s*>'is"); | ||
539 | - // strip out preformatted tags | ||
540 | - $this->remove_noise("'<\s*(?:code)[^>]*>(.*?)<\s*/\s*(?:code)\s*>'is"); | ||
541 | - // strip out server side scripts | ||
542 | - $this->remove_noise("'(<\?)(.*?)(\?>)'s", true); | ||
543 | - // strip smarty scripts | ||
544 | - $this->remove_noise("'(\{\w)(.*?)(\})'s", true); | ||
545 | - | ||
546 | - // parsing | ||
547 | - while ($this->parse()); | ||
548 | - // end | ||
549 | - $this->root->_[HDOM_INFO_END] = $this->cursor; | ||
550 | - } | ||
551 | - | ||
552 | - // load html from file | ||
553 | - function load_file() { | ||
554 | - $args = func_get_args(); | ||
555 | - $this->load(call_user_func_array('file_get_contents', $args), true); | ||
556 | - } | ||
557 | - | ||
558 | - // set callback function | ||
559 | - function set_callback($function_name) { | ||
560 | - $this->callback = $function_name; | ||
561 | - } | ||
562 | - | ||
563 | - // remove callback function | ||
564 | - function remove_callback() { | ||
565 | - $this->callback = null; | ||
566 | - } | ||
567 | - | ||
568 | - // save dom as string | ||
569 | - function save($filepath='') { | ||
570 | - $ret = $this->root->innertext(); | ||
571 | - if ($filepath!=='') file_put_contents($filepath, $ret); | ||
572 | - return $ret; | ||
573 | - } | ||
574 | - | ||
575 | - // find dom node by css selector | ||
576 | - function find($selector, $idx=null) { | ||
577 | - return $this->root->find($selector, $idx); | ||
578 | - } | ||
579 | - | ||
580 | - // clean up memory due to php5 circular references memory leak... | ||
581 | - function clear() { | ||
582 | - foreach($this->nodes as $n) {$n->clear(); $n = null;} | ||
583 | - if (isset($this->parent)) {$this->parent->clear(); unset($this->parent);} | ||
584 | - if (isset($this->root)) {$this->root->clear(); unset($this->root);} | ||
585 | - unset($this->doc); | ||
586 | - unset($this->noise); | ||
587 | - } | ||
588 | - | ||
589 | - function dump($show_attr=true) { | ||
590 | - $this->root->dump($show_attr); | ||
591 | - } | ||
592 | - | ||
593 | - // prepare HTML data and init everything | ||
594 | - protected function prepare($str, $lowercase=true) { | ||
595 | - $this->clear(); | ||
596 | - $this->doc = $str; | ||
597 | - $this->pos = 0; | ||
598 | - $this->cursor = 1; | ||
599 | - $this->noise = array(); | ||
600 | - $this->nodes = array(); | ||
601 | - $this->lowercase = $lowercase; | ||
602 | - $this->root = new simple_html_dom_node($this); | ||
603 | - $this->root->tag = 'root'; | ||
604 | - $this->root->_[HDOM_INFO_BEGIN] = -1; | ||
605 | - $this->root->nodetype = HDOM_TYPE_ROOT; | ||
606 | - $this->parent = $this->root; | ||
607 | - // set the length of content | ||
608 | - $this->size = strlen($str); | ||
609 | - if ($this->size>0) $this->char = $this->doc[0]; | ||
610 | - } | ||
611 | - | ||
612 | - // parse html content | ||
613 | - protected function parse() { | ||
614 | - if (($s = $this->copy_until_char('<'))==='') | ||
615 | - return $this->read_tag(); | ||
616 | - | ||
617 | - // text | ||
618 | - $node = new simple_html_dom_node($this); | ||
619 | - ++$this->cursor; | ||
620 | - $node->_[HDOM_INFO_TEXT] = $s; | ||
621 | - $this->link_nodes($node, false); | ||
622 | - return true; | ||
623 | - } | ||
624 | - | ||
625 | - // read tag info | ||
626 | - protected function read_tag() { | ||
627 | - if ($this->char!=='<') { | ||
628 | - $this->root->_[HDOM_INFO_END] = $this->cursor; | ||
629 | - return false; | ||
630 | - } | ||
631 | - $begin_tag_pos = $this->pos; | ||
632 | - $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | ||
633 | - | ||
634 | - // end tag | ||
635 | - if ($this->char==='/') { | ||
636 | - $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | ||
637 | - $this->skip($this->token_blank_t); | ||
638 | - $tag = $this->copy_until_char('>'); | ||
639 | - | ||
640 | - // skip attributes in end tag | ||
641 | - if (($pos = strpos($tag, ' '))!==false) | ||
642 | - $tag = substr($tag, 0, $pos); | ||
643 | - | ||
644 | - $parent_lower = strtolower($this->parent->tag); | ||
645 | - $tag_lower = strtolower($tag); | ||
646 | - | ||
647 | - if ($parent_lower!==$tag_lower) { | ||
648 | - if (isset($this->optional_closing_tags[$parent_lower]) && isset($this->block_tags[$tag_lower])) { | ||
649 | - $this->parent->_[HDOM_INFO_END] = 0; | ||
650 | - $org_parent = $this->parent; | ||
651 | - | ||
652 | - while (($this->parent->parent) && strtolower($this->parent->tag)!==$tag_lower) | ||
653 | - $this->parent = $this->parent->parent; | ||
654 | - | ||
655 | - if (strtolower($this->parent->tag)!==$tag_lower) { | ||
656 | - $this->parent = $org_parent; // restore origonal parent | ||
657 | - if ($this->parent->parent) $this->parent = $this->parent->parent; | ||
658 | - $this->parent->_[HDOM_INFO_END] = $this->cursor; | ||
659 | - return $this->as_text_node($tag); | ||
660 | - } | ||
661 | - } | ||
662 | - else if (($this->parent->parent) && isset($this->block_tags[$tag_lower])) { | ||
663 | - $this->parent->_[HDOM_INFO_END] = 0; | ||
664 | - $org_parent = $this->parent; | ||
665 | - | ||
666 | - while (($this->parent->parent) && strtolower($this->parent->tag)!==$tag_lower) | ||
667 | - $this->parent = $this->parent->parent; | ||
668 | - | ||
669 | - if (strtolower($this->parent->tag)!==$tag_lower) { | ||
670 | - $this->parent = $org_parent; // restore origonal parent | ||
671 | - $this->parent->_[HDOM_INFO_END] = $this->cursor; | ||
672 | - return $this->as_text_node($tag); | ||
673 | - } | ||
674 | - } | ||
675 | - else if (($this->parent->parent) && strtolower($this->parent->parent->tag)===$tag_lower) { | ||
676 | - $this->parent->_[HDOM_INFO_END] = 0; | ||
677 | - $this->parent = $this->parent->parent; | ||
678 | - } | ||
679 | - else | ||
680 | - return $this->as_text_node($tag); | ||
681 | - } | ||
682 | - | ||
683 | - $this->parent->_[HDOM_INFO_END] = $this->cursor; | ||
684 | - if ($this->parent->parent) $this->parent = $this->parent->parent; | ||
685 | - | ||
686 | - $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | ||
687 | - return true; | ||
688 | - } | ||
689 | - | ||
690 | - $node = new simple_html_dom_node($this); | ||
691 | - $node->_[HDOM_INFO_BEGIN] = $this->cursor; | ||
692 | - ++$this->cursor; | ||
693 | - $tag = $this->copy_until($this->token_slash); | ||
694 | - | ||
695 | - // doctype, cdata & comments... | ||
696 | - if (isset($tag[0]) && $tag[0]==='!') { | ||
697 | - $node->_[HDOM_INFO_TEXT] = '<' . $tag . $this->copy_until_char('>'); | ||
698 | - | ||
699 | - if (isset($tag[2]) && $tag[1]==='-' && $tag[2]==='-') { | ||
700 | - $node->nodetype = HDOM_TYPE_COMMENT; | ||
701 | - $node->tag = 'comment'; | ||
702 | - } else { | ||
703 | - $node->nodetype = HDOM_TYPE_UNKNOWN; | ||
704 | - $node->tag = 'unknown'; | ||
705 | - } | ||
706 | - | ||
707 | - if ($this->char==='>') $node->_[HDOM_INFO_TEXT].='>'; | ||
708 | - $this->link_nodes($node, true); | ||
709 | - $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | ||
710 | - return true; | ||
711 | - } | ||
712 | - | ||
713 | - // text | ||
714 | - if ($pos=strpos($tag, '<')!==false) { | ||
715 | - $tag = '<' . substr($tag, 0, -1); | ||
716 | - $node->_[HDOM_INFO_TEXT] = $tag; | ||
717 | - $this->link_nodes($node, false); | ||
718 | - $this->char = $this->doc[--$this->pos]; // prev | ||
719 | - return true; | ||
720 | - } | ||
721 | - | ||
722 | - if (!preg_match("/^[\w-:]+$/", $tag)) { | ||
723 | - $node->_[HDOM_INFO_TEXT] = '<' . $tag . $this->copy_until('<>'); | ||
724 | - if ($this->char==='<') { | ||
725 | - $this->link_nodes($node, false); | ||
726 | - return true; | ||
727 | - } | ||
728 | - | ||
729 | - if ($this->char==='>') $node->_[HDOM_INFO_TEXT].='>'; | ||
730 | - $this->link_nodes($node, false); | ||
731 | - $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | ||
732 | - return true; | ||
733 | - } | ||
734 | - | ||
735 | - // begin tag | ||
736 | - $node->nodetype = HDOM_TYPE_ELEMENT; | ||
737 | - $tag_lower = strtolower($tag); | ||
738 | - $node->tag = ($this->lowercase) ? $tag_lower : $tag; | ||
739 | - | ||
740 | - // handle optional closing tags | ||
741 | - if (isset($this->optional_closing_tags[$tag_lower]) ) { | ||
742 | - while (isset($this->optional_closing_tags[$tag_lower][strtolower($this->parent->tag)])) { | ||
743 | - $this->parent->_[HDOM_INFO_END] = 0; | ||
744 | - $this->parent = $this->parent->parent; | ||
745 | - } | ||
746 | - $node->parent = $this->parent; | ||
747 | - } | ||
748 | - | ||
749 | - $guard = 0; // prevent infinity loop | ||
750 | - $space = array($this->copy_skip($this->token_blank), '', ''); | ||
751 | - | ||
752 | - // attributes | ||
753 | - do { | ||
754 | - if ($this->char!==null && $space[0]==='') break; | ||
755 | - $name = $this->copy_until($this->token_equal); | ||
756 | - if($guard===$this->pos) { | ||
757 | - $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | ||
758 | - continue; | ||
759 | - } | ||
760 | - $guard = $this->pos; | ||
761 | - | ||
762 | - // handle endless '<' | ||
763 | - if($this->pos>=$this->size-1 && $this->char!=='>') { | ||
764 | - $node->nodetype = HDOM_TYPE_TEXT; | ||
765 | - $node->_[HDOM_INFO_END] = 0; | ||
766 | - $node->_[HDOM_INFO_TEXT] = '<'.$tag . $space[0] . $name; | ||
767 | - $node->tag = 'text'; | ||
768 | - $this->link_nodes($node, false); | ||
769 | - return true; | ||
770 | - } | ||
771 | - | ||
772 | - // handle mismatch '<' | ||
773 | - if($this->doc[$this->pos-1]=='<') { | ||
774 | - $node->nodetype = HDOM_TYPE_TEXT; | ||
775 | - $node->tag = 'text'; | ||
776 | - $node->attr = array(); | ||
777 | - $node->_[HDOM_INFO_END] = 0; | ||
778 | - $node->_[HDOM_INFO_TEXT] = substr($this->doc, $begin_tag_pos, $this->pos-$begin_tag_pos-1); | ||
779 | - $this->pos -= 2; | ||
780 | - $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | ||
781 | - $this->link_nodes($node, false); | ||
782 | - return true; | ||
783 | - } | ||
784 | - | ||
785 | - if ($name!=='/' && $name!=='') { | ||
786 | - $space[1] = $this->copy_skip($this->token_blank); | ||
787 | - $name = $this->restore_noise($name); | ||
788 | - if ($this->lowercase) $name = strtolower($name); | ||
789 | - if ($this->char==='=') { | ||
790 | - $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | ||
791 | - $this->parse_attr($node, $name, $space); | ||
792 | - } | ||
793 | - else { | ||
794 | - //no value attr: nowrap, checked selected... | ||
795 | - $node->_[HDOM_INFO_QUOTE][] = HDOM_QUOTE_NO; | ||
796 | - $node->attr[$name] = true; | ||
797 | - if ($this->char!='>') $this->char = $this->doc[--$this->pos]; // prev | ||
798 | - } | ||
799 | - $node->_[HDOM_INFO_SPACE][] = $space; | ||
800 | - $space = array($this->copy_skip($this->token_blank), '', ''); | ||
801 | - } | ||
802 | - else | ||
803 | - break; | ||
804 | - } while($this->char!=='>' && $this->char!=='/'); | ||
805 | - | ||
806 | - $this->link_nodes($node, true); | ||
807 | - $node->_[HDOM_INFO_ENDSPACE] = $space[0]; | ||
808 | - | ||
809 | - // check self closing | ||
810 | - if ($this->copy_until_char_escape('>')==='/') { | ||
811 | - $node->_[HDOM_INFO_ENDSPACE] .= '/'; | ||
812 | - $node->_[HDOM_INFO_END] = 0; | ||
813 | - } | ||
814 | - else { | ||
815 | - // reset parent | ||
816 | - if (!isset($this->self_closing_tags[strtolower($node->tag)])) $this->parent = $node; | ||
817 | - } | ||
818 | - $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | ||
819 | - return true; | ||
820 | - } | ||
821 | - | ||
822 | - // parse attributes | ||
823 | - protected function parse_attr($node, $name, &$space) { | ||
824 | - $space[2] = $this->copy_skip($this->token_blank); | ||
825 | - switch($this->char) { | ||
826 | - case '"': | ||
827 | - $node->_[HDOM_INFO_QUOTE][] = HDOM_QUOTE_DOUBLE; | ||
828 | - $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | ||
829 | - $node->attr[$name] = $this->restore_noise($this->copy_until_char_escape('"')); | ||
830 | - $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | ||
831 | - break; | ||
832 | - case '\'': | ||
833 | - $node->_[HDOM_INFO_QUOTE][] = HDOM_QUOTE_SINGLE; | ||
834 | - $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | ||
835 | - $node->attr[$name] = $this->restore_noise($this->copy_until_char_escape('\'')); | ||
836 | - $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | ||
837 | - break; | ||
838 | - default: | ||
839 | - $node->_[HDOM_INFO_QUOTE][] = HDOM_QUOTE_NO; | ||
840 | - $node->attr[$name] = $this->restore_noise($this->copy_until($this->token_attr)); | ||
841 | - } | ||
842 | - } | ||
843 | - | ||
844 | - // link node's parent | ||
845 | - protected function link_nodes(&$node, $is_child) { | ||
846 | - $node->parent = $this->parent; | ||
847 | - $this->parent->nodes[] = $node; | ||
848 | - if ($is_child) | ||
849 | - $this->parent->children[] = $node; | ||
850 | - } | ||
851 | - | ||
852 | - // as a text node | ||
853 | - protected function as_text_node($tag) { | ||
854 | - $node = new simple_html_dom_node($this); | ||
855 | - ++$this->cursor; | ||
856 | - $node->_[HDOM_INFO_TEXT] = '</' . $tag . '>'; | ||
857 | - $this->link_nodes($node, false); | ||
858 | - $this->char = (++$this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | ||
859 | - return true; | ||
860 | - } | ||
861 | - | ||
862 | - protected function skip($chars) { | ||
863 | - $this->pos += strspn($this->doc, $chars, $this->pos); | ||
864 | - $this->char = ($this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | ||
865 | - } | ||
866 | - | ||
867 | - protected function copy_skip($chars) { | ||
868 | - $pos = $this->pos; | ||
869 | - $len = strspn($this->doc, $chars, $pos); | ||
870 | - $this->pos += $len; | ||
871 | - $this->char = ($this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | ||
872 | - if ($len===0) return ''; | ||
873 | - return substr($this->doc, $pos, $len); | ||
874 | - } | ||
875 | - | ||
876 | - protected function copy_until($chars) { | ||
877 | - $pos = $this->pos; | ||
878 | - $len = strcspn($this->doc, $chars, $pos); | ||
879 | - $this->pos += $len; | ||
880 | - $this->char = ($this->pos<$this->size) ? $this->doc[$this->pos] : null; // next | ||
881 | - return substr($this->doc, $pos, $len); | ||
882 | - } | ||
883 | - | ||
884 | - protected function copy_until_char($char) { | ||
885 | - if ($this->char===null) return ''; | ||
886 | - | ||
887 | - if (($pos = strpos($this->doc, $char, $this->pos))===false) { | ||
888 | - $ret = substr($this->doc, $this->pos, $this->size-$this->pos); | ||
889 | - $this->char = null; | ||
890 | - $this->pos = $this->size; | ||
891 | - return $ret; | ||
892 | - } | ||
893 | - | ||
894 | - if ($pos===$this->pos) return ''; | ||
895 | - $pos_old = $this->pos; | ||
896 | - $this->char = $this->doc[$pos]; | ||
897 | - $this->pos = $pos; | ||
898 | - return substr($this->doc, $pos_old, $pos-$pos_old); | ||
899 | - } | ||
900 | - | ||
901 | - protected function copy_until_char_escape($char) { | ||
902 | - if ($this->char===null) return ''; | ||
903 | - | ||
904 | - $start = $this->pos; | ||
905 | - while(1) { | ||
906 | - if (($pos = strpos($this->doc, $char, $start))===false) { | ||
907 | - $ret = substr($this->doc, $this->pos, $this->size-$this->pos); | ||
908 | - $this->char = null; | ||
909 | - $this->pos = $this->size; | ||
910 | - return $ret; | ||
911 | - } | ||
912 | - | ||
913 | - if ($pos===$this->pos) return ''; | ||
914 | - | ||
915 | - if ($this->doc[$pos-1]==='\\') { | ||
916 | - $start = $pos+1; | ||
917 | - continue; | ||
918 | - } | ||
919 | - | ||
920 | - $pos_old = $this->pos; | ||
921 | - $this->char = $this->doc[$pos]; | ||
922 | - $this->pos = $pos; | ||
923 | - return substr($this->doc, $pos_old, $pos-$pos_old); | ||
924 | - } | ||
925 | - } | ||
926 | - | ||
927 | - // remove noise from html content | ||
928 | - protected function remove_noise($pattern, $remove_tag=false) { | ||
929 | - $count = preg_match_all($pattern, $this->doc, $matches, PREG_SET_ORDER|PREG_OFFSET_CAPTURE); | ||
930 | - | ||
931 | - for ($i=$count-1; $i>-1; --$i) { | ||
932 | - $key = '___noise___'.sprintf('% 3d', count($this->noise)+100); | ||
933 | - $idx = ($remove_tag) ? 0 : 1; | ||
934 | - $this->noise[$key] = $matches[$i][$idx][0]; | ||
935 | - $this->doc = substr_replace($this->doc, $key, $matches[$i][$idx][1], strlen($matches[$i][$idx][0])); | ||
936 | - } | ||
937 | - | ||
938 | - // reset the length of content | ||
939 | - $this->size = strlen($this->doc); | ||
940 | - if ($this->size>0) $this->char = $this->doc[0]; | ||
941 | - } | ||
942 | - | ||
943 | - // restore noise to html content | ||
944 | - function restore_noise($text) { | ||
945 | - while(($pos=strpos($text, '___noise___'))!==false) { | ||
946 | - $key = '___noise___'.$text[$pos+11].$text[$pos+12].$text[$pos+13]; | ||
947 | - if (isset($this->noise[$key])) | ||
948 | - $text = substr($text, 0, $pos).$this->noise[$key].substr($text, $pos+14); | ||
949 | - } | ||
950 | - return $text; | ||
951 | - } | ||
952 | - | ||
953 | - function __toString() { | ||
954 | - return $this->root->innertext(); | ||
955 | - } | ||
956 | - | ||
957 | - function __get($name) { | ||
958 | - switch($name) { | ||
959 | - case 'outertext': return $this->root->innertext(); | ||
960 | - case 'innertext': return $this->root->innertext(); | ||
961 | - case 'plaintext': return $this->root->text(); | ||
962 | - } | ||
963 | - } | ||
964 | - | ||
965 | - // camel naming conventions | ||
966 | - function childNodes($idx=-1) {return $this->root->childNodes($idx);} | ||
967 | - function firstChild() {return $this->root->first_child();} | ||
968 | - function lastChild() {return $this->root->last_child();} | ||
969 | - function getElementById($id) {return $this->find("#$id", 0);} | ||
970 | - function getElementsById($id, $idx=null) {return $this->find("#$id", $idx);} | ||
971 | - function getElementByTagName($name) {return $this->find($name, 0);} | ||
972 | - function getElementsByTagName($name, $idx=-1) {return $this->find($name, $idx);} | ||
973 | - function loadFile() {$args = func_get_args();$this->load(call_user_func_array('file_get_contents', $args), true);} | ||
974 | -} | ||
975 | -?> | ||
976 | \ No newline at end of file | 1 | \ No newline at end of file |
2 | +<?php | ||
3 | +/** | ||
4 | + * Website: http://sourceforge.net/projects/simplehtmldom/ | ||
5 | + * Additional projects: http://sourceforge.net/projects/debugobject/ | ||
6 | + * Acknowledge: Jose Solorzano (https://sourceforge.net/projects/php-html/) | ||
7 | + * | ||
8 | + * Licensed under The MIT License | ||
9 | + * See the LICENSE file in the project root for more information. | ||
10 | + * | ||
11 | + * Authors: | ||
12 | + * S.C. Chen | ||
13 | + * John Schlick | ||
14 | + * Rus Carroll | ||
15 | + * logmanoriginal | ||
16 | + * | ||
17 | + * Contributors: | ||
18 | + * Yousuke Kumakura | ||
19 | + * Vadim Voituk | ||
20 | + * Antcs | ||
21 | + * | ||
22 | + * Version Rev. 1.9 (290) | ||
23 | + */ | ||
24 | + | ||
25 | +define('HDOM_TYPE_ELEMENT', 1); | ||
26 | +define('HDOM_TYPE_COMMENT', 2); | ||
27 | +define('HDOM_TYPE_TEXT', 3); | ||
28 | +define('HDOM_TYPE_ENDTAG', 4); | ||
29 | +define('HDOM_TYPE_ROOT', 5); | ||
30 | +define('HDOM_TYPE_UNKNOWN', 6); | ||
31 | +define('HDOM_QUOTE_DOUBLE', 0); | ||
32 | +define('HDOM_QUOTE_SINGLE', 1); | ||
33 | +define('HDOM_QUOTE_NO', 3); | ||
34 | +define('HDOM_INFO_BEGIN', 0); | ||
35 | +define('HDOM_INFO_END', 1); | ||
36 | +define('HDOM_INFO_QUOTE', 2); | ||
37 | +define('HDOM_INFO_SPACE', 3); | ||
38 | +define('HDOM_INFO_TEXT', 4); | ||
39 | +define('HDOM_INFO_INNER', 5); | ||
40 | +define('HDOM_INFO_OUTER', 6); | ||
41 | +define('HDOM_INFO_ENDSPACE', 7); | ||
42 | + | ||
43 | +defined('DEFAULT_TARGET_CHARSET') || define('DEFAULT_TARGET_CHARSET', 'UTF-8'); | ||
44 | +defined('DEFAULT_BR_TEXT') || define('DEFAULT_BR_TEXT', "\r\n"); | ||
45 | +defined('DEFAULT_SPAN_TEXT') || define('DEFAULT_SPAN_TEXT', ' '); | ||
46 | +defined('MAX_FILE_SIZE') || define('MAX_FILE_SIZE', 600000); | ||
47 | +define('HDOM_SMARTY_AS_TEXT', 1); | ||
48 | + | ||
49 | +function file_get_html( | ||
50 | + $url, | ||
51 | + $use_include_path = false, | ||
52 | + $context = null, | ||
53 | + $offset = 0, | ||
54 | + $maxLen = -1, | ||
55 | + $lowercase = true, | ||
56 | + $forceTagsClosed = true, | ||
57 | + $target_charset = DEFAULT_TARGET_CHARSET, | ||
58 | + $stripRN = true, | ||
59 | + $defaultBRText = DEFAULT_BR_TEXT, | ||
60 | + $defaultSpanText = DEFAULT_SPAN_TEXT) | ||
61 | +{ | ||
62 | + if($maxLen <= 0) { $maxLen = MAX_FILE_SIZE; } | ||
63 | + | ||
64 | + $dom = new simple_html_dom( | ||
65 | + null, | ||
66 | + $lowercase, | ||
67 | + $forceTagsClosed, | ||
68 | + $target_charset, | ||
69 | + $stripRN, | ||
70 | + $defaultBRText, | ||
71 | + $defaultSpanText | ||
72 | + ); | ||
73 | + | ||
74 | + /** | ||
75 | + * For sourceforge users: uncomment the next line and comment the | ||
76 | + * retrieve_url_contents line 2 lines down if it is not already done. | ||
77 | + */ | ||
78 | + $contents = file_get_contents( | ||
79 | + $url, | ||
80 | + $use_include_path, | ||
81 | + $context, | ||
82 | + $offset, | ||
83 | + $maxLen | ||
84 | + ); | ||
85 | + // $contents = retrieve_url_contents($url); | ||
86 | + | ||
87 | + if (empty($contents) || strlen($contents) > $maxLen) { | ||
88 | + $dom->clear(); | ||
89 | + return false; | ||
90 | + } | ||
91 | + | ||
92 | + return $dom->load($contents, $lowercase, $stripRN); | ||
93 | +} | ||
94 | + | ||
95 | +function str_get_html( | ||
96 | + $str, | ||
97 | + $lowercase = true, | ||
98 | + $forceTagsClosed = true, | ||
99 | + $target_charset = DEFAULT_TARGET_CHARSET, | ||
100 | + $stripRN = true, | ||
101 | + $defaultBRText = DEFAULT_BR_TEXT, | ||
102 | + $defaultSpanText = DEFAULT_SPAN_TEXT) | ||
103 | +{ | ||
104 | + $dom = new simple_html_dom( | ||
105 | + null, | ||
106 | + $lowercase, | ||
107 | + $forceTagsClosed, | ||
108 | + $target_charset, | ||
109 | + $stripRN, | ||
110 | + $defaultBRText, | ||
111 | + $defaultSpanText | ||
112 | + ); | ||
113 | + | ||
114 | + if (empty($str) || strlen($str) > MAX_FILE_SIZE) { | ||
115 | + $dom->clear(); | ||
116 | + return false; | ||
117 | + } | ||
118 | + | ||
119 | + return $dom->load($str, $lowercase, $stripRN); | ||
120 | +} | ||
121 | + | ||
122 | +function dump_html_tree($node, $show_attr = true, $deep = 0) | ||
123 | +{ | ||
124 | + $node->dump($node); | ||
125 | +} | ||
126 | + | ||
127 | +class simple_html_dom_node | ||
128 | +{ | ||
129 | + public $nodetype = HDOM_TYPE_TEXT; | ||
130 | + public $tag = 'text'; | ||
131 | + public $attr = array(); | ||
132 | + public $children = array(); | ||
133 | + public $nodes = array(); | ||
134 | + public $parent = null; | ||
135 | + public $_ = array(); | ||
136 | + public $tag_start = 0; | ||
137 | + private $dom = null; | ||
138 | + | ||
139 | + function __construct($dom) | ||
140 | + { | ||
141 | + $this->dom = $dom; | ||
142 | + $dom->nodes[] = $this; | ||
143 | + } | ||
144 | + | ||
145 | + function __destruct() | ||
146 | + { | ||
147 | + $this->clear(); | ||
148 | + } | ||
149 | + | ||
150 | + function __toString() | ||
151 | + { | ||
152 | + return $this->outertext(); | ||
153 | + } | ||
154 | + | ||
155 | + function clear() | ||
156 | + { | ||
157 | + $this->dom = null; | ||
158 | + $this->nodes = null; | ||
159 | + $this->parent = null; | ||
160 | + $this->children = null; | ||
161 | + } | ||
162 | + | ||
163 | + function dump($show_attr = true, $depth = 0) | ||
164 | + { | ||
165 | + echo str_repeat("\t", $depth) . $this->tag; | ||
166 | + | ||
167 | + if ($show_attr && count($this->attr) > 0) { | ||
168 | + echo '('; | ||
169 | + foreach ($this->attr as $k => $v) { | ||
170 | + echo "[$k]=>\"$v\", "; | ||
171 | + } | ||
172 | + echo ')'; | ||
173 | + } | ||
174 | + | ||
175 | + echo "\n"; | ||
176 | + | ||
177 | + if ($this->nodes) { | ||
178 | + foreach ($this->nodes as $node) { | ||
179 | + $node->dump($show_attr, $depth + 1); | ||
180 | + } | ||
181 | + } | ||
182 | + } | ||
183 | + | ||
184 | + function dump_node($echo = true) | ||
185 | + { | ||
186 | + $string = $this->tag; | ||
187 | + | ||
188 | + if (count($this->attr) > 0) { | ||
189 | + $string .= '('; | ||
190 | + foreach ($this->attr as $k => $v) { | ||
191 | + $string .= "[$k]=>\"$v\", "; | ||
192 | + } | ||
193 | + $string .= ')'; | ||
194 | + } | ||
195 | + | ||
196 | + if (count($this->_) > 0) { | ||
197 | + $string .= ' $_ ('; | ||
198 | + foreach ($this->_ as $k => $v) { | ||
199 | + if (is_array($v)) { | ||
200 | + $string .= "[$k]=>("; | ||
201 | + foreach ($v as $k2 => $v2) { | ||
202 | + $string .= "[$k2]=>\"$v2\", "; | ||
203 | + } | ||
204 | + $string .= ')'; | ||
205 | + } else { | ||
206 | + $string .= "[$k]=>\"$v\", "; | ||
207 | + } | ||
208 | + } | ||
209 | + $string .= ')'; | ||
210 | + } | ||
211 | + | ||
212 | + if (isset($this->text)) { | ||
213 | + $string .= " text: ({$this->text})"; | ||
214 | + } | ||
215 | + | ||
216 | + $string .= ' HDOM_INNER_INFO: '; | ||
217 | + | ||
218 | + if (isset($node->_[HDOM_INFO_INNER])) { | ||
219 | + $string .= "'" . $node->_[HDOM_INFO_INNER] . "'"; | ||
220 | + } else { | ||
221 | + $string .= ' NULL '; | ||
222 | + } | ||
223 | + | ||
224 | + $string .= ' children: ' . count($this->children); | ||
225 | + $string .= ' nodes: ' . count($this->nodes); | ||
226 | + $string .= ' tag_start: ' . $this->tag_start; | ||
227 | + $string .= "\n"; | ||
228 | + | ||
229 | + if ($echo) { | ||
230 | + echo $string; | ||
231 | + return; | ||
232 | + } else { | ||
233 | + return $string; | ||
234 | + } | ||
235 | + } | ||
236 | + | ||
237 | + function parent($parent = null) | ||
238 | + { | ||
239 | + // I am SURE that this doesn't work properly. | ||
240 | + // It fails to unset the current node from it's current parents nodes or | ||
241 | + // children list first. | ||
242 | + if ($parent !== null) { | ||
243 | + $this->parent = $parent; | ||
244 | + $this->parent->nodes[] = $this; | ||
245 | + $this->parent->children[] = $this; | ||
246 | + } | ||
247 | + | ||
248 | + return $this->parent; | ||
249 | + } | ||
250 | + | ||
251 | + function has_child() | ||
252 | + { | ||
253 | + return !empty($this->children); | ||
254 | + } | ||
255 | + | ||
256 | + function children($idx = -1) | ||
257 | + { | ||
258 | + if ($idx === -1) { | ||
259 | + return $this->children; | ||
260 | + } | ||
261 | + | ||
262 | + if (isset($this->children[$idx])) { | ||
263 | + return $this->children[$idx]; | ||
264 | + } | ||
265 | + | ||
266 | + return null; | ||
267 | + } | ||
268 | + | ||
269 | + function first_child() | ||
270 | + { | ||
271 | + if (count($this->children) > 0) { | ||
272 | + return $this->children[0]; | ||
273 | + } | ||
274 | + return null; | ||
275 | + } | ||
276 | + | ||
277 | + function last_child() | ||
278 | + { | ||
279 | + if (count($this->children) > 0) { | ||
280 | + return end($this->children); | ||
281 | + } | ||
282 | + return null; | ||
283 | + } | ||
284 | + | ||
285 | + function next_sibling() | ||
286 | + { | ||
287 | + if ($this->parent === null) { | ||
288 | + return null; | ||
289 | + } | ||
290 | + | ||
291 | + $idx = array_search($this, $this->parent->children, true); | ||
292 | + | ||
293 | + if ($idx !== false && isset($this->parent->children[$idx + 1])) { | ||
294 | + return $this->parent->children[$idx + 1]; | ||
295 | + } | ||
296 | + | ||
297 | + return null; | ||
298 | + } | ||
299 | + | ||
300 | + function prev_sibling() | ||
301 | + { | ||
302 | + if ($this->parent === null) { | ||
303 | + return null; | ||
304 | + } | ||
305 | + | ||
306 | + $idx = array_search($this, $this->parent->children, true); | ||
307 | + | ||
308 | + if ($idx !== false && $idx > 0) { | ||
309 | + return $this->parent->children[$idx - 1]; | ||
310 | + } | ||
311 | + | ||
312 | + return null; | ||
313 | + } | ||
314 | + | ||
315 | + function find_ancestor_tag($tag) | ||
316 | + { | ||
317 | + global $debug_object; | ||
318 | + if (is_object($debug_object)) { $debug_object->debug_log_entry(1); } | ||
319 | + | ||
320 | + if ($this->parent === null) { | ||
321 | + return null; | ||
322 | + } | ||
323 | + | ||
324 | + $ancestor = $this->parent; | ||
325 | + | ||
326 | + while (!is_null($ancestor)) { | ||
327 | + if (is_object($debug_object)) { | ||
328 | + $debug_object->debug_log(2, 'Current tag is: ' . $ancestor->tag); | ||
329 | + } | ||
330 | + | ||
331 | + if ($ancestor->tag === $tag) { | ||
332 | + break; | ||
333 | + } | ||
334 | + | ||
335 | + $ancestor = $ancestor->parent; | ||
336 | + } | ||
337 | + | ||
338 | + return $ancestor; | ||
339 | + } | ||
340 | + | ||
341 | + function innertext() | ||
342 | + { | ||
343 | + if (isset($this->_[HDOM_INFO_INNER])) { | ||
344 | + return $this->_[HDOM_INFO_INNER]; | ||
345 | + } | ||
346 | + | ||
347 | + if (isset($this->_[HDOM_INFO_TEXT])) { | ||
348 | + return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]); | ||
349 | + } | ||
350 | + | ||
351 | + $ret = ''; | ||
352 | + | ||
353 | + foreach ($this->nodes as $n) { | ||
354 | + $ret .= $n->outertext(); | ||
355 | + } | ||
356 | + | ||
357 | + return $ret; | ||
358 | + } | ||
359 | + | ||
360 | + function outertext() | ||
361 | + { | ||
362 | + global $debug_object; | ||
363 | + | ||
364 | + if (is_object($debug_object)) { | ||
365 | + $text = ''; | ||
366 | + | ||
367 | + if ($this->tag === 'text') { | ||
368 | + if (!empty($this->text)) { | ||
369 | + $text = ' with text: ' . $this->text; | ||
370 | + } | ||
371 | + } | ||
372 | + | ||
373 | + $debug_object->debug_log(1, 'Innertext of tag: ' . $this->tag . $text); | ||
374 | + } | ||
375 | + | ||
376 | + if ($this->tag === 'root') { | ||
377 | + return $this->innertext(); | ||
378 | + } | ||
379 | + | ||
380 | + // todo: What is the use of this callback? Remove? | ||
381 | + if ($this->dom && $this->dom->callback !== null) { | ||
382 | + call_user_func_array($this->dom->callback, array($this)); | ||
383 | + } | ||
384 | + | ||
385 | + if (isset($this->_[HDOM_INFO_OUTER])) { | ||
386 | + return $this->_[HDOM_INFO_OUTER]; | ||
387 | + } | ||
388 | + | ||
389 | + if (isset($this->_[HDOM_INFO_TEXT])) { | ||
390 | + return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]); | ||
391 | + } | ||
392 | + | ||
393 | + $ret = ''; | ||
394 | + | ||
395 | + if ($this->dom && $this->dom->nodes[$this->_[HDOM_INFO_BEGIN]]) { | ||
396 | + $ret = $this->dom->nodes[$this->_[HDOM_INFO_BEGIN]]->makeup(); | ||
397 | + } | ||
398 | + | ||
399 | + if (isset($this->_[HDOM_INFO_INNER])) { | ||
400 | + // todo: <br> should either never have HDOM_INFO_INNER or always | ||
401 | + if ($this->tag !== 'br') { | ||
402 | + $ret .= $this->_[HDOM_INFO_INNER]; | ||
403 | + } | ||
404 | + } elseif ($this->nodes) { | ||
405 | + foreach ($this->nodes as $n) { | ||
406 | + $ret .= $this->convert_text($n->outertext()); | ||
407 | + } | ||
408 | + } | ||
409 | + | ||
410 | + if (isset($this->_[HDOM_INFO_END]) && $this->_[HDOM_INFO_END] != 0) { | ||
411 | + $ret .= '</' . $this->tag . '>'; | ||
412 | + } | ||
413 | + | ||
414 | + return $ret; | ||
415 | + } | ||
416 | + | ||
417 | + function text() | ||
418 | + { | ||
419 | + if (isset($this->_[HDOM_INFO_INNER])) { | ||
420 | + return $this->_[HDOM_INFO_INNER]; | ||
421 | + } | ||
422 | + | ||
423 | + switch ($this->nodetype) { | ||
424 | + case HDOM_TYPE_TEXT: return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]); | ||
425 | + case HDOM_TYPE_COMMENT: return ''; | ||
426 | + case HDOM_TYPE_UNKNOWN: return ''; | ||
427 | + } | ||
428 | + | ||
429 | + if (strcasecmp($this->tag, 'script') === 0) { return ''; } | ||
430 | + if (strcasecmp($this->tag, 'style') === 0) { return ''; } | ||
431 | + | ||
432 | + $ret = ''; | ||
433 | + | ||
434 | + // In rare cases, (always node type 1 or HDOM_TYPE_ELEMENT - observed | ||
435 | + // for some span tags, and some p tags) $this->nodes is set to NULL. | ||
436 | + // NOTE: This indicates that there is a problem where it's set to NULL | ||
437 | + // without a clear happening. | ||
438 | + // WHY is this happening? | ||
439 | + if (!is_null($this->nodes)) { | ||
440 | + foreach ($this->nodes as $n) { | ||
441 | + // Start paragraph after a blank line | ||
442 | + if ($n->tag === 'p') { | ||
443 | + $ret = trim($ret) . "\n\n"; | ||
444 | + } | ||
445 | + | ||
446 | + $ret .= $this->convert_text($n->text()); | ||
447 | + | ||
448 | + // If this node is a span... add a space at the end of it so | ||
449 | + // multiple spans don't run into each other. This is plaintext | ||
450 | + // after all. | ||
451 | + if ($n->tag === 'span') { | ||
452 | + $ret .= $this->dom->default_span_text; | ||
453 | + } | ||
454 | + } | ||
455 | + } | ||
456 | + return $ret; | ||
457 | + } | ||
458 | + | ||
459 | + function xmltext() | ||
460 | + { | ||
461 | + $ret = $this->innertext(); | ||
462 | + $ret = str_ireplace('<![CDATA[', '', $ret); | ||
463 | + $ret = str_replace(']]>', '', $ret); | ||
464 | + return $ret; | ||
465 | + } | ||
466 | + | ||
467 | + function makeup() | ||
468 | + { | ||
469 | + // text, comment, unknown | ||
470 | + if (isset($this->_[HDOM_INFO_TEXT])) { | ||
471 | + return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]); | ||
472 | + } | ||
473 | + | ||
474 | + $ret = '<' . $this->tag; | ||
475 | + $i = -1; | ||
476 | + | ||
477 | + foreach ($this->attr as $key => $val) { | ||
478 | + ++$i; | ||
479 | + | ||
480 | + // skip removed attribute | ||
481 | + if ($val === null || $val === false) { continue; } | ||
482 | + | ||
483 | + $ret .= $this->_[HDOM_INFO_SPACE][$i][0]; | ||
484 | + | ||
485 | + //no value attr: nowrap, checked selected... | ||
486 | + if ($val === true) { | ||
487 | + $ret .= $key; | ||
488 | + } else { | ||
489 | + switch ($this->_[HDOM_INFO_QUOTE][$i]) | ||
490 | + { | ||
491 | + case HDOM_QUOTE_DOUBLE: $quote = '"'; break; | ||
492 | + case HDOM_QUOTE_SINGLE: $quote = '\''; break; | ||
493 | + default: $quote = ''; | ||
494 | + } | ||
495 | + | ||
496 | + $ret .= $key | ||
497 | + . $this->_[HDOM_INFO_SPACE][$i][1] | ||
498 | + . '=' | ||
499 | + . $this->_[HDOM_INFO_SPACE][$i][2] | ||
500 | + . $quote | ||
501 | + . $val | ||
502 | + . $quote; | ||
503 | + } | ||
504 | + } | ||
505 | + | ||
506 | + $ret = $this->dom->restore_noise($ret); | ||
507 | + return $ret . $this->_[HDOM_INFO_ENDSPACE] . '>'; | ||
508 | + } | ||
509 | + | ||
510 | + function find($selector, $idx = null, $lowercase = false) | ||
511 | + { | ||
512 | + $selectors = $this->parse_selector($selector); | ||
513 | + if (($count = count($selectors)) === 0) { return array(); } | ||
514 | + $found_keys = array(); | ||
515 | + | ||
516 | + // find each selector | ||
517 | + for ($c = 0; $c < $count; ++$c) { | ||
518 | + // The change on the below line was documented on the sourceforge | ||
519 | + // code tracker id 2788009 | ||
520 | + // used to be: if (($levle=count($selectors[0]))===0) return array(); | ||
521 | + if (($levle = count($selectors[$c])) === 0) { return array(); } | ||
522 | + if (!isset($this->_[HDOM_INFO_BEGIN])) { return array(); } | ||
523 | + | ||
524 | + $head = array($this->_[HDOM_INFO_BEGIN] => 1); | ||
525 | + $cmd = ' '; // Combinator | ||
526 | + | ||
527 | + // handle descendant selectors, no recursive! | ||
528 | + for ($l = 0; $l < $levle; ++$l) { | ||
529 | + $ret = array(); | ||
530 | + | ||
531 | + foreach ($head as $k => $v) { | ||
532 | + $n = ($k === -1) ? $this->dom->root : $this->dom->nodes[$k]; | ||
533 | + //PaperG - Pass this optional parameter on to the seek function. | ||
534 | + $n->seek($selectors[$c][$l], $ret, $cmd, $lowercase); | ||
535 | + } | ||
536 | + | ||
537 | + $head = $ret; | ||
538 | + $cmd = $selectors[$c][$l][4]; // Next Combinator | ||
539 | + } | ||
540 | + | ||
541 | + foreach ($head as $k => $v) { | ||
542 | + if (!isset($found_keys[$k])) { | ||
543 | + $found_keys[$k] = 1; | ||
544 | + } | ||
545 | + } | ||
546 | + } | ||
547 | + | ||
548 | + // sort keys | ||
549 | + ksort($found_keys); | ||
550 | + | ||
551 | + $found = array(); | ||
552 | + foreach ($found_keys as $k => $v) { | ||
553 | + $found[] = $this->dom->nodes[$k]; | ||
554 | + } | ||
555 | + | ||
556 | + // return nth-element or array | ||
557 | + if (is_null($idx)) { return $found; } | ||
558 | + elseif ($idx < 0) { $idx = count($found) + $idx; } | ||
559 | + return (isset($found[$idx])) ? $found[$idx] : null; | ||
560 | + } | ||
561 | + | ||
562 | + protected function seek($selector, &$ret, $parent_cmd, $lowercase = false) | ||
563 | + { | ||
564 | + global $debug_object; | ||
565 | + if (is_object($debug_object)) { $debug_object->debug_log_entry(1); } | ||
566 | + | ||
567 | + list($tag, $id, $class, $attributes, $cmb) = $selector; | ||
568 | + $nodes = array(); | ||
569 | + | ||
570 | + if ($parent_cmd === ' ') { // Descendant Combinator | ||
571 | + // Find parent closing tag if the current element doesn't have a closing | ||
572 | + // tag (i.e. void element) | ||
573 | + $end = (!empty($this->_[HDOM_INFO_END])) ? $this->_[HDOM_INFO_END] : 0; | ||
574 | + if ($end == 0) { | ||
575 | + $parent = $this->parent; | ||
576 | + while (!isset($parent->_[HDOM_INFO_END]) && $parent !== null) { | ||
577 | + $end -= 1; | ||
578 | + $parent = $parent->parent; | ||
579 | + } | ||
580 | + $end += $parent->_[HDOM_INFO_END]; | ||
581 | + } | ||
582 | + | ||
583 | + // Get list of target nodes | ||
584 | + $nodes_start = $this->_[HDOM_INFO_BEGIN] + 1; | ||
585 | + $nodes_count = $end - $nodes_start; | ||
586 | + $nodes = array_slice($this->dom->nodes, $nodes_start, $nodes_count, true); | ||
587 | + } elseif ($parent_cmd === '>') { // Child Combinator | ||
588 | + $nodes = $this->children; | ||
589 | + } elseif ($parent_cmd === '+' | ||
590 | + && $this->parent | ||
591 | + && in_array($this, $this->parent->children)) { // Next-Sibling Combinator | ||
592 | + $index = array_search($this, $this->parent->children, true) + 1; | ||
593 | + if ($index < count($this->parent->children)) | ||
594 | + $nodes[] = $this->parent->children[$index]; | ||
595 | + } elseif ($parent_cmd === '~' | ||
596 | + && $this->parent | ||
597 | + && in_array($this, $this->parent->children)) { // Subsequent Sibling Combinator | ||
598 | + $index = array_search($this, $this->parent->children, true); | ||
599 | + $nodes = array_slice($this->parent->children, $index); | ||
600 | + } | ||
601 | + | ||
602 | + // Go throgh each element starting at this element until the end tag | ||
603 | + // Note: If this element is a void tag, any previous void element is | ||
604 | + // skipped. | ||
605 | + foreach($nodes as $node) { | ||
606 | + $pass = true; | ||
607 | + | ||
608 | + // Skip root nodes | ||
609 | + if(!$node->parent) { | ||
610 | + $pass = false; | ||
611 | + } | ||
612 | + | ||
613 | + // Skip if node isn't a child node (i.e. text nodes) | ||
614 | + if($pass && !in_array($node, $node->parent->children, true)) { | ||
615 | + $pass = false; | ||
616 | + } | ||
617 | + | ||
618 | + // Skip if tag doesn't match | ||
619 | + if ($pass && $tag !== '' && $tag !== $node->tag && $tag !== '*') { | ||
620 | + $pass = false; | ||
621 | + } | ||
622 | + | ||
623 | + // Skip if ID doesn't exist | ||
624 | + if ($pass && $id !== '' && !isset($node->attr['id'])) { | ||
625 | + $pass = false; | ||
626 | + } | ||
627 | + | ||
628 | + // Check if ID matches | ||
629 | + if ($pass && $id !== '' && isset($node->attr['id'])) { | ||
630 | + // Note: Only consider the first ID (as browsers do) | ||
631 | + $node_id = explode(' ', trim($node->attr['id']))[0]; | ||
632 | + | ||
633 | + if($id !== $node_id) { $pass = false; } | ||
634 | + } | ||
635 | + | ||
636 | + // Check if all class(es) exist | ||
637 | + if ($pass && $class !== '' && is_array($class) && !empty($class)) { | ||
638 | + if (isset($node->attr['class'])) { | ||
639 | + $node_classes = explode(' ', $node->attr['class']); | ||
640 | + | ||
641 | + if ($lowercase) { | ||
642 | + $node_classes = array_map('strtolower', $node_classes); | ||
643 | + } | ||
644 | + | ||
645 | + foreach($class as $c) { | ||
646 | + if(!in_array($c, $node_classes)) { | ||
647 | + $pass = false; | ||
648 | + break; | ||
649 | + } | ||
650 | + } | ||
651 | + } else { | ||
652 | + $pass = false; | ||
653 | + } | ||
654 | + } | ||
655 | + | ||
656 | + // Check attributes | ||
657 | + if ($pass | ||
658 | + && $attributes !== '' | ||
659 | + && is_array($attributes) | ||
660 | + && !empty($attributes)) { | ||
661 | + foreach($attributes as $a) { | ||
662 | + list ( | ||
663 | + $att_name, | ||
664 | + $att_expr, | ||
665 | + $att_val, | ||
666 | + $att_inv, | ||
667 | + $att_case_sensitivity | ||
668 | + ) = $a; | ||
669 | + | ||
670 | + // Handle indexing attributes (i.e. "[2]") | ||
671 | + /** | ||
672 | + * Note: This is not supported by the CSS Standard but adds | ||
673 | + * the ability to select items compatible to XPath (i.e. | ||
674 | + * the 3rd element within it's parent). | ||
675 | + * | ||
676 | + * Note: This doesn't conflict with the CSS Standard which | ||
677 | + * doesn't work on numeric attributes anyway. | ||
678 | + */ | ||
679 | + if (is_numeric($att_name) | ||
680 | + && $att_expr === '' | ||
681 | + && $att_val === '') { | ||
682 | + $count = 0; | ||
683 | + | ||
684 | + // Find index of current element in parent | ||
685 | + foreach ($node->parent->children as $c) { | ||
686 | + if ($c->tag === $node->tag) ++$count; | ||
687 | + if ($c === $node) break; | ||
688 | + } | ||
689 | + | ||
690 | + // If this is the correct node, continue with next | ||
691 | + // attribute | ||
692 | + if ($count === (int)$att_name) continue; | ||
693 | + } | ||
694 | + | ||
695 | + // Check attribute availability | ||
696 | + if ($att_inv) { // Attribute should NOT be set | ||
697 | + if (isset($node->attr[$att_name])) { | ||
698 | + $pass = false; | ||
699 | + break; | ||
700 | + } | ||
701 | + } else { // Attribute should be set | ||
702 | + // todo: "plaintext" is not a valid CSS selector! | ||
703 | + if ($att_name !== 'plaintext' | ||
704 | + && !isset($node->attr[$att_name])) { | ||
705 | + $pass = false; | ||
706 | + break; | ||
707 | + } | ||
708 | + } | ||
709 | + | ||
710 | + // Continue with next attribute if expression isn't defined | ||
711 | + if ($att_expr === '') continue; | ||
712 | + | ||
713 | + // If they have told us that this is a "plaintext" | ||
714 | + // search then we want the plaintext of the node - right? | ||
715 | + // todo "plaintext" is not a valid CSS selector! | ||
716 | + if ($att_name === 'plaintext') { | ||
717 | + $nodeKeyValue = $node->text(); | ||
718 | + } else { | ||
719 | + $nodeKeyValue = $node->attr[$att_name]; | ||
720 | + } | ||
721 | + | ||
722 | + if (is_object($debug_object)) { | ||
723 | + $debug_object->debug_log(2, | ||
724 | + 'testing node: ' | ||
725 | + . $node->tag | ||
726 | + . ' for attribute: ' | ||
727 | + . $att_name | ||
728 | + . $att_expr | ||
729 | + . $att_val | ||
730 | + . ' where nodes value is: ' | ||
731 | + . $nodeKeyValue | ||
732 | + ); | ||
733 | + } | ||
734 | + | ||
735 | + // If lowercase is set, do a case insensitive test of | ||
736 | + // the value of the selector. | ||
737 | + if ($lowercase) { | ||
738 | + $check = $this->match( | ||
739 | + $att_expr, | ||
740 | + strtolower($att_val), | ||
741 | + strtolower($nodeKeyValue), | ||
742 | + $att_case_sensitivity | ||
743 | + ); | ||
744 | + } else { | ||
745 | + $check = $this->match( | ||
746 | + $att_expr, | ||
747 | + $att_val, | ||
748 | + $nodeKeyValue, | ||
749 | + $att_case_sensitivity | ||
750 | + ); | ||
751 | + } | ||
752 | + | ||
753 | + if (is_object($debug_object)) { | ||
754 | + $debug_object->debug_log(2, | ||
755 | + 'after match: ' | ||
756 | + . ($check ? 'true' : 'false') | ||
757 | + ); | ||
758 | + } | ||
759 | + | ||
760 | + if (!$check) { | ||
761 | + $pass = false; | ||
762 | + break; | ||
763 | + } | ||
764 | + } | ||
765 | + } | ||
766 | + | ||
767 | + // Found a match. Add to list and clear node | ||
768 | + if ($pass) $ret[$node->_[HDOM_INFO_BEGIN]] = 1; | ||
769 | + unset($node); | ||
770 | + } | ||
771 | + // It's passed by reference so this is actually what this function returns. | ||
772 | + if (is_object($debug_object)) { | ||
773 | + $debug_object->debug_log(1, 'EXIT - ret: ', $ret); | ||
774 | + } | ||
775 | + } | ||
776 | + | ||
777 | + protected function match($exp, $pattern, $value, $case_sensitivity) | ||
778 | + { | ||
779 | + global $debug_object; | ||
780 | + if (is_object($debug_object)) {$debug_object->debug_log_entry(1);} | ||
781 | + | ||
782 | + if ($case_sensitivity === 'i') { | ||
783 | + $pattern = strtolower($pattern); | ||
784 | + $value = strtolower($value); | ||
785 | + } | ||
786 | + | ||
787 | + switch ($exp) { | ||
788 | + case '=': | ||
789 | + return ($value === $pattern); | ||
790 | + case '!=': | ||
791 | + return ($value !== $pattern); | ||
792 | + case '^=': | ||
793 | + return preg_match('/^' . preg_quote($pattern, '/') . '/', $value); | ||
794 | + case '$=': | ||
795 | + return preg_match('/' . preg_quote($pattern, '/') . '$/', $value); | ||
796 | + case '*=': | ||
797 | + return preg_match('/' . preg_quote($pattern, '/') . '/', $value); | ||
798 | + case '|=': | ||
799 | + /** | ||
800 | + * [att|=val] | ||
801 | + * | ||
802 | + * Represents an element with the att attribute, its value | ||
803 | + * either being exactly "val" or beginning with "val" | ||
804 | + * immediately followed by "-" (U+002D). | ||
805 | + */ | ||
806 | + return strpos($value, $pattern) === 0; | ||
807 | + case '~=': | ||
808 | + /** | ||
809 | + * [att~=val] | ||
810 | + * | ||
811 | + * Represents an element with the att attribute whose value is a | ||
812 | + * whitespace-separated list of words, one of which is exactly | ||
813 | + * "val". If "val" contains whitespace, it will never represent | ||
814 | + * anything (since the words are separated by spaces). Also if | ||
815 | + * "val" is the empty string, it will never represent anything. | ||
816 | + */ | ||
817 | + return in_array($pattern, explode(' ', trim($value)), true); | ||
818 | + } | ||
819 | + return false; | ||
820 | + } | ||
821 | + | ||
822 | + protected function parse_selector($selector_string) | ||
823 | + { | ||
824 | + global $debug_object; | ||
825 | + if (is_object($debug_object)) { $debug_object->debug_log_entry(1); } | ||
826 | + | ||
827 | + /** | ||
828 | + * Pattern of CSS selectors, modified from mootools (https://mootools.net/) | ||
829 | + * | ||
830 | + * Paperg: Add the colon to the attribute, so that it properly finds | ||
831 | + * <tag attr:ibute="something" > like google does. | ||
832 | + * | ||
833 | + * Note: if you try to look at this attribute, you MUST use getAttribute | ||
834 | + * since $dom->x:y will fail the php syntax check. | ||
835 | + * | ||
836 | + * Notice the \[ starting the attribute? and the @? following? This | ||
837 | + * implies that an attribute can begin with an @ sign that is not | ||
838 | + * captured. This implies that an html attribute specifier may start | ||
839 | + * with an @ sign that is NOT captured by the expression. Farther study | ||
840 | + * is required to determine of this should be documented or removed. | ||
841 | + * | ||
842 | + * Matches selectors in this order: | ||
843 | + * | ||
844 | + * [0] - full match | ||
845 | + * | ||
846 | + * [1] - tag name | ||
847 | + * ([\w:\*-]*) | ||
848 | + * Matches the tag name consisting of zero or more words, colons, | ||
849 | + * asterisks and hyphens. | ||
850 | + * | ||
851 | + * [2] - id name | ||
852 | + * (?:\#([\w-]+)) | ||
853 | + * Optionally matches a id name, consisting of an "#" followed by | ||
854 | + * the id name (one or more words and hyphens). | ||
855 | + * | ||
856 | + * [3] - class names (including dots) | ||
857 | + * (?:\.([\w\.-]+))? | ||
858 | + * Optionally matches a list of classs, consisting of an "." | ||
859 | + * followed by the class name (one or more words and hyphens) | ||
860 | + * where multiple classes can be chained (i.e. ".foo.bar.baz") | ||
861 | + * | ||
862 | + * [4] - attributes | ||
863 | + * ((?:\[@?(?:!?[\w:-]+)(?:(?:[!*^$|~]?=)[\"']?(?:.*?)[\"']?)?(?:\s*?(?:[iIsS])?)?\])+)? | ||
864 | + * Optionally matches the attributes list | ||
865 | + * | ||
866 | + * [5] - separator | ||
867 | + * ([\/, >+~]+) | ||
868 | + * Matches the selector list separator | ||
869 | + */ | ||
870 | + // phpcs:ignore Generic.Files.LineLength | ||
871 | + $pattern = "/([\w:\*-]*)(?:\#([\w-]+))?(?:|\.([\w\.-]+))?((?:\[@?(?:!?[\w:-]+)(?:(?:[!*^$|~]?=)[\"']?(?:.*?)[\"']?)?(?:\s*?(?:[iIsS])?)?\])+)?([\/, >+~]+)/is"; | ||
872 | + | ||
873 | + preg_match_all( | ||
874 | + $pattern, | ||
875 | + trim($selector_string) . ' ', // Add final ' ' as pseudo separator | ||
876 | + $matches, | ||
877 | + PREG_SET_ORDER | ||
878 | + ); | ||
879 | + | ||
880 | + if (is_object($debug_object)) { | ||
881 | + $debug_object->debug_log(2, 'Matches Array: ', $matches); | ||
882 | + } | ||
883 | + | ||
884 | + $selectors = array(); | ||
885 | + $result = array(); | ||
886 | + | ||
887 | + foreach ($matches as $m) { | ||
888 | + $m[0] = trim($m[0]); | ||
889 | + | ||
890 | + // Skip NoOps | ||
891 | + if ($m[0] === '' || $m[0] === '/' || $m[0] === '//') { continue; } | ||
892 | + | ||
893 | + // Convert to lowercase | ||
894 | + if ($this->dom->lowercase) { | ||
895 | + $m[1] = strtolower($m[1]); | ||
896 | + } | ||
897 | + | ||
898 | + // Extract classes | ||
899 | + if ($m[3] !== '') { $m[3] = explode('.', $m[3]); } | ||
900 | + | ||
901 | + /* Extract attributes (pattern based on the pattern above!) | ||
902 | + | ||
903 | + * [0] - full match | ||
904 | + * [1] - attribute name | ||
905 | + * [2] - attribute expression | ||
906 | + * [3] - attribute value | ||
907 | + * [4] - case sensitivity | ||
908 | + * | ||
909 | + * Note: Attributes can be negated with a "!" prefix to their name | ||
910 | + */ | ||
911 | + if($m[4] !== '') { | ||
912 | + preg_match_all( | ||
913 | + "/\[@?(!?[\w:-]+)(?:([!*^$|~]?=)[\"']?(.*?)[\"']?)?(?:\s+?([iIsS])?)?\]/is", | ||
914 | + trim($m[4]), | ||
915 | + $attributes, | ||
916 | + PREG_SET_ORDER | ||
917 | + ); | ||
918 | + | ||
919 | + // Replace element by array | ||
920 | + $m[4] = array(); | ||
921 | + | ||
922 | + foreach($attributes as $att) { | ||
923 | + // Skip empty matches | ||
924 | + if(trim($att[0]) === '') { continue; } | ||
925 | + | ||
926 | + $inverted = (isset($att[1][0]) && $att[1][0] === '!'); | ||
927 | + $m[4][] = array( | ||
928 | + $inverted ? substr($att[1], 1) : $att[1], // Name | ||
929 | + (isset($att[2])) ? $att[2] : '', // Expression | ||
930 | + (isset($att[3])) ? $att[3] : '', // Value | ||
931 | + $inverted, // Inverted Flag | ||
932 | + (isset($att[4])) ? strtolower($att[4]) : '', // Case-Sensitivity | ||
933 | + ); | ||
934 | + } | ||
935 | + } | ||
936 | + | ||
937 | + // Sanitize Separator | ||
938 | + if ($m[5] !== '' && trim($m[5]) === '') { // Descendant Separator | ||
939 | + $m[5] = ' '; | ||
940 | + } else { // Other Separator | ||
941 | + $m[5] = trim($m[5]); | ||
942 | + } | ||
943 | + | ||
944 | + // Clear Separator if it's a Selector List | ||
945 | + if ($is_list = ($m[5] === ',')) { $m[5] = ''; } | ||
946 | + | ||
947 | + // Remove full match before adding to results | ||
948 | + array_shift($m); | ||
949 | + $result[] = $m; | ||
950 | + | ||
951 | + if ($is_list) { // Selector List | ||
952 | + $selectors[] = $result; | ||
953 | + $result = array(); | ||
954 | + } | ||
955 | + } | ||
956 | + | ||
957 | + if (count($result) > 0) { $selectors[] = $result; } | ||
958 | + return $selectors; | ||
959 | + } | ||
960 | + | ||
961 | + function __get($name) | ||
962 | + { | ||
963 | + if (isset($this->attr[$name])) { | ||
964 | + return $this->convert_text($this->attr[$name]); | ||
965 | + } | ||
966 | + switch ($name) { | ||
967 | + case 'outertext': return $this->outertext(); | ||
968 | + case 'innertext': return $this->innertext(); | ||
969 | + case 'plaintext': return $this->text(); | ||
970 | + case 'xmltext': return $this->xmltext(); | ||
971 | + default: return array_key_exists($name, $this->attr); | ||
972 | + } | ||
973 | + } | ||
974 | + | ||
975 | + function __set($name, $value) | ||
976 | + { | ||
977 | + global $debug_object; | ||
978 | + if (is_object($debug_object)) { $debug_object->debug_log_entry(1); } | ||
979 | + | ||
980 | + switch ($name) { | ||
981 | + case 'outertext': return $this->_[HDOM_INFO_OUTER] = $value; | ||
982 | + case 'innertext': | ||
983 | + if (isset($this->_[HDOM_INFO_TEXT])) { | ||
984 | + return $this->_[HDOM_INFO_TEXT] = $value; | ||
985 | + } | ||
986 | + return $this->_[HDOM_INFO_INNER] = $value; | ||
987 | + } | ||
988 | + | ||
989 | + if (!isset($this->attr[$name])) { | ||
990 | + $this->_[HDOM_INFO_SPACE][] = array(' ', '', ''); | ||
991 | + $this->_[HDOM_INFO_QUOTE][] = HDOM_QUOTE_DOUBLE; | ||
992 | + } | ||
993 | + | ||
994 | + $this->attr[$name] = $value; | ||
995 | + } | ||
996 | + | ||
997 | + function __isset($name) | ||
998 | + { | ||
999 | + switch ($name) { | ||
1000 | + case 'outertext': return true; | ||
1001 | + case 'innertext': return true; | ||
1002 | + case 'plaintext': return true; | ||
1003 | + } | ||
1004 | + //no value attr: nowrap, checked selected... | ||
1005 | + return (array_key_exists($name, $this->attr)) ? true : isset($this->attr[$name]); | ||
1006 | + } | ||
1007 | + | ||
1008 | + function __unset($name) | ||
1009 | + { | ||
1010 | + if (isset($this->attr[$name])) { unset($this->attr[$name]); } | ||
1011 | + } | ||
1012 | + | ||
1013 | + function convert_text($text) | ||
1014 | + { | ||
1015 | + global $debug_object; | ||
1016 | + if (is_object($debug_object)) { $debug_object->debug_log_entry(1); } | ||
1017 | + | ||
1018 | + $converted_text = $text; | ||
1019 | + | ||
1020 | + $sourceCharset = ''; | ||
1021 | + $targetCharset = ''; | ||
1022 | + | ||
1023 | + if ($this->dom) { | ||
1024 | + $sourceCharset = strtoupper($this->dom->_charset); | ||
1025 | + $targetCharset = strtoupper($this->dom->_target_charset); | ||
1026 | + } | ||
1027 | + | ||
1028 | + if (is_object($debug_object)) { | ||
1029 | + $debug_object->debug_log(3, | ||
1030 | + 'source charset: ' | ||
1031 | + . $sourceCharset | ||
1032 | + . ' target charaset: ' | ||
1033 | + . $targetCharset | ||
1034 | + ); | ||
1035 | + } | ||
1036 | + | ||
1037 | + if (!empty($sourceCharset) | ||
1038 | + && !empty($targetCharset) | ||
1039 | + && (strcasecmp($sourceCharset, $targetCharset) != 0)) { | ||
1040 | + // Check if the reported encoding could have been incorrect and the text is actually already UTF-8 | ||
1041 | + if ((strcasecmp($targetCharset, 'UTF-8') == 0) | ||
1042 | + && ($this->is_utf8($text))) { | ||
1043 | + $converted_text = $text; | ||
1044 | + } else { | ||
1045 | + $converted_text = iconv($sourceCharset, $targetCharset, $text); | ||
1046 | + } | ||
1047 | + } | ||
1048 | + | ||
1049 | + // Lets make sure that we don't have that silly BOM issue with any of the utf-8 text we output. | ||
1050 | + if ($targetCharset === 'UTF-8') { | ||
1051 | + if (substr($converted_text, 0, 3) === "\xef\xbb\xbf") { | ||
1052 | + $converted_text = substr($converted_text, 3); | ||
1053 | + } | ||
1054 | + | ||
1055 | + if (substr($converted_text, -3) === "\xef\xbb\xbf") { | ||
1056 | + $converted_text = substr($converted_text, 0, -3); | ||
1057 | + } | ||
1058 | + } | ||
1059 | + | ||
1060 | + return $converted_text; | ||
1061 | + } | ||
1062 | + | ||
1063 | + static function is_utf8($str) | ||
1064 | + { | ||
1065 | + $c = 0; $b = 0; | ||
1066 | + $bits = 0; | ||
1067 | + $len = strlen($str); | ||
1068 | + for($i = 0; $i < $len; $i++) { | ||
1069 | + $c = ord($str[$i]); | ||
1070 | + if($c > 128) { | ||
1071 | + if(($c >= 254)) { return false; } | ||
1072 | + elseif($c >= 252) { $bits = 6; } | ||
1073 | + elseif($c >= 248) { $bits = 5; } | ||
1074 | + elseif($c >= 240) { $bits = 4; } | ||
1075 | + elseif($c >= 224) { $bits = 3; } | ||
1076 | + elseif($c >= 192) { $bits = 2; } | ||
1077 | + else { return false; } | ||
1078 | + if(($i + $bits) > $len) { return false; } | ||
1079 | + while($bits > 1) { | ||
1080 | + $i++; | ||
1081 | + $b = ord($str[$i]); | ||
1082 | + if($b < 128 || $b > 191) { return false; } | ||
1083 | + $bits--; | ||
1084 | + } | ||
1085 | + } | ||
1086 | + } | ||
1087 | + return true; | ||
1088 | + } | ||
1089 | + | ||
1090 | + function get_display_size() | ||
1091 | + { | ||
1092 | + global $debug_object; | ||
1093 | + | ||
1094 | + $width = -1; | ||
1095 | + $height = -1; | ||
1096 | + | ||
1097 | + if ($this->tag !== 'img') { | ||
1098 | + return false; | ||
1099 | + } | ||
1100 | + | ||
1101 | + // See if there is aheight or width attribute in the tag itself. | ||
1102 | + if (isset($this->attr['width'])) { | ||
1103 | + $width = $this->attr['width']; | ||
1104 | + } | ||
1105 | + | ||
1106 | + if (isset($this->attr['height'])) { | ||
1107 | + $height = $this->attr['height']; | ||
1108 | + } | ||
1109 | + | ||
1110 | + // Now look for an inline style. | ||
1111 | + if (isset($this->attr['style'])) { | ||
1112 | + // Thanks to user gnarf from stackoverflow for this regular expression. | ||
1113 | + $attributes = array(); | ||
1114 | + | ||
1115 | + preg_match_all( | ||
1116 | + '/([\w-]+)\s*:\s*([^;]+)\s*;?/', | ||
1117 | + $this->attr['style'], | ||
1118 | + $matches, | ||
1119 | + PREG_SET_ORDER | ||
1120 | + ); | ||
1121 | + | ||
1122 | + foreach ($matches as $match) { | ||
1123 | + $attributes[$match[1]] = $match[2]; | ||
1124 | + } | ||
1125 | + | ||
1126 | + // If there is a width in the style attributes: | ||
1127 | + if (isset($attributes['width']) && $width == -1) { | ||
1128 | + // check that the last two characters are px (pixels) | ||
1129 | + if (strtolower(substr($attributes['width'], -2)) === 'px') { | ||
1130 | + $proposed_width = substr($attributes['width'], 0, -2); | ||
1131 | + // Now make sure that it's an integer and not something stupid. | ||
1132 | + if (filter_var($proposed_width, FILTER_VALIDATE_INT)) { | ||
1133 | + $width = $proposed_width; | ||
1134 | + } | ||
1135 | + } | ||
1136 | + } | ||
1137 | + | ||
1138 | + // If there is a width in the style attributes: | ||
1139 | + if (isset($attributes['height']) && $height == -1) { | ||
1140 | + // check that the last two characters are px (pixels) | ||
1141 | + if (strtolower(substr($attributes['height'], -2)) == 'px') { | ||
1142 | + $proposed_height = substr($attributes['height'], 0, -2); | ||
1143 | + // Now make sure that it's an integer and not something stupid. | ||
1144 | + if (filter_var($proposed_height, FILTER_VALIDATE_INT)) { | ||
1145 | + $height = $proposed_height; | ||
1146 | + } | ||
1147 | + } | ||
1148 | + } | ||
1149 | + | ||
1150 | + } | ||
1151 | + | ||
1152 | + // Future enhancement: | ||
1153 | + // Look in the tag to see if there is a class or id specified that has | ||
1154 | + // a height or width attribute to it. | ||
1155 | + | ||
1156 | + // Far future enhancement | ||
1157 | + // Look at all the parent tags of this image to see if they specify a | ||
1158 | + // class or id that has an img selector that specifies a height or width | ||
1159 | + // Note that in this case, the class or id will have the img subselector | ||
1160 | + // for it to apply to the image. | ||
1161 | + | ||
1162 | + // ridiculously far future development | ||
1163 | + // If the class or id is specified in a SEPARATE css file thats not on | ||
1164 | + // the page, go get it and do what we were just doing for the ones on | ||
1165 | + // the page. | ||
1166 | + | ||
1167 | + $result = array( | ||
1168 | + 'height' => $height, | ||
1169 | + 'width' => $width | ||
1170 | + ); | ||
1171 | + | ||
1172 | + return $result; | ||
1173 | + } | ||
1174 | + | ||
1175 | + function save($filepath = '') | ||
1176 | + { | ||
1177 | + $ret = $this->outertext(); | ||
1178 | + | ||
1179 | + if ($filepath !== '') { | ||
1180 | + file_put_contents($filepath, $ret, LOCK_EX); | ||
1181 | + } | ||
1182 | + | ||
1183 | + return $ret; | ||
1184 | + } | ||
1185 | + | ||
1186 | + function addClass($class) | ||
1187 | + { | ||
1188 | + if (is_string($class)) { | ||
1189 | + $class = explode(' ', $class); | ||
1190 | + } | ||
1191 | + | ||
1192 | + if (is_array($class)) { | ||
1193 | + foreach($class as $c) { | ||
1194 | + if (isset($this->class)) { | ||
1195 | + if ($this->hasClass($c)) { | ||
1196 | + continue; | ||
1197 | + } else { | ||
1198 | + $this->class .= ' ' . $c; | ||
1199 | + } | ||
1200 | + } else { | ||
1201 | + $this->class = $c; | ||
1202 | + } | ||
1203 | + } | ||
1204 | + } else { | ||
1205 | + if (is_object($debug_object)) { | ||
1206 | + $debug_object->debug_log(2, 'Invalid type: ', gettype($class)); | ||
1207 | + } | ||
1208 | + } | ||
1209 | + } | ||
1210 | + | ||
1211 | + function hasClass($class) | ||
1212 | + { | ||
1213 | + if (is_string($class)) { | ||
1214 | + if (isset($this->class)) { | ||
1215 | + return in_array($class, explode(' ', $this->class), true); | ||
1216 | + } | ||
1217 | + } else { | ||
1218 | + if (is_object($debug_object)) { | ||
1219 | + $debug_object->debug_log(2, 'Invalid type: ', gettype($class)); | ||
1220 | + } | ||
1221 | + } | ||
1222 | + | ||
1223 | + return false; | ||
1224 | + } | ||
1225 | + | ||
1226 | + function removeClass($class = null) | ||
1227 | + { | ||
1228 | + if (!isset($this->class)) { | ||
1229 | + return; | ||
1230 | + } | ||
1231 | + | ||
1232 | + if (is_null($class)) { | ||
1233 | + $this->removeAttribute('class'); | ||
1234 | + return; | ||
1235 | + } | ||
1236 | + | ||
1237 | + if (is_string($class)) { | ||
1238 | + $class = explode(' ', $class); | ||
1239 | + } | ||
1240 | + | ||
1241 | + if (is_array($class)) { | ||
1242 | + $class = array_diff(explode(' ', $this->class), $class); | ||
1243 | + if (empty($class)) { | ||
1244 | + $this->removeAttribute('class'); | ||
1245 | + } else { | ||
1246 | + $this->class = implode(' ', $class); | ||
1247 | + } | ||
1248 | + } | ||
1249 | + } | ||
1250 | + | ||
1251 | + function getAllAttributes() | ||
1252 | + { | ||
1253 | + return $this->attr; | ||
1254 | + } | ||
1255 | + | ||
1256 | + function getAttribute($name) | ||
1257 | + { | ||
1258 | + return $this->__get($name); | ||
1259 | + } | ||
1260 | + | ||
1261 | + function setAttribute($name, $value) | ||
1262 | + { | ||
1263 | + $this->__set($name, $value); | ||
1264 | + } | ||
1265 | + | ||
1266 | + function hasAttribute($name) | ||
1267 | + { | ||
1268 | + return $this->__isset($name); | ||
1269 | + } | ||
1270 | + | ||
1271 | + function removeAttribute($name) | ||
1272 | + { | ||
1273 | + $this->__set($name, null); | ||
1274 | + } | ||
1275 | + | ||
1276 | + function remove() | ||
1277 | + { | ||
1278 | + if ($this->parent) { | ||
1279 | + $this->parent->removeChild($this); | ||
1280 | + } | ||
1281 | + } | ||
1282 | + | ||
1283 | + function removeChild($node) | ||
1284 | + { | ||
1285 | + $nidx = array_search($node, $this->nodes, true); | ||
1286 | + $cidx = array_search($node, $this->children, true); | ||
1287 | + $didx = array_search($node, $this->dom->nodes, true); | ||
1288 | + | ||
1289 | + if ($nidx !== false && $cidx !== false && $didx !== false) { | ||
1290 | + | ||
1291 | + foreach($node->children as $child) { | ||
1292 | + $node->removeChild($child); | ||
1293 | + } | ||
1294 | + | ||
1295 | + foreach($node->nodes as $entity) { | ||
1296 | + $enidx = array_search($entity, $node->nodes, true); | ||
1297 | + $edidx = array_search($entity, $node->dom->nodes, true); | ||
1298 | + | ||
1299 | + if ($enidx !== false && $edidx !== false) { | ||
1300 | + unset($node->nodes[$enidx]); | ||
1301 | + unset($node->dom->nodes[$edidx]); | ||
1302 | + } | ||
1303 | + } | ||
1304 | + | ||
1305 | + unset($this->nodes[$nidx]); | ||
1306 | + unset($this->children[$cidx]); | ||
1307 | + unset($this->dom->nodes[$didx]); | ||
1308 | + | ||
1309 | + $node->clear(); | ||
1310 | + | ||
1311 | + } | ||
1312 | + } | ||
1313 | + | ||
1314 | + function getElementById($id) | ||
1315 | + { | ||
1316 | + return $this->find("#$id", 0); | ||
1317 | + } | ||
1318 | + | ||
1319 | + function getElementsById($id, $idx = null) | ||
1320 | + { | ||
1321 | + return $this->find("#$id", $idx); | ||
1322 | + } | ||
1323 | + | ||
1324 | + function getElementByTagName($name) | ||
1325 | + { | ||
1326 | + return $this->find($name, 0); | ||
1327 | + } | ||
1328 | + | ||
1329 | + function getElementsByTagName($name, $idx = null) | ||
1330 | + { | ||
1331 | + return $this->find($name, $idx); | ||
1332 | + } | ||
1333 | + | ||
1334 | + function parentNode() | ||
1335 | + { | ||
1336 | + return $this->parent(); | ||
1337 | + } | ||
1338 | + | ||
1339 | + function childNodes($idx = -1) | ||
1340 | + { | ||
1341 | + return $this->children($idx); | ||
1342 | + } | ||
1343 | + | ||
1344 | + function firstChild() | ||
1345 | + { | ||
1346 | + return $this->first_child(); | ||
1347 | + } | ||
1348 | + | ||
1349 | + function lastChild() | ||
1350 | + { | ||
1351 | + return $this->last_child(); | ||
1352 | + } | ||
1353 | + | ||
1354 | + function nextSibling() | ||
1355 | + { | ||
1356 | + return $this->next_sibling(); | ||
1357 | + } | ||
1358 | + | ||
1359 | + function previousSibling() | ||
1360 | + { | ||
1361 | + return $this->prev_sibling(); | ||
1362 | + } | ||
1363 | + | ||
1364 | + function hasChildNodes() | ||
1365 | + { | ||
1366 | + return $this->has_child(); | ||
1367 | + } | ||
1368 | + | ||
1369 | + function nodeName() | ||
1370 | + { | ||
1371 | + return $this->tag; | ||
1372 | + } | ||
1373 | + | ||
1374 | + function appendChild($node) | ||
1375 | + { | ||
1376 | + $node->parent($this); | ||
1377 | + return $node; | ||
1378 | + } | ||
1379 | + | ||
1380 | +} | ||
1381 | + | ||
1382 | +class simple_html_dom | ||
1383 | +{ | ||
1384 | + public $root = null; | ||
1385 | + public $nodes = array(); | ||
1386 | + public $callback = null; | ||
1387 | + public $lowercase = false; | ||
1388 | + public $original_size; | ||
1389 | + public $size; | ||
1390 | + | ||
1391 | + protected $pos; | ||
1392 | + protected $doc; | ||
1393 | + protected $char; | ||
1394 | + | ||
1395 | + protected $cursor; | ||
1396 | + protected $parent; | ||
1397 | + protected $noise = array(); | ||
1398 | + protected $token_blank = " \t\r\n"; | ||
1399 | + protected $token_equal = ' =/>'; | ||
1400 | + protected $token_slash = " />\r\n\t"; | ||
1401 | + protected $token_attr = ' >'; | ||
1402 | + | ||
1403 | + public $_charset = ''; | ||
1404 | + public $_target_charset = ''; | ||
1405 | + | ||
1406 | + protected $default_br_text = ''; | ||
1407 | + | ||
1408 | + public $default_span_text = ''; | ||
1409 | + | ||
1410 | + protected $self_closing_tags = array( | ||
1411 | + 'area' => 1, | ||
1412 | + 'base' => 1, | ||
1413 | + 'br' => 1, | ||
1414 | + 'col' => 1, | ||
1415 | + 'embed' => 1, | ||
1416 | + 'hr' => 1, | ||
1417 | + 'img' => 1, | ||
1418 | + 'input' => 1, | ||
1419 | + 'link' => 1, | ||
1420 | + 'meta' => 1, | ||
1421 | + 'param' => 1, | ||
1422 | + 'source' => 1, | ||
1423 | + 'track' => 1, | ||
1424 | + 'wbr' => 1 | ||
1425 | + ); | ||
1426 | + protected $block_tags = array( | ||
1427 | + 'body' => 1, | ||
1428 | + 'div' => 1, | ||
1429 | + 'form' => 1, | ||
1430 | + 'root' => 1, | ||
1431 | + 'span' => 1, | ||
1432 | + 'table' => 1 | ||
1433 | + ); | ||
1434 | + protected $optional_closing_tags = array( | ||
1435 | + // Not optional, see | ||
1436 | + // https://www.w3.org/TR/html/textlevel-semantics.html#the-b-element | ||
1437 | + 'b' => array('b' => 1), | ||
1438 | + 'dd' => array('dd' => 1, 'dt' => 1), | ||
1439 | + // Not optional, see | ||
1440 | + // https://www.w3.org/TR/html/grouping-content.html#the-dl-element | ||
1441 | + 'dl' => array('dd' => 1, 'dt' => 1), | ||
1442 | + 'dt' => array('dd' => 1, 'dt' => 1), | ||
1443 | + 'li' => array('li' => 1), | ||
1444 | + 'optgroup' => array('optgroup' => 1, 'option' => 1), | ||
1445 | + 'option' => array('optgroup' => 1, 'option' => 1), | ||
1446 | + 'p' => array('p' => 1), | ||
1447 | + 'rp' => array('rp' => 1, 'rt' => 1), | ||
1448 | + 'rt' => array('rp' => 1, 'rt' => 1), | ||
1449 | + 'td' => array('td' => 1, 'th' => 1), | ||
1450 | + 'th' => array('td' => 1, 'th' => 1), | ||
1451 | + 'tr' => array('td' => 1, 'th' => 1, 'tr' => 1), | ||
1452 | + ); | ||
1453 | + | ||
1454 | + function __construct( | ||
1455 | + $str = null, | ||
1456 | + $lowercase = true, | ||
1457 | + $forceTagsClosed = true, | ||
1458 | + $target_charset = DEFAULT_TARGET_CHARSET, | ||
1459 | + $stripRN = true, | ||
1460 | + $defaultBRText = DEFAULT_BR_TEXT, | ||
1461 | + $defaultSpanText = DEFAULT_SPAN_TEXT, | ||
1462 | + $options = 0) | ||
1463 | + { | ||
1464 | + if ($str) { | ||
1465 | + if (preg_match('/^http:\/\//i', $str) || is_file($str)) { | ||
1466 | + $this->load_file($str); | ||
1467 | + } else { | ||
1468 | + $this->load( | ||
1469 | + $str, | ||
1470 | + $lowercase, | ||
1471 | + $stripRN, | ||
1472 | + $defaultBRText, | ||
1473 | + $defaultSpanText, | ||
1474 | + $options | ||
1475 | + ); | ||
1476 | + } | ||
1477 | + } | ||
1478 | + // Forcing tags to be closed implies that we don't trust the html, but | ||
1479 | + // it can lead to parsing errors if we SHOULD trust the html. | ||
1480 | + if (!$forceTagsClosed) { | ||
1481 | + $this->optional_closing_array = array(); | ||
1482 | + } | ||
1483 | + | ||
1484 | + $this->_target_charset = $target_charset; | ||
1485 | + } | ||
1486 | + | ||
1487 | + function __destruct() | ||
1488 | + { | ||
1489 | + $this->clear(); | ||
1490 | + } | ||
1491 | + | ||
1492 | + function load( | ||
1493 | + $str, | ||
1494 | + $lowercase = true, | ||
1495 | + $stripRN = true, | ||
1496 | + $defaultBRText = DEFAULT_BR_TEXT, | ||
1497 | + $defaultSpanText = DEFAULT_SPAN_TEXT, | ||
1498 | + $options = 0) | ||
1499 | + { | ||
1500 | + global $debug_object; | ||
1501 | + | ||
1502 | + // prepare | ||
1503 | + $this->prepare($str, $lowercase, $defaultBRText, $defaultSpanText); | ||
1504 | + | ||
1505 | + // Per sourceforge http://sourceforge.net/tracker/?func=detail&aid=2949097&group_id=218559&atid=1044037 | ||
1506 | + // Script tags removal now preceeds style tag removal. | ||
1507 | + // strip out <script> tags | ||
1508 | + $this->remove_noise("'<\s*script[^>]*[^/]>(.*?)<\s*/\s*script\s*>'is"); | ||
1509 | + $this->remove_noise("'<\s*script\s*>(.*?)<\s*/\s*script\s*>'is"); | ||
1510 | + | ||
1511 | + // strip out the \r \n's if we are told to. | ||
1512 | + if ($stripRN) { | ||
1513 | + $this->doc = str_replace("\r", ' ', $this->doc); | ||
1514 | + $this->doc = str_replace("\n", ' ', $this->doc); | ||
1515 | + | ||
1516 | + // set the length of content since we have changed it. | ||
1517 | + $this->size = strlen($this->doc); | ||
1518 | + } | ||
1519 | + | ||
1520 | + // strip out cdata | ||
1521 | + $this->remove_noise("'<!\[CDATA\[(.*?)\]\]>'is", true); | ||
1522 | + // strip out comments | ||
1523 | + $this->remove_noise("'<!--(.*?)-->'is"); | ||
1524 | + // strip out <style> tags | ||
1525 | + $this->remove_noise("'<\s*style[^>]*[^/]>(.*?)<\s*/\s*style\s*>'is"); | ||
1526 | + $this->remove_noise("'<\s*style\s*>(.*?)<\s*/\s*style\s*>'is"); | ||
1527 | + // strip out preformatted tags | ||
1528 | + $this->remove_noise("'<\s*(?:code)[^>]*>(.*?)<\s*/\s*(?:code)\s*>'is"); | ||
1529 | + // strip out server side scripts | ||
1530 | + $this->remove_noise("'(<\?)(.*?)(\?>)'s", true); | ||
1531 | + | ||
1532 | + if($options & HDOM_SMARTY_AS_TEXT) { // Strip Smarty scripts | ||
1533 | + $this->remove_noise("'(\{\w)(.*?)(\})'s", true); | ||
1534 | + } | ||
1535 | + | ||
1536 | + // parsing | ||
1537 | + $this->parse(); | ||
1538 | + // end | ||
1539 | + $this->root->_[HDOM_INFO_END] = $this->cursor; | ||
1540 | + $this->parse_charset(); | ||
1541 | + | ||
1542 | + // make load function chainable | ||
1543 | + return $this; | ||
1544 | + } | ||
1545 | + | ||
1546 | + function load_file() | ||
1547 | + { | ||
1548 | + $args = func_get_args(); | ||
1549 | + | ||
1550 | + if(($doc = call_user_func_array('file_get_contents', $args)) !== false) { | ||
1551 | + $this->load($doc, true); | ||
1552 | + } else { | ||
1553 | + return false; | ||
1554 | + } | ||
1555 | + } | ||
1556 | + | ||
1557 | + function set_callback($function_name) | ||
1558 | + { | ||
1559 | + $this->callback = $function_name; | ||
1560 | + } | ||
1561 | + | ||
1562 | + function remove_callback() | ||
1563 | + { | ||
1564 | + $this->callback = null; | ||
1565 | + } | ||
1566 | + | ||
1567 | + function save($filepath = '') | ||
1568 | + { | ||
1569 | + $ret = $this->root->innertext(); | ||
1570 | + if ($filepath !== '') { file_put_contents($filepath, $ret, LOCK_EX); } | ||
1571 | + return $ret; | ||
1572 | + } | ||
1573 | + | ||
1574 | + function find($selector, $idx = null, $lowercase = false) | ||
1575 | + { | ||
1576 | + return $this->root->find($selector, $idx, $lowercase); | ||
1577 | + } | ||
1578 | + | ||
1579 | + function clear() | ||
1580 | + { | ||
1581 | + if (isset($this->nodes)) { | ||
1582 | + foreach ($this->nodes as $n) { | ||
1583 | + $n->clear(); | ||
1584 | + $n = null; | ||
1585 | + } | ||
1586 | + } | ||
1587 | + | ||
1588 | + // This add next line is documented in the sourceforge repository. | ||
1589 | + // 2977248 as a fix for ongoing memory leaks that occur even with the | ||
1590 | + // use of clear. | ||
1591 | + if (isset($this->children)) { | ||
1592 | + foreach ($this->children as $n) { | ||
1593 | + $n->clear(); | ||
1594 | + $n = null; | ||
1595 | + } | ||
1596 | + } | ||
1597 | + | ||
1598 | + if (isset($this->parent)) { | ||
1599 | + $this->parent->clear(); | ||
1600 | + unset($this->parent); | ||
1601 | + } | ||
1602 | + | ||
1603 | + if (isset($this->root)) { | ||
1604 | + $this->root->clear(); | ||
1605 | + unset($this->root); | ||
1606 | + } | ||
1607 | + | ||
1608 | + unset($this->doc); | ||
1609 | + unset($this->noise); | ||
1610 | + } | ||
1611 | + | ||
1612 | + function dump($show_attr = true) | ||
1613 | + { | ||
1614 | + $this->root->dump($show_attr); | ||
1615 | + } | ||
1616 | + | ||
1617 | + protected function prepare( | ||
1618 | + $str, $lowercase = true, | ||
1619 | + $defaultBRText = DEFAULT_BR_TEXT, | ||
1620 | + $defaultSpanText = DEFAULT_SPAN_TEXT) | ||
1621 | + { | ||
1622 | + $this->clear(); | ||
1623 | + | ||
1624 | + $this->doc = trim($str); | ||
1625 | + $this->size = strlen($this->doc); | ||
1626 | + $this->original_size = $this->size; // original size of the html | ||
1627 | + $this->pos = 0; | ||
1628 | + $this->cursor = 1; | ||
1629 | + $this->noise = array(); | ||
1630 | + $this->nodes = array(); | ||
1631 | + $this->lowercase = $lowercase; | ||
1632 | + $this->default_br_text = $defaultBRText; | ||
1633 | + $this->default_span_text = $defaultSpanText; | ||
1634 | + $this->root = new simple_html_dom_node($this); | ||
1635 | + $this->root->tag = 'root'; | ||
1636 | + $this->root->_[HDOM_INFO_BEGIN] = -1; | ||
1637 | + $this->root->nodetype = HDOM_TYPE_ROOT; | ||
1638 | + $this->parent = $this->root; | ||
1639 | + if ($this->size > 0) { $this->char = $this->doc[0]; } | ||
1640 | + } | ||
1641 | + | ||
1642 | + protected function parse() | ||
1643 | + { | ||
1644 | + while (true) { | ||
1645 | + // Read next tag if there is no text between current position and the | ||
1646 | + // next opening tag. | ||
1647 | + if (($s = $this->copy_until_char('<')) === '') { | ||
1648 | + if($this->read_tag()) { | ||
1649 | + continue; | ||
1650 | + } else { | ||
1651 | + return true; | ||
1652 | + } | ||
1653 | + } | ||
1654 | + | ||
1655 | + // Add a text node for text between tags | ||
1656 | + $node = new simple_html_dom_node($this); | ||
1657 | + ++$this->cursor; | ||
1658 | + $node->_[HDOM_INFO_TEXT] = $s; | ||
1659 | + $this->link_nodes($node, false); | ||
1660 | + } | ||
1661 | + } | ||
1662 | + | ||
1663 | + protected function parse_charset() | ||
1664 | + { | ||
1665 | + global $debug_object; | ||
1666 | + | ||
1667 | + $charset = null; | ||
1668 | + | ||
1669 | + if (function_exists('get_last_retrieve_url_contents_content_type')) { | ||
1670 | + $contentTypeHeader = get_last_retrieve_url_contents_content_type(); | ||
1671 | + $success = preg_match('/charset=(.+)/', $contentTypeHeader, $matches); | ||
1672 | + if ($success) { | ||
1673 | + $charset = $matches[1]; | ||
1674 | + if (is_object($debug_object)) { | ||
1675 | + $debug_object->debug_log(2, | ||
1676 | + 'header content-type found charset of: ' | ||
1677 | + . $charset | ||
1678 | + ); | ||
1679 | + } | ||
1680 | + } | ||
1681 | + } | ||
1682 | + | ||
1683 | + if (empty($charset)) { | ||
1684 | + // https://www.w3.org/TR/html/document-metadata.html#statedef-http-equiv-content-type | ||
1685 | + $el = $this->root->find('meta[http-equiv=Content-Type]', 0, true); | ||
1686 | + | ||
1687 | + if (!empty($el)) { | ||
1688 | + $fullvalue = $el->content; | ||
1689 | + if (is_object($debug_object)) { | ||
1690 | + $debug_object->debug_log(2, | ||
1691 | + 'meta content-type tag found' | ||
1692 | + . $fullvalue | ||
1693 | + ); | ||
1694 | + } | ||
1695 | + | ||
1696 | + if (!empty($fullvalue)) { | ||
1697 | + $success = preg_match( | ||
1698 | + '/charset=(.+)/i', | ||
1699 | + $fullvalue, | ||
1700 | + $matches | ||
1701 | + ); | ||
1702 | + | ||
1703 | + if ($success) { | ||
1704 | + $charset = $matches[1]; | ||
1705 | + } else { | ||
1706 | + // If there is a meta tag, and they don't specify the | ||
1707 | + // character set, research says that it's typically | ||
1708 | + // ISO-8859-1 | ||
1709 | + if (is_object($debug_object)) { | ||
1710 | + $debug_object->debug_log(2, | ||
1711 | + 'meta content-type tag couldn\'t be parsed. using iso-8859 default.' | ||
1712 | + ); | ||
1713 | + } | ||
1714 | + | ||
1715 | + $charset = 'ISO-8859-1'; | ||
1716 | + } | ||
1717 | + } | ||
1718 | + } | ||
1719 | + } | ||
1720 | + | ||
1721 | + if (empty($charset)) { | ||
1722 | + // https://www.w3.org/TR/html/document-metadata.html#character-encoding-declaration | ||
1723 | + if ($meta = $this->root->find('meta[charset]', 0)) { | ||
1724 | + $charset = $meta->charset; | ||
1725 | + if (is_object($debug_object)) { | ||
1726 | + $debug_object->debug_log(2, 'meta charset: ' . $charset); | ||
1727 | + } | ||
1728 | + } | ||
1729 | + } | ||
1730 | + | ||
1731 | + if (empty($charset)) { | ||
1732 | + // Try to guess the charset based on the content | ||
1733 | + // Requires Multibyte String (mbstring) support (optional) | ||
1734 | + if (function_exists('mb_detect_encoding')) { | ||
1735 | + /** | ||
1736 | + * mb_detect_encoding() is not intended to distinguish between | ||
1737 | + * charsets, especially single-byte charsets. Its primary | ||
1738 | + * purpose is to detect which multibyte encoding is in use, | ||
1739 | + * i.e. UTF-8, UTF-16, shift-JIS, etc. | ||
1740 | + * | ||
1741 | + * -- https://bugs.php.net/bug.php?id=38138 | ||
1742 | + * | ||
1743 | + * Adding both CP1251/ISO-8859-5 and CP1252/ISO-8859-1 will | ||
1744 | + * always result in CP1251/ISO-8859-5 and vice versa. | ||
1745 | + * | ||
1746 | + * Thus, only detect if it's either UTF-8 or CP1252/ISO-8859-1 | ||
1747 | + * to stay compatible. | ||
1748 | + */ | ||
1749 | + $encoding = mb_detect_encoding( | ||
1750 | + $this->doc, | ||
1751 | + array( 'UTF-8', 'CP1252', 'ISO-8859-1' ) | ||
1752 | + ); | ||
1753 | + | ||
1754 | + if ($encoding === 'CP1252' || $encoding === 'ISO-8859-1') { | ||
1755 | + // Due to a limitation of mb_detect_encoding | ||
1756 | + // 'CP1251'/'ISO-8859-5' will be detected as | ||
1757 | + // 'CP1252'/'ISO-8859-1'. This will cause iconv to fail, in | ||
1758 | + // which case we can simply assume it is the other charset. | ||
1759 | + if (!@iconv('CP1252', 'UTF-8', $this->doc)) { | ||
1760 | + $encoding = 'CP1251'; | ||
1761 | + } | ||
1762 | + } | ||
1763 | + | ||
1764 | + if ($encoding !== false) { | ||
1765 | + $charset = $encoding; | ||
1766 | + if (is_object($debug_object)) { | ||
1767 | + $debug_object->debug_log(2, 'mb_detect: ' . $charset); | ||
1768 | + } | ||
1769 | + } | ||
1770 | + } | ||
1771 | + } | ||
1772 | + | ||
1773 | + if (empty($charset)) { | ||
1774 | + // Assume it's UTF-8 as it is the most likely charset to be used | ||
1775 | + $charset = 'UTF-8'; | ||
1776 | + if (is_object($debug_object)) { | ||
1777 | + $debug_object->debug_log(2, 'No match found, assume ' . $charset); | ||
1778 | + } | ||
1779 | + } | ||
1780 | + | ||
1781 | + // Since CP1252 is a superset, if we get one of it's subsets, we want | ||
1782 | + // it instead. | ||
1783 | + if ((strtolower($charset) == 'iso-8859-1') | ||
1784 | + || (strtolower($charset) == 'latin1') | ||
1785 | + || (strtolower($charset) == 'latin-1')) { | ||
1786 | + $charset = 'CP1252'; | ||
1787 | + if (is_object($debug_object)) { | ||
1788 | + $debug_object->debug_log(2, | ||
1789 | + 'replacing ' . $charset . ' with CP1252 as its a superset' | ||
1790 | + ); | ||
1791 | + } | ||
1792 | + } | ||
1793 | + | ||
1794 | + if (is_object($debug_object)) { | ||
1795 | + $debug_object->debug_log(1, 'EXIT - ' . $charset); | ||
1796 | + } | ||
1797 | + | ||
1798 | + return $this->_charset = $charset; | ||
1799 | + } | ||
1800 | + | ||
1801 | + protected function read_tag() | ||
1802 | + { | ||
1803 | + // Set end position if no further tags found | ||
1804 | + if ($this->char !== '<') { | ||
1805 | + $this->root->_[HDOM_INFO_END] = $this->cursor; | ||
1806 | + return false; | ||
1807 | + } | ||
1808 | + | ||
1809 | + $begin_tag_pos = $this->pos; | ||
1810 | + $this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next | ||
1811 | + | ||
1812 | + // end tag | ||
1813 | + if ($this->char === '/') { | ||
1814 | + $this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next | ||
1815 | + | ||
1816 | + // Skip whitespace in end tags (i.e. in "</ html>") | ||
1817 | + $this->skip($this->token_blank); | ||
1818 | + $tag = $this->copy_until_char('>'); | ||
1819 | + | ||
1820 | + // Skip attributes in end tags | ||
1821 | + if (($pos = strpos($tag, ' ')) !== false) { | ||
1822 | + $tag = substr($tag, 0, $pos); | ||
1823 | + } | ||
1824 | + | ||
1825 | + $parent_lower = strtolower($this->parent->tag); | ||
1826 | + $tag_lower = strtolower($tag); | ||
1827 | + | ||
1828 | + // The end tag is supposed to close the parent tag. Handle situations | ||
1829 | + // when it doesn't | ||
1830 | + if ($parent_lower !== $tag_lower) { | ||
1831 | + // Parent tag does not have to be closed necessarily (optional closing tag) | ||
1832 | + // Current tag is a block tag, so it may close an ancestor | ||
1833 | + if (isset($this->optional_closing_tags[$parent_lower]) | ||
1834 | + && isset($this->block_tags[$tag_lower])) { | ||
1835 | + | ||
1836 | + $this->parent->_[HDOM_INFO_END] = 0; | ||
1837 | + $org_parent = $this->parent; | ||
1838 | + | ||
1839 | + // Traverse ancestors to find a matching opening tag | ||
1840 | + // Stop at root node | ||
1841 | + while (($this->parent->parent) | ||
1842 | + && strtolower($this->parent->tag) !== $tag_lower | ||
1843 | + ){ | ||
1844 | + $this->parent = $this->parent->parent; | ||
1845 | + } | ||
1846 | + | ||
1847 | + // If we don't have a match add current tag as text node | ||
1848 | + if (strtolower($this->parent->tag) !== $tag_lower) { | ||
1849 | + $this->parent = $org_parent; // restore origonal parent | ||
1850 | + | ||
1851 | + if ($this->parent->parent) { | ||
1852 | + $this->parent = $this->parent->parent; | ||
1853 | + } | ||
1854 | + | ||
1855 | + $this->parent->_[HDOM_INFO_END] = $this->cursor; | ||
1856 | + return $this->as_text_node($tag); | ||
1857 | + } | ||
1858 | + } elseif (($this->parent->parent) | ||
1859 | + && isset($this->block_tags[$tag_lower]) | ||
1860 | + ) { | ||
1861 | + // Grandparent exists and current tag is a block tag, so our | ||
1862 | + // parent doesn't have an end tag | ||
1863 | + $this->parent->_[HDOM_INFO_END] = 0; // No end tag | ||
1864 | + $org_parent = $this->parent; | ||
1865 | + | ||
1866 | + // Traverse ancestors to find a matching opening tag | ||
1867 | + // Stop at root node | ||
1868 | + while (($this->parent->parent) | ||
1869 | + && strtolower($this->parent->tag) !== $tag_lower | ||
1870 | + ) { | ||
1871 | + $this->parent = $this->parent->parent; | ||
1872 | + } | ||
1873 | + | ||
1874 | + // If we don't have a match add current tag as text node | ||
1875 | + if (strtolower($this->parent->tag) !== $tag_lower) { | ||
1876 | + $this->parent = $org_parent; // restore origonal parent | ||
1877 | + $this->parent->_[HDOM_INFO_END] = $this->cursor; | ||
1878 | + return $this->as_text_node($tag); | ||
1879 | + } | ||
1880 | + } elseif (($this->parent->parent) | ||
1881 | + && strtolower($this->parent->parent->tag) === $tag_lower | ||
1882 | + ) { // Grandparent exists and current tag closes it | ||
1883 | + $this->parent->_[HDOM_INFO_END] = 0; | ||
1884 | + $this->parent = $this->parent->parent; | ||
1885 | + } else { // Random tag, add as text node | ||
1886 | + return $this->as_text_node($tag); | ||
1887 | + } | ||
1888 | + } | ||
1889 | + | ||
1890 | + // Set end position of parent tag to current cursor position | ||
1891 | + $this->parent->_[HDOM_INFO_END] = $this->cursor; | ||
1892 | + | ||
1893 | + if ($this->parent->parent) { | ||
1894 | + $this->parent = $this->parent->parent; | ||
1895 | + } | ||
1896 | + | ||
1897 | + $this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next | ||
1898 | + return true; | ||
1899 | + } | ||
1900 | + | ||
1901 | + // start tag | ||
1902 | + $node = new simple_html_dom_node($this); | ||
1903 | + $node->_[HDOM_INFO_BEGIN] = $this->cursor; | ||
1904 | + ++$this->cursor; | ||
1905 | + $tag = $this->copy_until($this->token_slash); // Get tag name | ||
1906 | + $node->tag_start = $begin_tag_pos; | ||
1907 | + | ||
1908 | + // doctype, cdata & comments... | ||
1909 | + // <!DOCTYPE html> | ||
1910 | + // <![CDATA[ ... ]]> | ||
1911 | + // <!-- Comment --> | ||
1912 | + if (isset($tag[0]) && $tag[0] === '!') { | ||
1913 | + $node->_[HDOM_INFO_TEXT] = '<' . $tag . $this->copy_until_char('>'); | ||
1914 | + | ||
1915 | + if (isset($tag[2]) && $tag[1] === '-' && $tag[2] === '-') { // Comment ("<!--") | ||
1916 | + $node->nodetype = HDOM_TYPE_COMMENT; | ||
1917 | + $node->tag = 'comment'; | ||
1918 | + } else { // Could be doctype or CDATA but we don't care | ||
1919 | + $node->nodetype = HDOM_TYPE_UNKNOWN; | ||
1920 | + $node->tag = 'unknown'; | ||
1921 | + } | ||
1922 | + | ||
1923 | + if ($this->char === '>') { $node->_[HDOM_INFO_TEXT] .= '>'; } | ||
1924 | + | ||
1925 | + $this->link_nodes($node, true); | ||
1926 | + $this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next | ||
1927 | + return true; | ||
1928 | + } | ||
1929 | + | ||
1930 | + // The start tag cannot contain another start tag, if so add as text | ||
1931 | + // i.e. "<<html>" | ||
1932 | + if ($pos = strpos($tag, '<') !== false) { | ||
1933 | + $tag = '<' . substr($tag, 0, -1); | ||
1934 | + $node->_[HDOM_INFO_TEXT] = $tag; | ||
1935 | + $this->link_nodes($node, false); | ||
1936 | + $this->char = $this->doc[--$this->pos]; // prev | ||
1937 | + return true; | ||
1938 | + } | ||
1939 | + | ||
1940 | + // Handle invalid tag names (i.e. "<html#doc>") | ||
1941 | + if (!preg_match('/^\w[\w:-]*$/', $tag)) { | ||
1942 | + $node->_[HDOM_INFO_TEXT] = '<' . $tag . $this->copy_until('<>'); | ||
1943 | + | ||
1944 | + // Next char is the beginning of a new tag, don't touch it. | ||
1945 | + if ($this->char === '<') { | ||
1946 | + $this->link_nodes($node, false); | ||
1947 | + return true; | ||
1948 | + } | ||
1949 | + | ||
1950 | + // Next char closes current tag, add and be done with it. | ||
1951 | + if ($this->char === '>') { $node->_[HDOM_INFO_TEXT] .= '>'; } | ||
1952 | + $this->link_nodes($node, false); | ||
1953 | + $this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next | ||
1954 | + return true; | ||
1955 | + } | ||
1956 | + | ||
1957 | + // begin tag, add new node | ||
1958 | + $node->nodetype = HDOM_TYPE_ELEMENT; | ||
1959 | + $tag_lower = strtolower($tag); | ||
1960 | + $node->tag = ($this->lowercase) ? $tag_lower : $tag; | ||
1961 | + | ||
1962 | + // handle optional closing tags | ||
1963 | + if (isset($this->optional_closing_tags[$tag_lower])) { | ||
1964 | + // Traverse ancestors to close all optional closing tags | ||
1965 | + while (isset($this->optional_closing_tags[$tag_lower][strtolower($this->parent->tag)])) { | ||
1966 | + $this->parent->_[HDOM_INFO_END] = 0; | ||
1967 | + $this->parent = $this->parent->parent; | ||
1968 | + } | ||
1969 | + $node->parent = $this->parent; | ||
1970 | + } | ||
1971 | + | ||
1972 | + $guard = 0; // prevent infinity loop | ||
1973 | + | ||
1974 | + // [0] Space between tag and first attribute | ||
1975 | + $space = array($this->copy_skip($this->token_blank), '', ''); | ||
1976 | + | ||
1977 | + // attributes | ||
1978 | + do { | ||
1979 | + // Everything until the first equal sign should be the attribute name | ||
1980 | + $name = $this->copy_until($this->token_equal); | ||
1981 | + | ||
1982 | + if ($name === '' && $this->char !== null && $space[0] === '') { | ||
1983 | + break; | ||
1984 | + } | ||
1985 | + | ||
1986 | + if ($guard === $this->pos) { // Escape infinite loop | ||
1987 | + $this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next | ||
1988 | + continue; | ||
1989 | + } | ||
1990 | + | ||
1991 | + $guard = $this->pos; | ||
1992 | + | ||
1993 | + // handle endless '<' | ||
1994 | + // Out of bounds before the tag ended | ||
1995 | + if ($this->pos >= $this->size - 1 && $this->char !== '>') { | ||
1996 | + $node->nodetype = HDOM_TYPE_TEXT; | ||
1997 | + $node->_[HDOM_INFO_END] = 0; | ||
1998 | + $node->_[HDOM_INFO_TEXT] = '<' . $tag . $space[0] . $name; | ||
1999 | + $node->tag = 'text'; | ||
2000 | + $this->link_nodes($node, false); | ||
2001 | + return true; | ||
2002 | + } | ||
2003 | + | ||
2004 | + // handle mismatch '<' | ||
2005 | + // Attributes cannot start after opening tag | ||
2006 | + if ($this->doc[$this->pos - 1] == '<') { | ||
2007 | + $node->nodetype = HDOM_TYPE_TEXT; | ||
2008 | + $node->tag = 'text'; | ||
2009 | + $node->attr = array(); | ||
2010 | + $node->_[HDOM_INFO_END] = 0; | ||
2011 | + $node->_[HDOM_INFO_TEXT] = substr( | ||
2012 | + $this->doc, | ||
2013 | + $begin_tag_pos, | ||
2014 | + $this->pos - $begin_tag_pos - 1 | ||
2015 | + ); | ||
2016 | + $this->pos -= 2; | ||
2017 | + $this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next | ||
2018 | + $this->link_nodes($node, false); | ||
2019 | + return true; | ||
2020 | + } | ||
2021 | + | ||
2022 | + if ($name !== '/' && $name !== '') { // this is a attribute name | ||
2023 | + // [1] Whitespace after attribute name | ||
2024 | + $space[1] = $this->copy_skip($this->token_blank); | ||
2025 | + | ||
2026 | + $name = $this->restore_noise($name); // might be a noisy name | ||
2027 | + | ||
2028 | + if ($this->lowercase) { $name = strtolower($name); } | ||
2029 | + | ||
2030 | + if ($this->char === '=') { // attribute with value | ||
2031 | + $this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next | ||
2032 | + $this->parse_attr($node, $name, $space); // get attribute value | ||
2033 | + } else { | ||
2034 | + //no value attr: nowrap, checked selected... | ||
2035 | + $node->_[HDOM_INFO_QUOTE][] = HDOM_QUOTE_NO; | ||
2036 | + $node->attr[$name] = true; | ||
2037 | + if ($this->char != '>') { $this->char = $this->doc[--$this->pos]; } // prev | ||
2038 | + } | ||
2039 | + | ||
2040 | + $node->_[HDOM_INFO_SPACE][] = $space; | ||
2041 | + | ||
2042 | + // prepare for next attribute | ||
2043 | + $space = array( | ||
2044 | + $this->copy_skip($this->token_blank), | ||
2045 | + '', | ||
2046 | + '' | ||
2047 | + ); | ||
2048 | + } else { // no more attributes | ||
2049 | + break; | ||
2050 | + } | ||
2051 | + } while ($this->char !== '>' && $this->char !== '/'); // go until the tag ended | ||
2052 | + | ||
2053 | + $this->link_nodes($node, true); | ||
2054 | + $node->_[HDOM_INFO_ENDSPACE] = $space[0]; | ||
2055 | + | ||
2056 | + // handle empty tags (i.e. "<div/>") | ||
2057 | + if ($this->copy_until_char('>') === '/') { | ||
2058 | + $node->_[HDOM_INFO_ENDSPACE] .= '/'; | ||
2059 | + $node->_[HDOM_INFO_END] = 0; | ||
2060 | + } else { | ||
2061 | + // reset parent | ||
2062 | + if (!isset($this->self_closing_tags[strtolower($node->tag)])) { | ||
2063 | + $this->parent = $node; | ||
2064 | + } | ||
2065 | + } | ||
2066 | + | ||
2067 | + $this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next | ||
2068 | + | ||
2069 | + // If it's a BR tag, we need to set it's text to the default text. | ||
2070 | + // This way when we see it in plaintext, we can generate formatting that the user wants. | ||
2071 | + // since a br tag never has sub nodes, this works well. | ||
2072 | + if ($node->tag === 'br') { | ||
2073 | + $node->_[HDOM_INFO_INNER] = $this->default_br_text; | ||
2074 | + } | ||
2075 | + | ||
2076 | + return true; | ||
2077 | + } | ||
2078 | + | ||
2079 | + protected function parse_attr($node, $name, &$space) | ||
2080 | + { | ||
2081 | + $is_duplicate = isset($node->attr[$name]); | ||
2082 | + | ||
2083 | + if (!$is_duplicate) // Copy whitespace between "=" and value | ||
2084 | + $space[2] = $this->copy_skip($this->token_blank); | ||
2085 | + | ||
2086 | + switch ($this->char) { | ||
2087 | + case '"': | ||
2088 | + $quote_type = HDOM_QUOTE_DOUBLE; | ||
2089 | + $this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next | ||
2090 | + $value = $this->copy_until_char('"'); | ||
2091 | + $this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next | ||
2092 | + break; | ||
2093 | + case '\'': | ||
2094 | + $quote_type = HDOM_QUOTE_SINGLE; | ||
2095 | + $this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next | ||
2096 | + $value = $this->copy_until_char('\''); | ||
2097 | + $this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next | ||
2098 | + break; | ||
2099 | + default: | ||
2100 | + $quote_type = HDOM_QUOTE_NO; | ||
2101 | + $value = $this->copy_until($this->token_attr); | ||
2102 | + } | ||
2103 | + | ||
2104 | + $value = $this->restore_noise($value); | ||
2105 | + | ||
2106 | + // PaperG: Attributes should not have \r or \n in them, that counts as | ||
2107 | + // html whitespace. | ||
2108 | + $value = str_replace("\r", '', $value); | ||
2109 | + $value = str_replace("\n", '', $value); | ||
2110 | + | ||
2111 | + // PaperG: If this is a "class" selector, lets get rid of the preceeding | ||
2112 | + // and trailing space since some people leave it in the multi class case. | ||
2113 | + if ($name === 'class') { | ||
2114 | + $value = trim($value); | ||
2115 | + } | ||
2116 | + | ||
2117 | + if (!$is_duplicate) { | ||
2118 | + $node->_[HDOM_INFO_QUOTE][] = $quote_type; | ||
2119 | + $node->attr[$name] = $value; | ||
2120 | + } | ||
2121 | + } | ||
2122 | + | ||
2123 | + protected function link_nodes(&$node, $is_child) | ||
2124 | + { | ||
2125 | + $node->parent = $this->parent; | ||
2126 | + $this->parent->nodes[] = $node; | ||
2127 | + if ($is_child) { | ||
2128 | + $this->parent->children[] = $node; | ||
2129 | + } | ||
2130 | + } | ||
2131 | + | ||
2132 | + protected function as_text_node($tag) | ||
2133 | + { | ||
2134 | + $node = new simple_html_dom_node($this); | ||
2135 | + ++$this->cursor; | ||
2136 | + $node->_[HDOM_INFO_TEXT] = '</' . $tag . '>'; | ||
2137 | + $this->link_nodes($node, false); | ||
2138 | + $this->char = (++$this->pos < $this->size) ? $this->doc[$this->pos] : null; // next | ||
2139 | + return true; | ||
2140 | + } | ||
2141 | + | ||
2142 | + protected function skip($chars) | ||
2143 | + { | ||
2144 | + $this->pos += strspn($this->doc, $chars, $this->pos); | ||
2145 | + $this->char = ($this->pos < $this->size) ? $this->doc[$this->pos] : null; // next | ||
2146 | + } | ||
2147 | + | ||
2148 | + protected function copy_skip($chars) | ||
2149 | + { | ||
2150 | + $pos = $this->pos; | ||
2151 | + $len = strspn($this->doc, $chars, $pos); | ||
2152 | + $this->pos += $len; | ||
2153 | + $this->char = ($this->pos < $this->size) ? $this->doc[$this->pos] : null; // next | ||
2154 | + if ($len === 0) { return ''; } | ||
2155 | + return substr($this->doc, $pos, $len); | ||
2156 | + } | ||
2157 | + | ||
2158 | + protected function copy_until($chars) | ||
2159 | + { | ||
2160 | + $pos = $this->pos; | ||
2161 | + $len = strcspn($this->doc, $chars, $pos); | ||
2162 | + $this->pos += $len; | ||
2163 | + $this->char = ($this->pos < $this->size) ? $this->doc[$this->pos] : null; // next | ||
2164 | + return substr($this->doc, $pos, $len); | ||
2165 | + } | ||
2166 | + | ||
2167 | + protected function copy_until_char($char) | ||
2168 | + { | ||
2169 | + if ($this->char === null) { return ''; } | ||
2170 | + | ||
2171 | + if (($pos = strpos($this->doc, $char, $this->pos)) === false) { | ||
2172 | + $ret = substr($this->doc, $this->pos, $this->size - $this->pos); | ||
2173 | + $this->char = null; | ||
2174 | + $this->pos = $this->size; | ||
2175 | + return $ret; | ||
2176 | + } | ||
2177 | + | ||
2178 | + if ($pos === $this->pos) { return ''; } | ||
2179 | + | ||
2180 | + $pos_old = $this->pos; | ||
2181 | + $this->char = $this->doc[$pos]; | ||
2182 | + $this->pos = $pos; | ||
2183 | + return substr($this->doc, $pos_old, $pos - $pos_old); | ||
2184 | + } | ||
2185 | + | ||
2186 | + protected function remove_noise($pattern, $remove_tag = false) | ||
2187 | + { | ||
2188 | + global $debug_object; | ||
2189 | + if (is_object($debug_object)) { $debug_object->debug_log_entry(1); } | ||
2190 | + | ||
2191 | + $count = preg_match_all( | ||
2192 | + $pattern, | ||
2193 | + $this->doc, | ||
2194 | + $matches, | ||
2195 | + PREG_SET_ORDER | PREG_OFFSET_CAPTURE | ||
2196 | + ); | ||
2197 | + | ||
2198 | + for ($i = $count - 1; $i > -1; --$i) { | ||
2199 | + $key = '___noise___' . sprintf('% 5d', count($this->noise) + 1000); | ||
2200 | + | ||
2201 | + if (is_object($debug_object)) { | ||
2202 | + $debug_object->debug_log(2, 'key is: ' . $key); | ||
2203 | + } | ||
2204 | + | ||
2205 | + $idx = ($remove_tag) ? 0 : 1; // 0 = entire match, 1 = submatch | ||
2206 | + $this->noise[$key] = $matches[$i][$idx][0]; | ||
2207 | + $this->doc = substr_replace($this->doc, $key, $matches[$i][$idx][1], strlen($matches[$i][$idx][0])); | ||
2208 | + } | ||
2209 | + | ||
2210 | + // reset the length of content | ||
2211 | + $this->size = strlen($this->doc); | ||
2212 | + | ||
2213 | + if ($this->size > 0) { | ||
2214 | + $this->char = $this->doc[0]; | ||
2215 | + } | ||
2216 | + } | ||
2217 | + | ||
2218 | + function restore_noise($text) | ||
2219 | + { | ||
2220 | + global $debug_object; | ||
2221 | + if (is_object($debug_object)) { $debug_object->debug_log_entry(1); } | ||
2222 | + | ||
2223 | + while (($pos = strpos($text, '___noise___')) !== false) { | ||
2224 | + // Sometimes there is a broken piece of markup, and we don't GET the | ||
2225 | + // pos+11 etc... token which indicates a problem outside of us... | ||
2226 | + | ||
2227 | + // todo: "___noise___1000" (or any number with four or more digits) | ||
2228 | + // in the DOM causes an infinite loop which could be utilized by | ||
2229 | + // malicious software | ||
2230 | + if (strlen($text) > $pos + 15) { | ||
2231 | + $key = '___noise___' | ||
2232 | + . $text[$pos + 11] | ||
2233 | + . $text[$pos + 12] | ||
2234 | + . $text[$pos + 13] | ||
2235 | + . $text[$pos + 14] | ||
2236 | + . $text[$pos + 15]; | ||
2237 | + | ||
2238 | + if (is_object($debug_object)) { | ||
2239 | + $debug_object->debug_log(2, 'located key of: ' . $key); | ||
2240 | + } | ||
2241 | + | ||
2242 | + if (isset($this->noise[$key])) { | ||
2243 | + $text = substr($text, 0, $pos) | ||
2244 | + . $this->noise[$key] | ||
2245 | + . substr($text, $pos + 16); | ||
2246 | + } else { | ||
2247 | + // do this to prevent an infinite loop. | ||
2248 | + $text = substr($text, 0, $pos) | ||
2249 | + . 'UNDEFINED NOISE FOR KEY: ' | ||
2250 | + . $key | ||
2251 | + . substr($text, $pos + 16); | ||
2252 | + } | ||
2253 | + } else { | ||
2254 | + // There is no valid key being given back to us... We must get | ||
2255 | + // rid of the ___noise___ or we will have a problem. | ||
2256 | + $text = substr($text, 0, $pos) | ||
2257 | + . 'NO NUMERIC NOISE KEY' | ||
2258 | + . substr($text, $pos + 11); | ||
2259 | + } | ||
2260 | + } | ||
2261 | + return $text; | ||
2262 | + } | ||
2263 | + | ||
2264 | + function search_noise($text) | ||
2265 | + { | ||
2266 | + global $debug_object; | ||
2267 | + if (is_object($debug_object)) { $debug_object->debug_log_entry(1); } | ||
2268 | + | ||
2269 | + foreach($this->noise as $noiseElement) { | ||
2270 | + if (strpos($noiseElement, $text) !== false) { | ||
2271 | + return $noiseElement; | ||
2272 | + } | ||
2273 | + } | ||
2274 | + } | ||
2275 | + | ||
2276 | + function __toString() | ||
2277 | + { | ||
2278 | + return $this->root->innertext(); | ||
2279 | + } | ||
2280 | + | ||
2281 | + function __get($name) | ||
2282 | + { | ||
2283 | + switch ($name) { | ||
2284 | + case 'outertext': | ||
2285 | + return $this->root->innertext(); | ||
2286 | + case 'innertext': | ||
2287 | + return $this->root->innertext(); | ||
2288 | + case 'plaintext': | ||
2289 | + return $this->root->text(); | ||
2290 | + case 'charset': | ||
2291 | + return $this->_charset; | ||
2292 | + case 'target_charset': | ||
2293 | + return $this->_target_charset; | ||
2294 | + } | ||
2295 | + } | ||
2296 | + | ||
2297 | + function childNodes($idx = -1) | ||
2298 | + { | ||
2299 | + return $this->root->childNodes($idx); | ||
2300 | + } | ||
2301 | + | ||
2302 | + function firstChild() | ||
2303 | + { | ||
2304 | + return $this->root->first_child(); | ||
2305 | + } | ||
2306 | + | ||
2307 | + function lastChild() | ||
2308 | + { | ||
2309 | + return $this->root->last_child(); | ||
2310 | + } | ||
2311 | + | ||
2312 | + function createElement($name, $value = null) | ||
2313 | + { | ||
2314 | + return @str_get_html("<$name>$value</$name>")->firstChild(); | ||
2315 | + } | ||
2316 | + | ||
2317 | + function createTextNode($value) | ||
2318 | + { | ||
2319 | + return @end(str_get_html($value)->nodes); | ||
2320 | + } | ||
2321 | + | ||
2322 | + function getElementById($id) | ||
2323 | + { | ||
2324 | + return $this->find("#$id", 0); | ||
2325 | + } | ||
2326 | + | ||
2327 | + function getElementsById($id, $idx = null) | ||
2328 | + { | ||
2329 | + return $this->find("#$id", $idx); | ||
2330 | + } | ||
2331 | + | ||
2332 | + function getElementByTagName($name) | ||
2333 | + { | ||
2334 | + return $this->find($name, 0); | ||
2335 | + } | ||
2336 | + | ||
2337 | + function getElementsByTagName($name, $idx = -1) | ||
2338 | + { | ||
2339 | + return $this->find($name, $idx); | ||
2340 | + } | ||
2341 | + | ||
2342 | + function loadFile() | ||
2343 | + { | ||
2344 | + $args = func_get_args(); | ||
2345 | + $this->load_file($args); | ||
2346 | + } | ||
2347 | +} |
php/config.php
@@ -183,7 +183,7 @@ $API = array( | @@ -183,7 +183,7 @@ $API = array( | ||
183 | //AKKA - New action to clean user WS | 183 | //AKKA - New action to clean user WS |
184 | 'cleanUserWS'=>array('len'=>0), | 184 | 'cleanUserWS'=>array('len'=>0), |
185 | 'deleteSpecialInfo'=>array('len'=>1), | 185 | 'deleteSpecialInfo'=>array('len'=>1), |
186 | - 'interactivePlot'=>array('len'=>2), | 186 | + 'interactivePlot'=>array('len'=>1), |
187 | 'getParamPlotInit'=>array('len'=>1), | 187 | 'getParamPlotInit'=>array('len'=>1), |
188 | 'getParamInfo'=>array('len'=>1), | 188 | 'getParamInfo'=>array('len'=>1), |
189 | 'getDerivedParamInfo'=>array('len'=>1), | 189 | 'getDerivedParamInfo'=>array('len'=>1), |
php/downloadPlot.php
@@ -10,19 +10,19 @@ if (!isset($_POST['sessionId'])) | @@ -10,19 +10,19 @@ if (!isset($_POST['sessionId'])) | ||
10 | } | 10 | } |
11 | $sessionId = $_POST['sessionId']; | 11 | $sessionId = $_POST['sessionId']; |
12 | 12 | ||
13 | -if (!isset($_POST['tabId'])) | 13 | +if (!isset($_POST['interactiveId'])) |
14 | { | 14 | { |
15 | header("HTTP/1.0 400 Bad Request"); | 15 | header("HTTP/1.0 400 Bad Request"); |
16 | - echo json_encode(array("success" => false, "error" => "Unknown tab Id")); | 16 | + echo json_encode(array("success" => false, "error" => "Unknown interactive Id")); |
17 | exit; | 17 | exit; |
18 | } | 18 | } |
19 | -$tabId = $_POST['tabId']; | 19 | +$interactiveId = $_POST['interactiveId']; |
20 | 20 | ||
21 | $preview = empty($_POST['preview']) ? FALSE : $_POST['preview']; | 21 | $preview = empty($_POST['preview']) ? FALSE : $_POST['preview']; |
22 | 22 | ||
23 | -download_plot($sessionId, $tabId, $preview); | 23 | +download_plot($sessionId, $interactiveId, $preview); |
24 | 24 | ||
25 | -function download_plot($sessionId, $tabId, $preview) | 25 | +function download_plot($sessionId, $interactiveId, $preview) |
26 | { | 26 | { |
27 | // Must be fresh start | 27 | // Must be fresh start |
28 | if( headers_sent() ) | 28 | if( headers_sent() ) |
@@ -38,10 +38,10 @@ function download_plot($sessionId, $tabId, $preview) | @@ -38,10 +38,10 @@ function download_plot($sessionId, $tabId, $preview) | ||
38 | 38 | ||
39 | //Build file path | 39 | //Build file path |
40 | if (!$preview) { | 40 | if (!$preview) { |
41 | - $fullPath = USERPATH."/".$sessionId."/RES/Plot_/".$tabId.".png"; | 41 | + $fullPath = USERPATH."/".$sessionId."/RES/Plot_/".$interactiveId.".png"; |
42 | } | 42 | } |
43 | else { | 43 | else { |
44 | - $fullPath = USERPATH."/".$sessionId."/RES/Plot_/".str_replace('plot_','instant',$tabId).".png"; | 44 | + $fullPath = USERPATH."/".$sessionId."/RES/Plot_/".str_replace('plot_','instant',$interactiveId).".png"; |
45 | } | 45 | } |
46 | // File Exists? | 46 | // File Exists? |
47 | if( file_exists($fullPath) ){ | 47 | if( file_exists($fullPath) ){ |
php/src/cdfsamplingfromdata.c
@@ -126,7 +126,7 @@ int main(int argc, char *argv[]) | @@ -126,7 +126,7 @@ int main(int argc, char *argv[]) | ||
126 | if (datatype == CDF_TIME_TT2000) { | 126 | if (datatype == CDF_TIME_TT2000) { |
127 | dbl_value_ = CDF_TT2000_to_UTC_EPOCH(int_value[0]); | 127 | dbl_value_ = CDF_TT2000_to_UTC_EPOCH(int_value[0]); |
128 | dbl_value = CDF_TT2000_to_UTC_EPOCH(int_value[1]); | 128 | dbl_value = CDF_TT2000_to_UTC_EPOCH(int_value[1]); |
129 | - sampling = (int)(dbl_value - dbl_value_ + 50)/100; | 129 | + sampling = (int)(dbl_value - dbl_value_); |
130 | } | 130 | } |
131 | else { | 131 | else { |
132 | if (datatype == CDF_EPOCH16) { | 132 | if (datatype == CDF_EPOCH16) { |
@@ -139,7 +139,7 @@ int main(int argc, char *argv[]) | @@ -139,7 +139,7 @@ int main(int argc, char *argv[]) | ||
139 | EPOCH16breakdown(epoch16, &year, &month, &day, &hour, &minute, &sec, &msec, &mksec, &nsec, &psec); | 139 | EPOCH16breakdown(epoch16, &year, &month, &day, &hour, &minute, &sec, &msec, &mksec, &nsec, &psec); |
140 | value[1] = computeEPOCH(year, month, day, hour, minute, sec, msec); | 140 | value[1] = computeEPOCH(year, month, day, hour, minute, sec, msec); |
141 | } | 141 | } |
142 | - sampling = (int)(value[1] - value[0] + 50)/100; | 142 | + sampling = (int)(value[1] - value[0]); |
143 | } | 143 | } |
144 | 144 | ||
145 | // fprintf(stdout,"value %f\n", value[11]-value[10]); | 145 | // fprintf(stdout,"value %f\n", value[11]-value[10]); |
@@ -150,5 +150,5 @@ int main(int argc, char *argv[]) | @@ -150,5 +150,5 @@ int main(int argc, char *argv[]) | ||
150 | if ((cstatus = CDFlib(CLOSE_, CDF_, NULL_)) != CDF_OK) | 150 | if ((cstatus = CDFlib(CLOSE_, CDF_, NULL_)) != CDF_OK) |
151 | cdf_handle_error (cstatus); | 151 | cdf_handle_error (cstatus); |
152 | 152 | ||
153 | - fprintf(stdout,"%f\n",(float)sampling/10.0); | 153 | + fprintf(stdout,"%f\n",(float)sampling/1000.0); // in sec.msec |
154 | } | 154 | } |
php/src/cdfsamplingsfromdata.c
@@ -162,7 +162,7 @@ int main(int argc, char *argv[]) | @@ -162,7 +162,7 @@ int main(int argc, char *argv[]) | ||
162 | if (datatype == CDF_TIME_TT2000) { | 162 | if (datatype == CDF_TIME_TT2000) { |
163 | dbl_value_ = CDF_TT2000_to_UTC_EPOCH(int_value[i-1]); | 163 | dbl_value_ = CDF_TT2000_to_UTC_EPOCH(int_value[i-1]); |
164 | dbl_value = CDF_TT2000_to_UTC_EPOCH(int_value[i]); | 164 | dbl_value = CDF_TT2000_to_UTC_EPOCH(int_value[i]); |
165 | - delta[i-1] = (int)(dbl_value - dbl_value_ + 50)/100; | 165 | + delta[i-1] = (int)(dbl_value - dbl_value_); |
166 | } | 166 | } |
167 | else { | 167 | else { |
168 | if (datatype == CDF_EPOCH16) { | 168 | if (datatype == CDF_EPOCH16) { |
@@ -175,7 +175,7 @@ int main(int argc, char *argv[]) | @@ -175,7 +175,7 @@ int main(int argc, char *argv[]) | ||
175 | EPOCH16breakdown(epoch16, &year, &month, &day, &hour, &minute, &sec, &msec, &mksec, &nsec, &psec); | 175 | EPOCH16breakdown(epoch16, &year, &month, &day, &hour, &minute, &sec, &msec, &mksec, &nsec, &psec); |
176 | value[i] = computeEPOCH(year, month, day, hour, minute, sec, msec); | 176 | value[i] = computeEPOCH(year, month, day, hour, minute, sec, msec); |
177 | } | 177 | } |
178 | - delta[i-1] = (int)(value[i] - value[i-1] + 50)/100; | 178 | + delta[i-1] = (int)(value[i] - value[i-1]); |
179 | } | 179 | } |
180 | } | 180 | } |
181 | // fprintf(stdout,"value %f\n", value[11]-value[10]); | 181 | // fprintf(stdout,"value %f\n", value[11]-value[10]); |
@@ -194,5 +194,5 @@ int main(int argc, char *argv[]) | @@ -194,5 +194,5 @@ int main(int argc, char *argv[]) | ||
194 | cdf_handle_error (cstatus); | 194 | cdf_handle_error (cstatus); |
195 | 195 | ||
196 | // fprintf(stdout,"%d %f\n",min[1], (float)min[0]/100.0); | 196 | // fprintf(stdout,"%d %f\n",min[1], (float)min[0]/100.0); |
197 | - fprintf(stdout,"%f\n",(float)min[0]/10.0); | 197 | + fprintf(stdout,"%f\n",(float)min[0]/1000.0); |
198 | } | 198 | } |