]>
Commit | Line | Data |
---|---|---|
6527f429 DM |
1 | /**\r |
2 | * A class which encapsulates a range of columns defining a selection in a grid.\r | |
3 | * @since 5.1.0\r | |
4 | */\r | |
5 | Ext.define('Ext.grid.selection.Columns', {\r | |
6 | extend: 'Ext.grid.selection.Selection',\r | |
7 | \r | |
8 | type: 'columns',\r | |
9 | \r | |
10 | /**\r | |
11 | * @property {Boolean} isColumns\r | |
12 | * This property indicates the this selection represents selected columns.\r | |
13 | * @readonly\r | |
14 | */\r | |
15 | isColumns: true,\r | |
16 | \r | |
17 | //-------------------------------------------------------------------------\r | |
18 | // Base Selection API\r | |
19 | \r | |
20 | clone: function() {\r | |
21 | var me = this,\r | |
22 | result = new me.self(me.view),\r | |
23 | columns = me.selectedColumns;\r | |
24 | \r | |
25 | if (columns) {\r | |
26 | result.selectedColumns = Ext.Array.slice(columns);\r | |
27 | }\r | |
28 | return result;\r | |
29 | },\r | |
30 | \r | |
31 | eachRow: function (fn, scope) {\r | |
32 | var columns = this.selectedColumns;\r | |
33 | \r | |
34 | if (columns && columns.length) {\r | |
35 | this.view.dataSource.each(fn, scope || this);\r | |
36 | }\r | |
37 | },\r | |
38 | \r | |
39 | eachColumn: function (fn, scope) {\r | |
40 | var me = this,\r | |
41 | view = me.view,\r | |
42 | columns = me.selectedColumns,\r | |
43 | len,\r | |
44 | i,\r | |
45 | context = new Ext.grid.CellContext(view);\r | |
46 | \r | |
47 | if (columns) {\r | |
48 | len = columns.length;\r | |
49 | for (i = 0; i < len; i++) {\r | |
50 | context.setColumn(columns[i]);\r | |
51 | if (fn.call(scope || me, context.column, context.colIdx) === false) {\r | |
52 | return false;\r | |
53 | }\r | |
54 | }\r | |
55 | }\r | |
56 | },\r | |
57 | \r | |
58 | eachCell: function (fn, scope) {\r | |
59 | var me = this,\r | |
60 | view = me.view,\r | |
61 | columns = me.selectedColumns,\r | |
62 | len,\r | |
63 | i,\r | |
64 | context = new Ext.grid.CellContext(view);\r | |
65 | \r | |
66 | if (columns) {\r | |
67 | len = columns.length;\r | |
68 | \r | |
69 | // Use Store#each instead of copying the entire dataset into an array and iterating that.\r | |
70 | view.dataSource.each(function(record) {\r | |
71 | context.setRow(record);\r | |
72 | for (i = 0; i < len; i++) {\r | |
73 | context.setColumn(columns[i]);\r | |
74 | if (fn.call(scope || me, context, context.colIdx, context.rowIdx) === false) {\r | |
75 | return false;\r | |
76 | }\r | |
77 | }\r | |
78 | });\r | |
79 | }\r | |
80 | },\r | |
81 | \r | |
82 | //-------------------------------------------------------------------------\r | |
83 | // Methods unique to this type of Selection\r | |
84 | \r | |
85 | /**\r | |
86 | * Returns `true` if the passed {@link Ext.grid.column.Column column} is selected.\r | |
87 | * @param {Ext.grid.column.Column} column The column to test.\r | |
88 | * @return {Boolean} `true` if the passed {@link Ext.grid.column.Column column} is selected.\r | |
89 | */\r | |
90 | contains: function(column) {\r | |
91 | var selectedColumns = this.selectedColumns;\r | |
92 | \r | |
93 | if (column && column.isColumn && selectedColumns && selectedColumns.length) {\r | |
94 | return Ext.Array.contains(selectedColumns, column);\r | |
95 | }\r | |
96 | \r | |
97 | return false;\r | |
98 | },\r | |
99 | \r | |
100 | /**\r | |
101 | * Returns the number of columns selected.\r | |
102 | * @return {Number} The number of columns selected.\r | |
103 | */\r | |
104 | getCount: function() {\r | |
105 | var selectedColumns = this.selectedColumns;\r | |
106 | return selectedColumns ? selectedColumns.length : 0;\r | |
107 | },\r | |
108 | \r | |
109 | /**\r | |
110 | * Returns the columns selected.\r | |
111 | * @return {Ext.grid.column.Column[]} The columns selected.\r | |
112 | */\r | |
113 | getColumns: function() {\r | |
114 | return this.selectedColumns || [];\r | |
115 | },\r | |
116 | \r | |
117 | //-------------------------------------------------------------------------\r | |
118 | \r | |
119 | privates: {\r | |
120 | /**\r | |
121 | * Adds the passed Column to the selection.\r | |
122 | * @param {Ext.grid.column.Column} column\r | |
123 | * @private\r | |
124 | */\r | |
125 | add: function(column) {\r | |
126 | //<debug>\r | |
127 | if (!column.isColumn) {\r | |
128 | Ext.raise('Column selection must be passed a grid Column header object');\r | |
129 | }\r | |
130 | //</debug>\r | |
131 | \r | |
132 | Ext.Array.include((this.selectedColumns || (this.selectedColumns = [])), column);\r | |
133 | this.refreshColumns(column);\r | |
134 | },\r | |
135 | \r | |
136 | /**\r | |
137 | * @private\r | |
138 | */\r | |
139 | clear: function() {\r | |
140 | var me = this,\r | |
141 | prevSelection = me.selectedColumns;\r | |
142 | \r | |
143 | if (prevSelection && prevSelection.length) {\r | |
144 | me.selectedColumns = [];\r | |
145 | me.refreshColumns.apply(me, prevSelection);\r | |
146 | }\r | |
147 | },\r | |
148 | \r | |
149 | /**\r | |
150 | * @return {Boolean}\r | |
151 | * @private\r | |
152 | */\r | |
153 | isAllSelected: function() {\r | |
154 | var selectedColumns = this.selectedColumns;\r | |
155 | \r | |
156 | // All selected means all columns, across both views if we are in a locking assembly.\r | |
157 | return selectedColumns && selectedColumns.length === this.view.ownerGrid.getVisibleColumnManager().getColumns().length;\r | |
158 | },\r | |
159 | \r | |
160 | /**\r | |
161 | * @private\r | |
162 | */\r | |
163 | refreshColumns: function(column) {\r | |
164 | var me = this,\r | |
165 | view = me.view,\r | |
166 | rows = view.all,\r | |
167 | rowIdx,\r | |
168 | columns = arguments,\r | |
169 | len = columns.length,\r | |
170 | colIdx,\r | |
171 | cellContext = new Ext.grid.CellContext(view),\r | |
172 | selected = [];\r | |
173 | \r | |
174 | if (view.rendered) {\r | |
175 | for (colIdx = 0; colIdx < len; colIdx++) {\r | |
176 | selected[colIdx] = me.contains(columns[colIdx]);\r | |
177 | }\r | |
178 | \r | |
179 | for (rowIdx = rows.startIndex; rowIdx <= rows.endIndex; rowIdx++) {\r | |
180 | cellContext.setRow(rowIdx);\r | |
181 | for (colIdx = 0; colIdx < len; colIdx++) {\r | |
182 | // Note colIdx is not the column's visible index. setColumn must be passed the column object\r | |
183 | cellContext.setColumn(columns[colIdx]);\r | |
184 | if (selected[colIdx]) {\r | |
185 | view.onCellSelect(cellContext);\r | |
186 | } else {\r | |
187 | view.onCellDeselect(cellContext);\r | |
188 | }\r | |
189 | }\r | |
190 | }\r | |
191 | }\r | |
192 | },\r | |
193 | \r | |
194 | /**\r | |
195 | * Removes the passed Column from the selection.\r | |
196 | * @param {Ext.grid.column.Column} column\r | |
197 | * @private\r | |
198 | */\r | |
199 | remove: function(column) {\r | |
200 | //<debug>\r | |
201 | if (!column.isColumn) {\r | |
202 | Ext.raise('Column selection must be passed a grid Column header object');\r | |
203 | }\r | |
204 | //</debug>\r | |
205 | \r | |
206 | if (this.selectedColumns) {\r | |
207 | Ext.Array.remove(this.selectedColumns, column);\r | |
208 | \r | |
209 | // Might be being called because of column removal/hiding.\r | |
210 | // In which case the view will have selected cells removed, so no refresh needed.\r | |
211 | if (column.getView() && column.isVisible()) {\r | |
212 | this.refreshColumns(column);\r | |
213 | }\r | |
214 | }\r | |
215 | },\r | |
216 | \r | |
217 | /**\r | |
218 | * @private\r | |
219 | */\r | |
220 | selectAll: function () {\r | |
221 | var me = this;\r | |
222 | \r | |
223 | me.clear();\r | |
224 | me.selectedColumns = me.view.getSelectionModel().lastContiguousColumnRange =\r | |
225 | me.view.getVisibleColumnManager().getColumns();\r | |
226 | me.refreshColumns.apply(me, me.selectedColumns);\r | |
227 | },\r | |
228 | \r | |
229 | extendRange: function(extensionVector) {\r | |
230 | var me = this,\r | |
231 | columns = me.view.getVisibleColumnManager().getColumns(),\r | |
232 | i;\r | |
233 | \r | |
234 | for (i = extensionVector.start.colIdx; i <= extensionVector.end.colIdx; i++) {\r | |
235 | me.add(columns[i]);\r | |
236 | }\r | |
237 | },\r | |
238 | \r | |
239 | onSelectionFinish: function() {\r | |
240 | var me = this,\r | |
241 | range = me.getContiguousSelection();\r | |
242 | \r | |
243 | if (range) {\r | |
244 | me.view.getSelectionModel().onSelectionFinish(me,\r | |
245 | new Ext.grid.CellContext(me.view).setPosition(0, range[0]),\r | |
246 | new Ext.grid.CellContext(me.view).setPosition(me.view.dataSource.getCount() - 1, range[1]));\r | |
247 | } else {\r | |
248 | me.view.getSelectionModel().onSelectionFinish(me);\r | |
249 | }\r | |
250 | },\r | |
251 | \r | |
252 | /**\r | |
253 | * @return {Array} `[startColumn, endColumn]` if the selection represents a visually contiguous set of columns.\r | |
254 | * The SelectionReplicator is only enabled if there is a contiguous block.\r | |
255 | * @private\r | |
256 | */\r | |
257 | getContiguousSelection: function() {\r | |
258 | var selection = Ext.Array.sort(this.selectedColumns, function(c1, c2) {\r | |
259 | // Use index *in ownerGrid* so that a locking assembly can order columns correctly\r | |
260 | return c1.getView().ownerGrid.getVisibleColumnManager().indexOf(c1) - c2.getView().ownerGrid.getVisibleColumnManager().indexOf(c2);\r | |
261 | }),\r | |
262 | len = selection.length,\r | |
263 | i;\r | |
264 | \r | |
265 | if (len) {\r | |
266 | for (i = 1; i < len; i++) {\r | |
267 | if (selection[i].getVisibleIndex() !== selection[i - 1].getVisibleIndex() + 1) {\r | |
268 | return false;\r | |
269 | }\r | |
270 | }\r | |
271 | return [selection[0], selection[len - 1]];\r | |
272 | }\r | |
273 | }\r | |
274 | }\r | |
275 | });\r |