lpmp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (636) hide show
  1. data/LICENSE +3 -0
  2. data/README +3 -0
  3. data/Rakefile +45 -0
  4. data/bin/lpmp +107 -0
  5. data/config/help.yaml +1 -0
  6. data/config/hosts.yaml +2 -0
  7. data/config/log.yaml +1 -0
  8. data/config/memcache.yaml +5 -0
  9. data/erb/index.erb +62 -0
  10. data/lib/bg_pull/caichen.rb +199 -0
  11. data/lib/bg_pull/lpmp.rb +45 -0
  12. data/lib/exception.rb +8 -0
  13. data/lib/lpmp.rb +53 -0
  14. data/lib/pull/lpmp.rb +355 -0
  15. data/lib/remote_lmp.rb +129 -0
  16. data/lib/utils.rb +14 -0
  17. data/lib/xq_push/caichen.rb +174 -0
  18. data/lib/xq_push/lpmp.rb +96 -0
  19. data/log/lpmp1st.log +1 -0
  20. data/public/css/ext-portal.css +40 -0
  21. data/public/css/lpmp.css +6 -0
  22. data/public/designer/caichen.epj +1 -0
  23. data/public/designer/hostmonitor.epj +1 -0
  24. data/public/ext-3.0.0/INCLUDE_ORDER.txt +35 -0
  25. data/public/ext-3.0.0/adapter/ext/ext-base-debug.js +3589 -0
  26. data/public/ext-3.0.0/adapter/ext/ext-base.js +7 -0
  27. data/public/ext-3.0.0/adapter/jquery/ext-jquery-adapter-debug.js +2292 -0
  28. data/public/ext-3.0.0/adapter/jquery/ext-jquery-adapter.js +7 -0
  29. data/public/ext-3.0.0/adapter/prototype/ext-prototype-adapter-debug.js +2346 -0
  30. data/public/ext-3.0.0/adapter/prototype/ext-prototype-adapter.js +7 -0
  31. data/public/ext-3.0.0/adapter/yui/ext-yui-adapter-debug.js +2136 -0
  32. data/public/ext-3.0.0/adapter/yui/ext-yui-adapter.js +7 -0
  33. data/public/ext-3.0.0/ext-all-debug.js +65610 -0
  34. data/public/ext-3.0.0/ext-all.js +11 -0
  35. data/public/ext-3.0.0/license.txt +42 -0
  36. data/public/ext-3.0.0/pkgs/cmp-foundation-debug.js +11287 -0
  37. data/public/ext-3.0.0/pkgs/cmp-foundation.js +7 -0
  38. data/public/ext-3.0.0/pkgs/data-foundation-debug.js +3853 -0
  39. data/public/ext-3.0.0/pkgs/data-foundation.js +7 -0
  40. data/public/ext-3.0.0/pkgs/data-grouping-debug.js +139 -0
  41. data/public/ext-3.0.0/pkgs/data-grouping.js +7 -0
  42. data/public/ext-3.0.0/pkgs/data-json-debug.js +582 -0
  43. data/public/ext-3.0.0/pkgs/data-json.js +7 -0
  44. data/public/ext-3.0.0/pkgs/data-list-views-debug.js +1278 -0
  45. data/public/ext-3.0.0/pkgs/data-list-views.js +7 -0
  46. data/public/ext-3.0.0/pkgs/data-xml-debug.js +234 -0
  47. data/public/ext-3.0.0/pkgs/data-xml.js +7 -0
  48. data/public/ext-3.0.0/pkgs/direct-debug.js +1121 -0
  49. data/public/ext-3.0.0/pkgs/direct.js +7 -0
  50. data/public/ext-3.0.0/pkgs/ext-dd-debug.js +4567 -0
  51. data/public/ext-3.0.0/pkgs/ext-dd.js +7 -0
  52. data/public/ext-3.0.0/pkgs/ext-foundation-debug.js +13417 -0
  53. data/public/ext-3.0.0/pkgs/ext-foundation.js +7 -0
  54. data/public/ext-3.0.0/pkgs/pkg-buttons-debug.js +1060 -0
  55. data/public/ext-3.0.0/pkgs/pkg-buttons.js +7 -0
  56. data/public/ext-3.0.0/pkgs/pkg-charts-debug.js +1621 -0
  57. data/public/ext-3.0.0/pkgs/pkg-charts.js +10 -0
  58. data/public/ext-3.0.0/pkgs/pkg-forms-debug.js +7661 -0
  59. data/public/ext-3.0.0/pkgs/pkg-forms.js +7 -0
  60. data/public/ext-3.0.0/pkgs/pkg-grid-editor-debug.js +560 -0
  61. data/public/ext-3.0.0/pkgs/pkg-grid-editor.js +7 -0
  62. data/public/ext-3.0.0/pkgs/pkg-grid-foundation-debug.js +4765 -0
  63. data/public/ext-3.0.0/pkgs/pkg-grid-foundation.js +7 -0
  64. data/public/ext-3.0.0/pkgs/pkg-grid-grouping-debug.js +517 -0
  65. data/public/ext-3.0.0/pkgs/pkg-grid-grouping.js +7 -0
  66. data/public/ext-3.0.0/pkgs/pkg-grid-property-debug.js +370 -0
  67. data/public/ext-3.0.0/pkgs/pkg-grid-property.js +7 -0
  68. data/public/ext-3.0.0/pkgs/pkg-history-debug.js +203 -0
  69. data/public/ext-3.0.0/pkgs/pkg-history.js +7 -0
  70. data/public/ext-3.0.0/pkgs/pkg-menu-debug.js +1628 -0
  71. data/public/ext-3.0.0/pkgs/pkg-menu.js +7 -0
  72. data/public/ext-3.0.0/pkgs/pkg-tabs-debug.js +1100 -0
  73. data/public/ext-3.0.0/pkgs/pkg-tabs.js +7 -0
  74. data/public/ext-3.0.0/pkgs/pkg-tips-debug.js +994 -0
  75. data/public/ext-3.0.0/pkgs/pkg-tips.js +7 -0
  76. data/public/ext-3.0.0/pkgs/pkg-toolbars-debug.js +1374 -0
  77. data/public/ext-3.0.0/pkgs/pkg-toolbars.js +7 -0
  78. data/public/ext-3.0.0/pkgs/pkg-tree-debug.js +4522 -0
  79. data/public/ext-3.0.0/pkgs/pkg-tree.js +7 -0
  80. data/public/ext-3.0.0/pkgs/resizable-debug.js +760 -0
  81. data/public/ext-3.0.0/pkgs/resizable.js +7 -0
  82. data/public/ext-3.0.0/pkgs/state-debug.js +274 -0
  83. data/public/ext-3.0.0/pkgs/state.js +7 -0
  84. data/public/ext-3.0.0/pkgs/window-debug.js +1888 -0
  85. data/public/ext-3.0.0/pkgs/window.js +7 -0
  86. data/public/ext-3.0.0/resources/charts.swf +0 -0
  87. data/public/ext-3.0.0/resources/css/README.txt +3 -0
  88. data/public/ext-3.0.0/resources/css/ext-all-notheme.css +5345 -0
  89. data/public/ext-3.0.0/resources/css/ext-all.css +6990 -0
  90. data/public/ext-3.0.0/resources/css/reset-min.css +7 -0
  91. data/public/ext-3.0.0/resources/css/structure/borders.css +54 -0
  92. data/public/ext-3.0.0/resources/css/structure/box.css +80 -0
  93. data/public/ext-3.0.0/resources/css/structure/button.css +440 -0
  94. data/public/ext-3.0.0/resources/css/structure/combo.css +45 -0
  95. data/public/ext-3.0.0/resources/css/structure/core.css +326 -0
  96. data/public/ext-3.0.0/resources/css/structure/date-picker.css +265 -0
  97. data/public/ext-3.0.0/resources/css/structure/dd.css +61 -0
  98. data/public/ext-3.0.0/resources/css/structure/debug.css +26 -0
  99. data/public/ext-3.0.0/resources/css/structure/dialog.css +62 -0
  100. data/public/ext-3.0.0/resources/css/structure/editor.css +92 -0
  101. data/public/ext-3.0.0/resources/css/structure/form.css +562 -0
  102. data/public/ext-3.0.0/resources/css/structure/grid.css +552 -0
  103. data/public/ext-3.0.0/resources/css/structure/layout.css +296 -0
  104. data/public/ext-3.0.0/resources/css/structure/list-view.css +85 -0
  105. data/public/ext-3.0.0/resources/css/structure/menu.css +205 -0
  106. data/public/ext-3.0.0/resources/css/structure/panel-reset.css +130 -0
  107. data/public/ext-3.0.0/resources/css/structure/panel.css +468 -0
  108. data/public/ext-3.0.0/resources/css/structure/progress.css +42 -0
  109. data/public/ext-3.0.0/resources/css/structure/qtips.css +153 -0
  110. data/public/ext-3.0.0/resources/css/structure/reset.css +7 -0
  111. data/public/ext-3.0.0/resources/css/structure/resizable.css +149 -0
  112. data/public/ext-3.0.0/resources/css/structure/slider.css +103 -0
  113. data/public/ext-3.0.0/resources/css/structure/tabs.css +372 -0
  114. data/public/ext-3.0.0/resources/css/structure/toolbar.css +259 -0
  115. data/public/ext-3.0.0/resources/css/structure/tree.css +203 -0
  116. data/public/ext-3.0.0/resources/css/structure/window.css +222 -0
  117. data/public/ext-3.0.0/resources/css/visual/borders.css +25 -0
  118. data/public/ext-3.0.0/resources/css/visual/box.css +74 -0
  119. data/public/ext-3.0.0/resources/css/visual/button.css +94 -0
  120. data/public/ext-3.0.0/resources/css/visual/combo.css +43 -0
  121. data/public/ext-3.0.0/resources/css/visual/core.css +76 -0
  122. data/public/ext-3.0.0/resources/css/visual/date-picker.css +143 -0
  123. data/public/ext-3.0.0/resources/css/visual/dd.css +29 -0
  124. data/public/ext-3.0.0/resources/css/visual/debug.css +24 -0
  125. data/public/ext-3.0.0/resources/css/visual/dialog.css +34 -0
  126. data/public/ext-3.0.0/resources/css/visual/editor.css +13 -0
  127. data/public/ext-3.0.0/resources/css/visual/form.css +117 -0
  128. data/public/ext-3.0.0/resources/css/visual/grid.css +272 -0
  129. data/public/ext-3.0.0/resources/css/visual/layout.css +53 -0
  130. data/public/ext-3.0.0/resources/css/visual/list-view.css +37 -0
  131. data/public/ext-3.0.0/resources/css/visual/menu.css +82 -0
  132. data/public/ext-3.0.0/resources/css/visual/panel.css +87 -0
  133. data/public/ext-3.0.0/resources/css/visual/progress.css +32 -0
  134. data/public/ext-3.0.0/resources/css/visual/qtips.css +44 -0
  135. data/public/ext-3.0.0/resources/css/visual/resizable.css +43 -0
  136. data/public/ext-3.0.0/resources/css/visual/slider.css +21 -0
  137. data/public/ext-3.0.0/resources/css/visual/tabs.css +119 -0
  138. data/public/ext-3.0.0/resources/css/visual/toolbar.css +103 -0
  139. data/public/ext-3.0.0/resources/css/visual/tree.css +157 -0
  140. data/public/ext-3.0.0/resources/css/visual/window.css +86 -0
  141. data/public/ext-3.0.0/resources/css/xtheme-blue.css +1652 -0
  142. data/public/ext-3.0.0/resources/expressinstall.swf +0 -0
  143. data/public/ext-3.0.0/resources/images/default/box/corners-blue.gif +0 -0
  144. data/public/ext-3.0.0/resources/images/default/box/corners.gif +0 -0
  145. data/public/ext-3.0.0/resources/images/default/box/l-blue.gif +0 -0
  146. data/public/ext-3.0.0/resources/images/default/box/l.gif +0 -0
  147. data/public/ext-3.0.0/resources/images/default/box/r-blue.gif +0 -0
  148. data/public/ext-3.0.0/resources/images/default/box/r.gif +0 -0
  149. data/public/ext-3.0.0/resources/images/default/box/tb-blue.gif +0 -0
  150. data/public/ext-3.0.0/resources/images/default/box/tb.gif +0 -0
  151. data/public/ext-3.0.0/resources/images/default/button/arrow.gif +0 -0
  152. data/public/ext-3.0.0/resources/images/default/button/btn.gif +0 -0
  153. data/public/ext-3.0.0/resources/images/default/button/group-cs.gif +0 -0
  154. data/public/ext-3.0.0/resources/images/default/button/group-lr.gif +0 -0
  155. data/public/ext-3.0.0/resources/images/default/button/group-tb.gif +0 -0
  156. data/public/ext-3.0.0/resources/images/default/button/s-arrow-b-noline.gif +0 -0
  157. data/public/ext-3.0.0/resources/images/default/button/s-arrow-b.gif +0 -0
  158. data/public/ext-3.0.0/resources/images/default/button/s-arrow-bo.gif +0 -0
  159. data/public/ext-3.0.0/resources/images/default/button/s-arrow-noline.gif +0 -0
  160. data/public/ext-3.0.0/resources/images/default/button/s-arrow-o.gif +0 -0
  161. data/public/ext-3.0.0/resources/images/default/button/s-arrow.gif +0 -0
  162. data/public/ext-3.0.0/resources/images/default/dd/drop-add.gif +0 -0
  163. data/public/ext-3.0.0/resources/images/default/dd/drop-no.gif +0 -0
  164. data/public/ext-3.0.0/resources/images/default/dd/drop-yes.gif +0 -0
  165. data/public/ext-3.0.0/resources/images/default/editor/tb-sprite.gif +0 -0
  166. data/public/ext-3.0.0/resources/images/default/form/checkbox.gif +0 -0
  167. data/public/ext-3.0.0/resources/images/default/form/clear-trigger.gif +0 -0
  168. data/public/ext-3.0.0/resources/images/default/form/clear-trigger.psd +0 -0
  169. data/public/ext-3.0.0/resources/images/default/form/date-trigger.gif +0 -0
  170. data/public/ext-3.0.0/resources/images/default/form/date-trigger.psd +0 -0
  171. data/public/ext-3.0.0/resources/images/default/form/error-tip-corners.gif +0 -0
  172. data/public/ext-3.0.0/resources/images/default/form/exclamation.gif +0 -0
  173. data/public/ext-3.0.0/resources/images/default/form/radio.gif +0 -0
  174. data/public/ext-3.0.0/resources/images/default/form/search-trigger.gif +0 -0
  175. data/public/ext-3.0.0/resources/images/default/form/search-trigger.psd +0 -0
  176. data/public/ext-3.0.0/resources/images/default/form/text-bg.gif +0 -0
  177. data/public/ext-3.0.0/resources/images/default/form/trigger-tpl.gif +0 -0
  178. data/public/ext-3.0.0/resources/images/default/form/trigger.gif +0 -0
  179. data/public/ext-3.0.0/resources/images/default/form/trigger.psd +0 -0
  180. data/public/ext-3.0.0/resources/images/default/gradient-bg.gif +0 -0
  181. data/public/ext-3.0.0/resources/images/default/grid/arrow-left-white.gif +0 -0
  182. data/public/ext-3.0.0/resources/images/default/grid/arrow-right-white.gif +0 -0
  183. data/public/ext-3.0.0/resources/images/default/grid/col-move-bottom.gif +0 -0
  184. data/public/ext-3.0.0/resources/images/default/grid/col-move-top.gif +0 -0
  185. data/public/ext-3.0.0/resources/images/default/grid/columns.gif +0 -0
  186. data/public/ext-3.0.0/resources/images/default/grid/dirty.gif +0 -0
  187. data/public/ext-3.0.0/resources/images/default/grid/done.gif +0 -0
  188. data/public/ext-3.0.0/resources/images/default/grid/drop-no.gif +0 -0
  189. data/public/ext-3.0.0/resources/images/default/grid/drop-yes.gif +0 -0
  190. data/public/ext-3.0.0/resources/images/default/grid/footer-bg.gif +0 -0
  191. data/public/ext-3.0.0/resources/images/default/grid/grid-blue-hd.gif +0 -0
  192. data/public/ext-3.0.0/resources/images/default/grid/grid-blue-split.gif +0 -0
  193. data/public/ext-3.0.0/resources/images/default/grid/grid-hrow.gif +0 -0
  194. data/public/ext-3.0.0/resources/images/default/grid/grid-loading.gif +0 -0
  195. data/public/ext-3.0.0/resources/images/default/grid/grid-split.gif +0 -0
  196. data/public/ext-3.0.0/resources/images/default/grid/grid-vista-hd.gif +0 -0
  197. data/public/ext-3.0.0/resources/images/default/grid/grid3-hd-btn.gif +0 -0
  198. data/public/ext-3.0.0/resources/images/default/grid/grid3-hrow-over.gif +0 -0
  199. data/public/ext-3.0.0/resources/images/default/grid/grid3-hrow.gif +0 -0
  200. data/public/ext-3.0.0/resources/images/default/grid/grid3-special-col-bg.gif +0 -0
  201. data/public/ext-3.0.0/resources/images/default/grid/grid3-special-col-sel-bg.gif +0 -0
  202. data/public/ext-3.0.0/resources/images/default/grid/group-by.gif +0 -0
  203. data/public/ext-3.0.0/resources/images/default/grid/group-collapse.gif +0 -0
  204. data/public/ext-3.0.0/resources/images/default/grid/group-expand-sprite.gif +0 -0
  205. data/public/ext-3.0.0/resources/images/default/grid/group-expand.gif +0 -0
  206. data/public/ext-3.0.0/resources/images/default/grid/hd-pop.gif +0 -0
  207. data/public/ext-3.0.0/resources/images/default/grid/hmenu-asc.gif +0 -0
  208. data/public/ext-3.0.0/resources/images/default/grid/hmenu-desc.gif +0 -0
  209. data/public/ext-3.0.0/resources/images/default/grid/hmenu-lock.gif +0 -0
  210. data/public/ext-3.0.0/resources/images/default/grid/hmenu-lock.png +0 -0
  211. data/public/ext-3.0.0/resources/images/default/grid/hmenu-unlock.gif +0 -0
  212. data/public/ext-3.0.0/resources/images/default/grid/hmenu-unlock.png +0 -0
  213. data/public/ext-3.0.0/resources/images/default/grid/invalid_line.gif +0 -0
  214. data/public/ext-3.0.0/resources/images/default/grid/loading.gif +0 -0
  215. data/public/ext-3.0.0/resources/images/default/grid/mso-hd.gif +0 -0
  216. data/public/ext-3.0.0/resources/images/default/grid/nowait.gif +0 -0
  217. data/public/ext-3.0.0/resources/images/default/grid/page-first-disabled.gif +0 -0
  218. data/public/ext-3.0.0/resources/images/default/grid/page-first.gif +0 -0
  219. data/public/ext-3.0.0/resources/images/default/grid/page-last-disabled.gif +0 -0
  220. data/public/ext-3.0.0/resources/images/default/grid/page-last.gif +0 -0
  221. data/public/ext-3.0.0/resources/images/default/grid/page-next-disabled.gif +0 -0
  222. data/public/ext-3.0.0/resources/images/default/grid/page-next.gif +0 -0
  223. data/public/ext-3.0.0/resources/images/default/grid/page-prev-disabled.gif +0 -0
  224. data/public/ext-3.0.0/resources/images/default/grid/page-prev.gif +0 -0
  225. data/public/ext-3.0.0/resources/images/default/grid/pick-button.gif +0 -0
  226. data/public/ext-3.0.0/resources/images/default/grid/refresh.gif +0 -0
  227. data/public/ext-3.0.0/resources/images/default/grid/row-check-sprite.gif +0 -0
  228. data/public/ext-3.0.0/resources/images/default/grid/row-expand-sprite.gif +0 -0
  229. data/public/ext-3.0.0/resources/images/default/grid/row-over.gif +0 -0
  230. data/public/ext-3.0.0/resources/images/default/grid/row-sel.gif +0 -0
  231. data/public/ext-3.0.0/resources/images/default/grid/sort-hd.gif +0 -0
  232. data/public/ext-3.0.0/resources/images/default/grid/sort_asc.gif +0 -0
  233. data/public/ext-3.0.0/resources/images/default/grid/sort_desc.gif +0 -0
  234. data/public/ext-3.0.0/resources/images/default/grid/wait.gif +0 -0
  235. data/public/ext-3.0.0/resources/images/default/layout/collapse.gif +0 -0
  236. data/public/ext-3.0.0/resources/images/default/layout/expand.gif +0 -0
  237. data/public/ext-3.0.0/resources/images/default/layout/gradient-bg.gif +0 -0
  238. data/public/ext-3.0.0/resources/images/default/layout/mini-bottom.gif +0 -0
  239. data/public/ext-3.0.0/resources/images/default/layout/mini-left.gif +0 -0
  240. data/public/ext-3.0.0/resources/images/default/layout/mini-right.gif +0 -0
  241. data/public/ext-3.0.0/resources/images/default/layout/mini-top.gif +0 -0
  242. data/public/ext-3.0.0/resources/images/default/layout/ns-collapse.gif +0 -0
  243. data/public/ext-3.0.0/resources/images/default/layout/ns-expand.gif +0 -0
  244. data/public/ext-3.0.0/resources/images/default/layout/panel-close.gif +0 -0
  245. data/public/ext-3.0.0/resources/images/default/layout/panel-title-bg.gif +0 -0
  246. data/public/ext-3.0.0/resources/images/default/layout/panel-title-light-bg.gif +0 -0
  247. data/public/ext-3.0.0/resources/images/default/layout/stick.gif +0 -0
  248. data/public/ext-3.0.0/resources/images/default/layout/stuck.gif +0 -0
  249. data/public/ext-3.0.0/resources/images/default/layout/tab-close-on.gif +0 -0
  250. data/public/ext-3.0.0/resources/images/default/layout/tab-close.gif +0 -0
  251. data/public/ext-3.0.0/resources/images/default/menu/checked.gif +0 -0
  252. data/public/ext-3.0.0/resources/images/default/menu/group-checked.gif +0 -0
  253. data/public/ext-3.0.0/resources/images/default/menu/item-over.gif +0 -0
  254. data/public/ext-3.0.0/resources/images/default/menu/menu-parent.gif +0 -0
  255. data/public/ext-3.0.0/resources/images/default/menu/menu.gif +0 -0
  256. data/public/ext-3.0.0/resources/images/default/menu/unchecked.gif +0 -0
  257. data/public/ext-3.0.0/resources/images/default/panel/corners-sprite.gif +0 -0
  258. data/public/ext-3.0.0/resources/images/default/panel/left-right.gif +0 -0
  259. data/public/ext-3.0.0/resources/images/default/panel/light-hd.gif +0 -0
  260. data/public/ext-3.0.0/resources/images/default/panel/tool-sprite-tpl.gif +0 -0
  261. data/public/ext-3.0.0/resources/images/default/panel/tool-sprites.gif +0 -0
  262. data/public/ext-3.0.0/resources/images/default/panel/tools-sprites-trans.gif +0 -0
  263. data/public/ext-3.0.0/resources/images/default/panel/top-bottom.gif +0 -0
  264. data/public/ext-3.0.0/resources/images/default/panel/top-bottom.png +0 -0
  265. data/public/ext-3.0.0/resources/images/default/panel/white-corners-sprite.gif +0 -0
  266. data/public/ext-3.0.0/resources/images/default/panel/white-left-right.gif +0 -0
  267. data/public/ext-3.0.0/resources/images/default/panel/white-top-bottom.gif +0 -0
  268. data/public/ext-3.0.0/resources/images/default/progress/progress-bg.gif +0 -0
  269. data/public/ext-3.0.0/resources/images/default/qtip/bg.gif +0 -0
  270. data/public/ext-3.0.0/resources/images/default/qtip/close.gif +0 -0
  271. data/public/ext-3.0.0/resources/images/default/qtip/tip-anchor-sprite.gif +0 -0
  272. data/public/ext-3.0.0/resources/images/default/qtip/tip-sprite.gif +0 -0
  273. data/public/ext-3.0.0/resources/images/default/s.gif +0 -0
  274. data/public/ext-3.0.0/resources/images/default/shadow-c.png +0 -0
  275. data/public/ext-3.0.0/resources/images/default/shadow-lr.png +0 -0
  276. data/public/ext-3.0.0/resources/images/default/shadow.png +0 -0
  277. data/public/ext-3.0.0/resources/images/default/shared/blue-loading.gif +0 -0
  278. data/public/ext-3.0.0/resources/images/default/shared/calendar.gif +0 -0
  279. data/public/ext-3.0.0/resources/images/default/shared/glass-bg.gif +0 -0
  280. data/public/ext-3.0.0/resources/images/default/shared/hd-sprite.gif +0 -0
  281. data/public/ext-3.0.0/resources/images/default/shared/large-loading.gif +0 -0
  282. data/public/ext-3.0.0/resources/images/default/shared/left-btn.gif +0 -0
  283. data/public/ext-3.0.0/resources/images/default/shared/loading-balls.gif +0 -0
  284. data/public/ext-3.0.0/resources/images/default/shared/right-btn.gif +0 -0
  285. data/public/ext-3.0.0/resources/images/default/shared/warning.gif +0 -0
  286. data/public/ext-3.0.0/resources/images/default/sizer/e-handle-dark.gif +0 -0
  287. data/public/ext-3.0.0/resources/images/default/sizer/e-handle.gif +0 -0
  288. data/public/ext-3.0.0/resources/images/default/sizer/ne-handle-dark.gif +0 -0
  289. data/public/ext-3.0.0/resources/images/default/sizer/ne-handle.gif +0 -0
  290. data/public/ext-3.0.0/resources/images/default/sizer/nw-handle-dark.gif +0 -0
  291. data/public/ext-3.0.0/resources/images/default/sizer/nw-handle.gif +0 -0
  292. data/public/ext-3.0.0/resources/images/default/sizer/s-handle-dark.gif +0 -0
  293. data/public/ext-3.0.0/resources/images/default/sizer/s-handle.gif +0 -0
  294. data/public/ext-3.0.0/resources/images/default/sizer/se-handle-dark.gif +0 -0
  295. data/public/ext-3.0.0/resources/images/default/sizer/se-handle.gif +0 -0
  296. data/public/ext-3.0.0/resources/images/default/sizer/square.gif +0 -0
  297. data/public/ext-3.0.0/resources/images/default/sizer/sw-handle-dark.gif +0 -0
  298. data/public/ext-3.0.0/resources/images/default/sizer/sw-handle.gif +0 -0
  299. data/public/ext-3.0.0/resources/images/default/slider/slider-bg.png +0 -0
  300. data/public/ext-3.0.0/resources/images/default/slider/slider-thumb.png +0 -0
  301. data/public/ext-3.0.0/resources/images/default/slider/slider-v-bg.png +0 -0
  302. data/public/ext-3.0.0/resources/images/default/slider/slider-v-thumb.png +0 -0
  303. data/public/ext-3.0.0/resources/images/default/tabs/scroll-left.gif +0 -0
  304. data/public/ext-3.0.0/resources/images/default/tabs/scroll-right.gif +0 -0
  305. data/public/ext-3.0.0/resources/images/default/tabs/scroller-bg.gif +0 -0
  306. data/public/ext-3.0.0/resources/images/default/tabs/tab-btm-inactive-left-bg.gif +0 -0
  307. data/public/ext-3.0.0/resources/images/default/tabs/tab-btm-inactive-right-bg.gif +0 -0
  308. data/public/ext-3.0.0/resources/images/default/tabs/tab-btm-left-bg.gif +0 -0
  309. data/public/ext-3.0.0/resources/images/default/tabs/tab-btm-right-bg.gif +0 -0
  310. data/public/ext-3.0.0/resources/images/default/tabs/tab-close.gif +0 -0
  311. data/public/ext-3.0.0/resources/images/default/tabs/tab-strip-bg.gif +0 -0
  312. data/public/ext-3.0.0/resources/images/default/tabs/tab-strip-bg.png +0 -0
  313. data/public/ext-3.0.0/resources/images/default/tabs/tab-strip-btm-bg.gif +0 -0
  314. data/public/ext-3.0.0/resources/images/default/tabs/tabs-sprite.gif +0 -0
  315. data/public/ext-3.0.0/resources/images/default/toolbar/bg.gif +0 -0
  316. data/public/ext-3.0.0/resources/images/default/toolbar/btn-arrow-light.gif +0 -0
  317. data/public/ext-3.0.0/resources/images/default/toolbar/btn-arrow.gif +0 -0
  318. data/public/ext-3.0.0/resources/images/default/toolbar/btn-over-bg.gif +0 -0
  319. data/public/ext-3.0.0/resources/images/default/toolbar/gray-bg.gif +0 -0
  320. data/public/ext-3.0.0/resources/images/default/toolbar/more.gif +0 -0
  321. data/public/ext-3.0.0/resources/images/default/toolbar/tb-bg.gif +0 -0
  322. data/public/ext-3.0.0/resources/images/default/toolbar/tb-btn-sprite.gif +0 -0
  323. data/public/ext-3.0.0/resources/images/default/toolbar/tb-xl-btn-sprite.gif +0 -0
  324. data/public/ext-3.0.0/resources/images/default/toolbar/tb-xl-sep.gif +0 -0
  325. data/public/ext-3.0.0/resources/images/default/tree/arrows.gif +0 -0
  326. data/public/ext-3.0.0/resources/images/default/tree/drop-add.gif +0 -0
  327. data/public/ext-3.0.0/resources/images/default/tree/drop-between.gif +0 -0
  328. data/public/ext-3.0.0/resources/images/default/tree/drop-no.gif +0 -0
  329. data/public/ext-3.0.0/resources/images/default/tree/drop-over.gif +0 -0
  330. data/public/ext-3.0.0/resources/images/default/tree/drop-under.gif +0 -0
  331. data/public/ext-3.0.0/resources/images/default/tree/drop-yes.gif +0 -0
  332. data/public/ext-3.0.0/resources/images/default/tree/elbow-end-minus-nl.gif +0 -0
  333. data/public/ext-3.0.0/resources/images/default/tree/elbow-end-minus.gif +0 -0
  334. data/public/ext-3.0.0/resources/images/default/tree/elbow-end-plus-nl.gif +0 -0
  335. data/public/ext-3.0.0/resources/images/default/tree/elbow-end-plus.gif +0 -0
  336. data/public/ext-3.0.0/resources/images/default/tree/elbow-end.gif +0 -0
  337. data/public/ext-3.0.0/resources/images/default/tree/elbow-line.gif +0 -0
  338. data/public/ext-3.0.0/resources/images/default/tree/elbow-minus-nl.gif +0 -0
  339. data/public/ext-3.0.0/resources/images/default/tree/elbow-minus.gif +0 -0
  340. data/public/ext-3.0.0/resources/images/default/tree/elbow-plus-nl.gif +0 -0
  341. data/public/ext-3.0.0/resources/images/default/tree/elbow-plus.gif +0 -0
  342. data/public/ext-3.0.0/resources/images/default/tree/elbow.gif +0 -0
  343. data/public/ext-3.0.0/resources/images/default/tree/folder-open.gif +0 -0
  344. data/public/ext-3.0.0/resources/images/default/tree/folder.gif +0 -0
  345. data/public/ext-3.0.0/resources/images/default/tree/leaf.gif +0 -0
  346. data/public/ext-3.0.0/resources/images/default/tree/loading.gif +0 -0
  347. data/public/ext-3.0.0/resources/images/default/tree/s.gif +0 -0
  348. data/public/ext-3.0.0/resources/images/default/window/icon-error.gif +0 -0
  349. data/public/ext-3.0.0/resources/images/default/window/icon-info.gif +0 -0
  350. data/public/ext-3.0.0/resources/images/default/window/icon-question.gif +0 -0
  351. data/public/ext-3.0.0/resources/images/default/window/icon-warning.gif +0 -0
  352. data/public/ext-3.0.0/resources/images/default/window/left-corners.png +0 -0
  353. data/public/ext-3.0.0/resources/images/default/window/left-corners.psd +0 -0
  354. data/public/ext-3.0.0/resources/images/default/window/left-right.png +0 -0
  355. data/public/ext-3.0.0/resources/images/default/window/left-right.psd +0 -0
  356. data/public/ext-3.0.0/resources/images/default/window/right-corners.png +0 -0
  357. data/public/ext-3.0.0/resources/images/default/window/right-corners.psd +0 -0
  358. data/public/ext-3.0.0/resources/images/default/window/top-bottom.png +0 -0
  359. data/public/ext-3.0.0/resources/images/default/window/top-bottom.psd +0 -0
  360. data/public/ext-3.0.0/resources/images/icon/chart.gif +0 -0
  361. data/public/ext-3.0.0/src/adapter/core/ext-base-ajax.js +371 -0
  362. data/public/ext-3.0.0/src/adapter/core/ext-base-anim-extra.js +301 -0
  363. data/public/ext-3.0.0/src/adapter/core/ext-base-anim.js +477 -0
  364. data/public/ext-3.0.0/src/adapter/core/ext-base-begin.js +18 -0
  365. data/public/ext-3.0.0/src/adapter/core/ext-base-dom.js +157 -0
  366. data/public/ext-3.0.0/src/adapter/core/ext-base-end.js +21 -0
  367. data/public/ext-3.0.0/src/adapter/core/ext-base-event.js +453 -0
  368. data/public/ext-3.0.0/src/adapter/core/ext-base-point.js +17 -0
  369. data/public/ext-3.0.0/src/adapter/core/ext-base-region.js +81 -0
  370. data/public/ext-3.0.0/src/adapter/ext-base-dom-more.js +9 -0
  371. data/public/ext-3.0.0/src/adapter/jquery-bridge.js +546 -0
  372. data/public/ext-3.0.0/src/adapter/prototype-bridge.js +600 -0
  373. data/public/ext-3.0.0/src/adapter/yui-bridge.js +390 -0
  374. data/public/ext-3.0.0/src/core/CompositeElement.js +136 -0
  375. data/public/ext-3.0.0/src/core/CompositeElementLite-more.js +102 -0
  376. data/public/ext-3.0.0/src/core/DomHelper-more.js +179 -0
  377. data/public/ext-3.0.0/src/core/Element-more.js +192 -0
  378. data/public/ext-3.0.0/src/core/Element.alignment.js +370 -0
  379. data/public/ext-3.0.0/src/core/Element.dd.js +46 -0
  380. data/public/ext-3.0.0/src/core/Element.fx-more.js +152 -0
  381. data/public/ext-3.0.0/src/core/Element.insertion-more.js +52 -0
  382. data/public/ext-3.0.0/src/core/Element.keys.js +48 -0
  383. data/public/ext-3.0.0/src/core/Element.legacy.js +42 -0
  384. data/public/ext-3.0.0/src/core/Element.position-more.js +165 -0
  385. data/public/ext-3.0.0/src/core/Element.scroll-more.js +110 -0
  386. data/public/ext-3.0.0/src/core/Element.style-more.js +318 -0
  387. data/public/ext-3.0.0/src/core/Error.js +81 -0
  388. data/public/ext-3.0.0/src/core/EventManager-more.js +334 -0
  389. data/public/ext-3.0.0/src/core/Ext-more.js +669 -0
  390. data/public/ext-3.0.0/src/core/Template-more.js +115 -0
  391. data/public/ext-3.0.0/src/core/core/CompositeElementLite.js +197 -0
  392. data/public/ext-3.0.0/src/core/core/DomHelper.js +378 -0
  393. data/public/ext-3.0.0/src/core/core/DomQuery.js +826 -0
  394. data/public/ext-3.0.0/src/core/core/Element.fx.js +324 -0
  395. data/public/ext-3.0.0/src/core/core/Element.insertion.js +147 -0
  396. data/public/ext-3.0.0/src/core/core/Element.js +945 -0
  397. data/public/ext-3.0.0/src/core/core/Element.position.js +303 -0
  398. data/public/ext-3.0.0/src/core/core/Element.scroll.js +58 -0
  399. data/public/ext-3.0.0/src/core/core/Element.style.js +439 -0
  400. data/public/ext-3.0.0/src/core/core/Element.traversal.js +176 -0
  401. data/public/ext-3.0.0/src/core/core/EventManager.js +623 -0
  402. data/public/ext-3.0.0/src/core/core/Ext.js +922 -0
  403. data/public/ext-3.0.0/src/core/core/Fx.js +1115 -0
  404. data/public/ext-3.0.0/src/core/core/Template.js +185 -0
  405. data/public/ext-3.0.0/src/data/Api.js +210 -0
  406. data/public/ext-3.0.0/src/data/ArrayReader.js +102 -0
  407. data/public/ext-3.0.0/src/data/ArrayStore.js +70 -0
  408. data/public/ext-3.0.0/src/data/DataField.js +249 -0
  409. data/public/ext-3.0.0/src/data/DataProxy.js +427 -0
  410. data/public/ext-3.0.0/src/data/DataReader.js +160 -0
  411. data/public/ext-3.0.0/src/data/DataWriter.js +201 -0
  412. data/public/ext-3.0.0/src/data/DirectProxy.js +141 -0
  413. data/public/ext-3.0.0/src/data/DirectStore.js +52 -0
  414. data/public/ext-3.0.0/src/data/GroupingStore.js +139 -0
  415. data/public/ext-3.0.0/src/data/HttpProxy.js +276 -0
  416. data/public/ext-3.0.0/src/data/JsonReader.js +311 -0
  417. data/public/ext-3.0.0/src/data/JsonStore.js +49 -0
  418. data/public/ext-3.0.0/src/data/JsonWriter.js +77 -0
  419. data/public/ext-3.0.0/src/data/MemoryProxy.js +69 -0
  420. data/public/ext-3.0.0/src/data/Record.js +400 -0
  421. data/public/ext-3.0.0/src/data/ScriptTagProxy.js +279 -0
  422. data/public/ext-3.0.0/src/data/SortTypes.js +91 -0
  423. data/public/ext-3.0.0/src/data/Store.js +1492 -0
  424. data/public/ext-3.0.0/src/data/StoreMgr.js +72 -0
  425. data/public/ext-3.0.0/src/data/Tree.js +785 -0
  426. data/public/ext-3.0.0/src/data/XmlReader.js +128 -0
  427. data/public/ext-3.0.0/src/data/XmlStore.js +75 -0
  428. data/public/ext-3.0.0/src/data/XmlWriter.js +45 -0
  429. data/public/ext-3.0.0/src/data/core/Connection.js +575 -0
  430. data/public/ext-3.0.0/src/dd/DDCore.js +2992 -0
  431. data/public/ext-3.0.0/src/dd/DragSource.js +365 -0
  432. data/public/ext-3.0.0/src/dd/DragTracker.js +217 -0
  433. data/public/ext-3.0.0/src/dd/DragZone.js +133 -0
  434. data/public/ext-3.0.0/src/dd/DropTarget.js +115 -0
  435. data/public/ext-3.0.0/src/dd/DropZone.js +262 -0
  436. data/public/ext-3.0.0/src/dd/Registry.js +127 -0
  437. data/public/ext-3.0.0/src/dd/ScrollManager.js +201 -0
  438. data/public/ext-3.0.0/src/dd/StatusProxy.js +171 -0
  439. data/public/ext-3.0.0/src/debug.js +906 -0
  440. data/public/ext-3.0.0/src/direct/Direct.js +235 -0
  441. data/public/ext-3.0.0/src/direct/Event.js +34 -0
  442. data/public/ext-3.0.0/src/direct/JsonProvider.js +45 -0
  443. data/public/ext-3.0.0/src/direct/PollingProvider.js +151 -0
  444. data/public/ext-3.0.0/src/direct/Provider.js +110 -0
  445. data/public/ext-3.0.0/src/direct/RemotingProvider.js +373 -0
  446. data/public/ext-3.0.0/src/direct/Transaction.js +32 -0
  447. data/public/ext-3.0.0/src/locale/ext-lang-af.js +184 -0
  448. data/public/ext-3.0.0/src/locale/ext-lang-bg.js +278 -0
  449. data/public/ext-3.0.0/src/locale/ext-lang-ca.js +315 -0
  450. data/public/ext-3.0.0/src/locale/ext-lang-cs.js +293 -0
  451. data/public/ext-3.0.0/src/locale/ext-lang-da.js +296 -0
  452. data/public/ext-3.0.0/src/locale/ext-lang-de.js +326 -0
  453. data/public/ext-3.0.0/src/locale/ext-lang-el_GR.js +309 -0
  454. data/public/ext-3.0.0/src/locale/ext-lang-en.js +335 -0
  455. data/public/ext-3.0.0/src/locale/ext-lang-en_GB.js +315 -0
  456. data/public/ext-3.0.0/src/locale/ext-lang-es.js +318 -0
  457. data/public/ext-3.0.0/src/locale/ext-lang-fa.js +272 -0
  458. data/public/ext-3.0.0/src/locale/ext-lang-fi.js +302 -0
  459. data/public/ext-3.0.0/src/locale/ext-lang-fr.js +335 -0
  460. data/public/ext-3.0.0/src/locale/ext-lang-fr_CA.js +218 -0
  461. data/public/ext-3.0.0/src/locale/ext-lang-gr.js +175 -0
  462. data/public/ext-3.0.0/src/locale/ext-lang-he.js +292 -0
  463. data/public/ext-3.0.0/src/locale/ext-lang-hr.js +295 -0
  464. data/public/ext-3.0.0/src/locale/ext-lang-hu.js +296 -0
  465. data/public/ext-3.0.0/src/locale/ext-lang-id.js +302 -0
  466. data/public/ext-3.0.0/src/locale/ext-lang-it.js +295 -0
  467. data/public/ext-3.0.0/src/locale/ext-lang-ja.js +318 -0
  468. data/public/ext-3.0.0/src/locale/ext-lang-ko.js +267 -0
  469. data/public/ext-3.0.0/src/locale/ext-lang-lt.js +333 -0
  470. data/public/ext-3.0.0/src/locale/ext-lang-lv.js +176 -0
  471. data/public/ext-3.0.0/src/locale/ext-lang-mk.js +176 -0
  472. data/public/ext-3.0.0/src/locale/ext-lang-nl.js +323 -0
  473. data/public/ext-3.0.0/src/locale/ext-lang-no_NB.js +294 -0
  474. data/public/ext-3.0.0/src/locale/ext-lang-no_NN.js +294 -0
  475. data/public/ext-3.0.0/src/locale/ext-lang-pl.js +304 -0
  476. data/public/ext-3.0.0/src/locale/ext-lang-pt.js +260 -0
  477. data/public/ext-3.0.0/src/locale/ext-lang-pt_BR.js +302 -0
  478. data/public/ext-3.0.0/src/locale/ext-lang-pt_PT.js +298 -0
  479. data/public/ext-3.0.0/src/locale/ext-lang-ro.js +295 -0
  480. data/public/ext-3.0.0/src/locale/ext-lang-ru.js +319 -0
  481. data/public/ext-3.0.0/src/locale/ext-lang-sk.js +182 -0
  482. data/public/ext-3.0.0/src/locale/ext-lang-sl.js +176 -0
  483. data/public/ext-3.0.0/src/locale/ext-lang-sr.js +179 -0
  484. data/public/ext-3.0.0/src/locale/ext-lang-sr_RS.js +178 -0
  485. data/public/ext-3.0.0/src/locale/ext-lang-sv_SE.js +178 -0
  486. data/public/ext-3.0.0/src/locale/ext-lang-th.js +294 -0
  487. data/public/ext-3.0.0/src/locale/ext-lang-tr.js +306 -0
  488. data/public/ext-3.0.0/src/locale/ext-lang-ukr.js +258 -0
  489. data/public/ext-3.0.0/src/locale/ext-lang-vn.js +181 -0
  490. data/public/ext-3.0.0/src/locale/ext-lang-zh_CN.js +174 -0
  491. data/public/ext-3.0.0/src/locale/ext-lang-zh_TW.js +178 -0
  492. data/public/ext-3.0.0/src/state/CookieProvider.js +91 -0
  493. data/public/ext-3.0.0/src/state/Provider.js +127 -0
  494. data/public/ext-3.0.0/src/state/StateManager.js +69 -0
  495. data/public/ext-3.0.0/src/util/CSS.js +161 -0
  496. data/public/ext-3.0.0/src/util/ClickRepeater.js +200 -0
  497. data/public/ext-3.0.0/src/util/Cookies.js +96 -0
  498. data/public/ext-3.0.0/src/util/Date.js +1317 -0
  499. data/public/ext-3.0.0/src/util/Format.js +356 -0
  500. data/public/ext-3.0.0/src/util/History.js +203 -0
  501. data/public/ext-3.0.0/src/util/KeyMap.js +242 -0
  502. data/public/ext-3.0.0/src/util/KeyNav.js +161 -0
  503. data/public/ext-3.0.0/src/util/MixedCollection.js +576 -0
  504. data/public/ext-3.0.0/src/util/Observable-more.js +178 -0
  505. data/public/ext-3.0.0/src/util/TextMetrics.js +131 -0
  506. data/public/ext-3.0.0/src/util/UpdateManager.js +536 -0
  507. data/public/ext-3.0.0/src/util/XTemplate.js +379 -0
  508. data/public/ext-3.0.0/src/util/core/DelayedTask.js +68 -0
  509. data/public/ext-3.0.0/src/util/core/JSON.js +174 -0
  510. data/public/ext-3.0.0/src/util/core/Observable.js +483 -0
  511. data/public/ext-3.0.0/src/util/core/TaskMgr.js +174 -0
  512. data/public/ext-3.0.0/src/widgets/Action.js +252 -0
  513. data/public/ext-3.0.0/src/widgets/BoxComponent.js +519 -0
  514. data/public/ext-3.0.0/src/widgets/Button.js +762 -0
  515. data/public/ext-3.0.0/src/widgets/ButtonGroup.js +103 -0
  516. data/public/ext-3.0.0/src/widgets/ColorPalette.js +148 -0
  517. data/public/ext-3.0.0/src/widgets/Component.js +1540 -0
  518. data/public/ext-3.0.0/src/widgets/ComponentMgr.js +159 -0
  519. data/public/ext-3.0.0/src/widgets/Container.js +894 -0
  520. data/public/ext-3.0.0/src/widgets/CycleButton.js +188 -0
  521. data/public/ext-3.0.0/src/widgets/DataView.js +749 -0
  522. data/public/ext-3.0.0/src/widgets/DatePicker.js +771 -0
  523. data/public/ext-3.0.0/src/widgets/Editor.js +385 -0
  524. data/public/ext-3.0.0/src/widgets/Layer.js +466 -0
  525. data/public/ext-3.0.0/src/widgets/LoadMask.js +123 -0
  526. data/public/ext-3.0.0/src/widgets/MessageBox.js +626 -0
  527. data/public/ext-3.0.0/src/widgets/PagingToolbar.js +502 -0
  528. data/public/ext-3.0.0/src/widgets/Panel.js +1772 -0
  529. data/public/ext-3.0.0/src/widgets/PanelDD.js +154 -0
  530. data/public/ext-3.0.0/src/widgets/ProgressBar.js +289 -0
  531. data/public/ext-3.0.0/src/widgets/Resizable.js +760 -0
  532. data/public/ext-3.0.0/src/widgets/Shadow.js +192 -0
  533. data/public/ext-3.0.0/src/widgets/Slider.js +426 -0
  534. data/public/ext-3.0.0/src/widgets/SplitBar.js +436 -0
  535. data/public/ext-3.0.0/src/widgets/SplitButton.js +124 -0
  536. data/public/ext-3.0.0/src/widgets/TabPanel.js +1100 -0
  537. data/public/ext-3.0.0/src/widgets/Toolbar.js +781 -0
  538. data/public/ext-3.0.0/src/widgets/Viewport.js +124 -0
  539. data/public/ext-3.0.0/src/widgets/Window.js +941 -0
  540. data/public/ext-3.0.0/src/widgets/WindowManager.js +187 -0
  541. data/public/ext-3.0.0/src/widgets/chart/Chart.js +721 -0
  542. data/public/ext-3.0.0/src/widgets/chart/EventProxy.js +20 -0
  543. data/public/ext-3.0.0/src/widgets/chart/FlashComponent.js +117 -0
  544. data/public/ext-3.0.0/src/widgets/chart/swfobject.js +783 -0
  545. data/public/ext-3.0.0/src/widgets/form/Action.js +626 -0
  546. data/public/ext-3.0.0/src/widgets/form/BasicForm.js +735 -0
  547. data/public/ext-3.0.0/src/widgets/form/Checkbox.js +177 -0
  548. data/public/ext-3.0.0/src/widgets/form/CheckboxGroup.js +419 -0
  549. data/public/ext-3.0.0/src/widgets/form/Combo.js +1232 -0
  550. data/public/ext-3.0.0/src/widgets/form/DateField.js +389 -0
  551. data/public/ext-3.0.0/src/widgets/form/DisplayField.js +98 -0
  552. data/public/ext-3.0.0/src/widgets/form/Field.js +640 -0
  553. data/public/ext-3.0.0/src/widgets/form/FieldSet.js +305 -0
  554. data/public/ext-3.0.0/src/widgets/form/Form.js +335 -0
  555. data/public/ext-3.0.0/src/widgets/form/Hidden.js +39 -0
  556. data/public/ext-3.0.0/src/widgets/form/HtmlEditor.js +1179 -0
  557. data/public/ext-3.0.0/src/widgets/form/Label.js +64 -0
  558. data/public/ext-3.0.0/src/widgets/form/NumberField.js +139 -0
  559. data/public/ext-3.0.0/src/widgets/form/Radio.js +81 -0
  560. data/public/ext-3.0.0/src/widgets/form/RadioGroup.js +116 -0
  561. data/public/ext-3.0.0/src/widgets/form/TextArea.js +117 -0
  562. data/public/ext-3.0.0/src/widgets/form/TextField.js +491 -0
  563. data/public/ext-3.0.0/src/widgets/form/TimeField.js +146 -0
  564. data/public/ext-3.0.0/src/widgets/form/TriggerField.js +328 -0
  565. data/public/ext-3.0.0/src/widgets/form/VTypes.js +135 -0
  566. data/public/ext-3.0.0/src/widgets/grid/AbstractSelectionModel.js +57 -0
  567. data/public/ext-3.0.0/src/widgets/grid/CellSelectionModel.js +262 -0
  568. data/public/ext-3.0.0/src/widgets/grid/CheckboxSelectionModel.js +103 -0
  569. data/public/ext-3.0.0/src/widgets/grid/Column.js +406 -0
  570. data/public/ext-3.0.0/src/widgets/grid/ColumnDD.js +199 -0
  571. data/public/ext-3.0.0/src/widgets/grid/ColumnModel.js +592 -0
  572. data/public/ext-3.0.0/src/widgets/grid/ColumnSplitDD.js +62 -0
  573. data/public/ext-3.0.0/src/widgets/grid/EditorGrid.js +291 -0
  574. data/public/ext-3.0.0/src/widgets/grid/GridDD.js +95 -0
  575. data/public/ext-3.0.0/src/widgets/grid/GridEditor.js +21 -0
  576. data/public/ext-3.0.0/src/widgets/grid/GridPanel.js +952 -0
  577. data/public/ext-3.0.0/src/widgets/grid/GridView.js +1776 -0
  578. data/public/ext-3.0.0/src/widgets/grid/GroupingView.js +517 -0
  579. data/public/ext-3.0.0/src/widgets/grid/PropertyGrid.js +370 -0
  580. data/public/ext-3.0.0/src/widgets/grid/RowNumberer.js +61 -0
  581. data/public/ext-3.0.0/src/widgets/grid/RowSelectionModel.js +530 -0
  582. data/public/ext-3.0.0/src/widgets/layout/AbsoluteLayout.js +82 -0
  583. data/public/ext-3.0.0/src/widgets/layout/AccordionLayout.js +177 -0
  584. data/public/ext-3.0.0/src/widgets/layout/AnchorLayout.js +200 -0
  585. data/public/ext-3.0.0/src/widgets/layout/BorderLayout.js +1108 -0
  586. data/public/ext-3.0.0/src/widgets/layout/BoxLayout.js +417 -0
  587. data/public/ext-3.0.0/src/widgets/layout/CardLayout.js +127 -0
  588. data/public/ext-3.0.0/src/widgets/layout/ColumnLayout.js +130 -0
  589. data/public/ext-3.0.0/src/widgets/layout/ContainerLayout.js +215 -0
  590. data/public/ext-3.0.0/src/widgets/layout/FitLayout.js +48 -0
  591. data/public/ext-3.0.0/src/widgets/layout/FormLayout.js +266 -0
  592. data/public/ext-3.0.0/src/widgets/layout/TableLayout.js +194 -0
  593. data/public/ext-3.0.0/src/widgets/list/ColumnResizer.js +123 -0
  594. data/public/ext-3.0.0/src/widgets/list/ListView.js +357 -0
  595. data/public/ext-3.0.0/src/widgets/list/Sorter.js +70 -0
  596. data/public/ext-3.0.0/src/widgets/menu/BaseItem.js +160 -0
  597. data/public/ext-3.0.0/src/widgets/menu/CheckItem.js +114 -0
  598. data/public/ext-3.0.0/src/widgets/menu/ColorMenu.js +72 -0
  599. data/public/ext-3.0.0/src/widgets/menu/DateMenu.js +90 -0
  600. data/public/ext-3.0.0/src/widgets/menu/Item.js +211 -0
  601. data/public/ext-3.0.0/src/widgets/menu/Menu.js +733 -0
  602. data/public/ext-3.0.0/src/widgets/menu/MenuMgr.js +211 -0
  603. data/public/ext-3.0.0/src/widgets/menu/Separator.js +46 -0
  604. data/public/ext-3.0.0/src/widgets/menu/TextItem.js +46 -0
  605. data/public/ext-3.0.0/src/widgets/tips/QuickTip.js +207 -0
  606. data/public/ext-3.0.0/src/widgets/tips/QuickTips.js +159 -0
  607. data/public/ext-3.0.0/src/widgets/tips/Tip.js +157 -0
  608. data/public/ext-3.0.0/src/widgets/tips/ToolTip.js +492 -0
  609. data/public/ext-3.0.0/src/widgets/tree/AsyncTreeNode.js +114 -0
  610. data/public/ext-3.0.0/src/widgets/tree/TreeDragZone.js +82 -0
  611. data/public/ext-3.0.0/src/widgets/tree/TreeDropZone.js +321 -0
  612. data/public/ext-3.0.0/src/widgets/tree/TreeEditor.js +160 -0
  613. data/public/ext-3.0.0/src/widgets/tree/TreeEventModel.js +169 -0
  614. data/public/ext-3.0.0/src/widgets/tree/TreeFilter.js +114 -0
  615. data/public/ext-3.0.0/src/widgets/tree/TreeLoader.js +342 -0
  616. data/public/ext-3.0.0/src/widgets/tree/TreeNode.js +546 -0
  617. data/public/ext-3.0.0/src/widgets/tree/TreeNodeUI.js +633 -0
  618. data/public/ext-3.0.0/src/widgets/tree/TreePanel.js +918 -0
  619. data/public/ext-3.0.0/src/widgets/tree/TreeSelectionModel.js +315 -0
  620. data/public/ext-3.0.0/src/widgets/tree/TreeSorter.js +106 -0
  621. data/public/js/ext-portal.js +235 -0
  622. data/public/js/global.js +7 -0
  623. data/public/js/outerframe.js +47 -0
  624. data/public/js/portal.js +713 -0
  625. data/public/js/test_chart.js +152 -0
  626. data/test/config.rb +62 -0
  627. data/test/config/hosts.yaml +5 -0
  628. data/test/config/log.yaml +1 -0
  629. data/test/config/memcache.yaml +5 -0
  630. data/test/exception.rb +39 -0
  631. data/test/method_missing.rb +14 -0
  632. data/test/module.rb +39 -0
  633. data/test/remote_lmp.rb +126 -0
  634. data/test/sinatra.rb +29 -0
  635. data/test/sinatra_base.rb +16 -0
  636. metadata +690 -0
@@ -0,0 +1,7 @@
1
+ /*
2
+ * Ext JS Library 3.0.0
3
+ * Copyright(c) 2006-2009 Ext JS, LLC
4
+ * licensing@extjs.com
5
+ * http://www.extjs.com/license
6
+ */
7
+ Ext.grid.CellSelectionModel=function(a){Ext.apply(this,a);this.selection=null;this.addEvents("beforecellselect","cellselect","selectionchange");Ext.grid.CellSelectionModel.superclass.constructor.call(this)};Ext.extend(Ext.grid.CellSelectionModel,Ext.grid.AbstractSelectionModel,{initEvents:function(){this.grid.on("cellmousedown",this.handleMouseDown,this);this.grid.getGridEl().on(Ext.EventManager.useKeydown?"keydown":"keypress",this.handleKeyDown,this);var a=this.grid.view;a.on("refresh",this.onViewChange,this);a.on("rowupdated",this.onRowUpdated,this);a.on("beforerowremoved",this.clearSelections,this);a.on("beforerowsinserted",this.clearSelections,this);if(this.grid.isEditor){this.grid.on("beforeedit",this.beforeEdit,this)}},beforeEdit:function(a){this.select(a.row,a.column,false,true,a.record)},onRowUpdated:function(a,b,c){if(this.selection&&this.selection.record==c){a.onCellSelect(b,this.selection.cell[1])}},onViewChange:function(){this.clearSelections(true)},getSelectedCell:function(){return this.selection?this.selection.cell:null},clearSelections:function(b){var a=this.selection;if(a){if(b!==true){this.grid.view.onCellDeselect(a.cell[0],a.cell[1])}this.selection=null;this.fireEvent("selectionchange",this,null)}},hasSelection:function(){return this.selection?true:false},handleMouseDown:function(b,d,a,c){if(c.button!==0||this.isLocked()){return}this.select(d,a)},select:function(f,c,b,e,d){if(this.fireEvent("beforecellselect",this,f,c)!==false){this.clearSelections();d=d||this.grid.store.getAt(f);this.selection={record:d,cell:[f,c]};if(!b){var a=this.grid.getView();a.onCellSelect(f,c);if(e!==true){a.focusCell(f,c)}}this.fireEvent("cellselect",this,f,c);this.fireEvent("selectionchange",this,this.selection)}},isSelectable:function(c,b,a){return !a.isHidden(b)},handleKeyDown:function(i){if(!i.isNavKeyPress()){return}var h=this.grid,n=this.selection;if(!n){i.stopEvent();var m=h.walkCells(0,0,1,this.isSelectable,this);if(m){this.select(m[0],m[1])}return}var b=this;var l=function(g,c,e){return h.walkCells(g,c,e,b.isSelectable,b)};var d=i.getKey(),a=n.cell[0],j=n.cell[1];var f;switch(d){case i.TAB:if(i.shiftKey){f=l(a,j-1,-1)}else{f=l(a,j+1,1)}break;case i.DOWN:f=l(a+1,j,1);break;case i.UP:f=l(a-1,j,-1);break;case i.RIGHT:f=l(a,j+1,1);break;case i.LEFT:f=l(a,j-1,-1);break;case i.ENTER:if(h.isEditor&&!h.editing){h.startEditing(a,j);i.stopEvent();return}break}if(f){this.select(f[0],f[1]);i.stopEvent()}},acceptsNav:function(c,b,a){return !a.isHidden(b)&&a.isCellEditable(b,c)},onEditorKey:function(f,d){var b=d.getKey(),h,c=this.grid,a=c.activeEditor;if(b==d.TAB){if(d.shiftKey){h=c.walkCells(a.row,a.col-1,-1,this.acceptsNav,this)}else{h=c.walkCells(a.row,a.col+1,1,this.acceptsNav,this)}d.stopEvent()}else{if(b==d.ENTER){a.completeEdit();d.stopEvent()}else{if(b==d.ESC){d.stopEvent();a.cancelEdit()}}}if(h){c.startEditing(h[0],h[1])}}});Ext.grid.EditorGridPanel=Ext.extend(Ext.grid.GridPanel,{clicksToEdit:2,forceValidation:false,isEditor:true,detectEdit:false,autoEncode:false,trackMouseOver:false,initComponent:function(){Ext.grid.EditorGridPanel.superclass.initComponent.call(this);if(!this.selModel){this.selModel=new Ext.grid.CellSelectionModel()}this.activeEditor=null;this.addEvents("beforeedit","afteredit","validateedit")},initEvents:function(){Ext.grid.EditorGridPanel.superclass.initEvents.call(this);this.on("bodyscroll",this.stopEditing,this,[true]);this.on("columnresize",this.stopEditing,this,[true]);if(this.clicksToEdit==1){this.on("cellclick",this.onCellDblClick,this)}else{if(this.clicksToEdit=="auto"&&this.view.mainBody){this.view.mainBody.on("mousedown",this.onAutoEditClick,this)}this.on("celldblclick",this.onCellDblClick,this)}},onCellDblClick:function(b,c,a){this.startEditing(c,a)},onAutoEditClick:function(c,b){if(c.button!==0){return}var f=this.view.findRowIndex(b);var a=this.view.findCellIndex(b);if(f!==false&&a!==false){this.stopEditing();if(this.selModel.getSelectedCell){var d=this.selModel.getSelectedCell();if(d&&d[0]===f&&d[1]===a){this.startEditing(f,a)}}else{if(this.selModel.isSelected(f)){this.startEditing(f,a)}}}},onEditComplete:function(b,d,a){this.editing=false;this.activeEditor=null;b.un("specialkey",this.selModel.onEditorKey,this.selModel);var c=b.record;var g=this.colModel.getDataIndex(b.col);d=this.postEditValue(d,a,c,g);if(this.forceValidation===true||String(d)!==String(a)){var f={grid:this,record:c,field:g,originalValue:a,value:d,row:b.row,column:b.col,cancel:false};if(this.fireEvent("validateedit",f)!==false&&!f.cancel&&String(d)!==String(a)){c.set(g,f.value);delete f.cancel;this.fireEvent("afteredit",f)}}this.view.focusCell(b.row,b.col)},startEditing:function(g,b){this.stopEditing();if(this.colModel.isCellEditable(b,g)){this.view.ensureVisible(g,b,true);var c=this.store.getAt(g);var f=this.colModel.getDataIndex(b);var d={grid:this,record:c,field:f,value:c.data[f],row:g,column:b,cancel:false};if(this.fireEvent("beforeedit",d)!==false&&!d.cancel){this.editing=true;var a=this.colModel.getCellEditor(b,g);if(!a){return}if(!a.rendered){a.render(this.view.getEditorParent(a))}(function(){a.row=g;a.col=b;a.record=c;a.on("complete",this.onEditComplete,this,{single:true});a.on("specialkey",this.selModel.onEditorKey,this.selModel);this.activeEditor=a;var e=this.preEditValue(c,f);a.startEdit(this.view.getCell(g,b).firstChild,e===undefined?"":e)}).defer(50,this)}}},preEditValue:function(a,c){var b=a.data[c];return this.autoEncode&&typeof b=="string"?Ext.util.Format.htmlDecode(b):b},postEditValue:function(c,a,b,d){return this.autoEncode&&typeof c=="string"?Ext.util.Format.htmlEncode(c):c},stopEditing:function(a){if(this.activeEditor){this.activeEditor[a===true?"cancelEdit":"completeEdit"]()}this.activeEditor=null}});Ext.reg("editorgrid",Ext.grid.EditorGridPanel);Ext.grid.GridEditor=function(b,a){Ext.grid.GridEditor.superclass.constructor.call(this,b,a);b.monitorTab=false};Ext.extend(Ext.grid.GridEditor,Ext.Editor,{alignment:"tl-tl",autoSize:"width",hideEl:false,cls:"x-small-editor x-grid-editor",shim:false,shadow:false});
@@ -0,0 +1,4765 @@
1
+ /*!
2
+ * Ext JS Library 3.0.0
3
+ * Copyright(c) 2006-2009 Ext JS, LLC
4
+ * licensing@extjs.com
5
+ * http://www.extjs.com/license
6
+ */
7
+ /**
8
+ * @class Ext.grid.GridPanel
9
+ * @extends Ext.Panel
10
+ * <p>This class represents the primary interface of a component based grid control to represent data
11
+ * in a tabular format of rows and columns. The GridPanel is composed of the following:</p>
12
+ * <div class="mdetail-params"><ul>
13
+ * <li><b>{@link Ext.data.Store Store}</b> : The Model holding the data records (rows)
14
+ * <div class="sub-desc"></div></li>
15
+ * <li><b>{@link Ext.grid.ColumnModel Column model}</b> : Column makeup
16
+ * <div class="sub-desc"></div></li>
17
+ * <li><b>{@link Ext.grid.GridView View}</b> : Encapsulates the user interface
18
+ * <div class="sub-desc"></div></li>
19
+ * <li><b>{@link Ext.grid.AbstractSelectionModel selection model}</b> : Selection behavior
20
+ * <div class="sub-desc"></div></li>
21
+ * </ul></div>
22
+ * <p>Example usage:</p>
23
+ * <pre><code>
24
+ var grid = new Ext.grid.GridPanel({
25
+ {@link #store}: new (@link Ext.data.Store}({
26
+ {@link Ext.data.Store#autoDestroy autoDestroy}: true,
27
+ {@link Ext.data.Store#reader reader}: reader,
28
+ {@link Ext.data.Store#data data}: xg.dummyData
29
+ }),
30
+ {@link #columns}: [
31
+ {id: 'company', header: 'Company', width: 200, sortable: true, dataIndex: 'company'},
32
+ {header: 'Price', width: 120, sortable: true, renderer: Ext.util.Format.usMoney, dataIndex: 'price'},
33
+ {header: 'Change', width: 120, sortable: true, dataIndex: 'change'},
34
+ {header: '% Change', width: 120, sortable: true, dataIndex: 'pctChange'},
35
+ // instead of specifying renderer: Ext.util.Format.dateRenderer('m/d/Y') use xtype
36
+ {header: 'Last Updated', width: 135, sortable: true, dataIndex: 'lastChange', xtype: 'datecolumn', format: 'M d, Y'}
37
+ ],
38
+ {@link #viewConfig}: {
39
+ {@link Ext.grid.GridView#forceFit forceFit}: true,
40
+
41
+ // Return CSS class to apply to rows depending upon data values
42
+ {@link Ext.grid.GridView#getRowClass getRowClass}: function(record, index) {
43
+ var c = record.{@link Ext.data.Record#get get}('change');
44
+ if (c < 0) {
45
+ return 'price-fall';
46
+ } else if (c > 0) {
47
+ return 'price-rise';
48
+ }
49
+ }
50
+ },
51
+ {@link #sm}: new Ext.grid.RowSelectionModel({singleSelect:true}),
52
+ width: 600,
53
+ height: 300,
54
+ frame: true,
55
+ title: 'Framed with Row Selection and Horizontal Scrolling',
56
+ iconCls: 'icon-grid'
57
+ });
58
+ * </code></pre>
59
+ * <p><b><u>Notes:</u></b></p>
60
+ * <div class="mdetail-params"><ul>
61
+ * <li>Although this class inherits many configuration options from base classes, some of them
62
+ * (such as autoScroll, autoWidth, layout, items, etc) are not used by this class, and will
63
+ * have no effect.</li>
64
+ * <li>A grid <b>requires</b> a width in which to scroll its columns, and a height in which to
65
+ * scroll its rows. These dimensions can either be set explicitly through the
66
+ * <tt>{@link Ext.BoxComponent#height height}</tt> and <tt>{@link Ext.BoxComponent#width width}</tt>
67
+ * configuration options or implicitly set by using the grid as a child item of a
68
+ * {@link Ext.Container Container} which will have a {@link Ext.Container#layout layout manager}
69
+ * provide the sizing of its child items (for example the Container of the Grid may specify
70
+ * <tt>{@link Ext.Container#layout layout}:'fit'</tt>).</li>
71
+ * <li>To access the data in a Grid, it is necessary to use the data model encapsulated
72
+ * by the {@link #store Store}. See the {@link #cellclick} event for more details.</li>
73
+ * </ul></div>
74
+ * @constructor
75
+ * @param {Object} config The config object
76
+ * @xtype grid
77
+ */
78
+ Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
79
+ /**
80
+ * @cfg {String} autoExpandColumn
81
+ * <p>The <tt>{@link Ext.grid.Column#id id}</tt> of a {@link Ext.grid.Column column} in
82
+ * this grid that should expand to fill unused space. This value specified here can not
83
+ * be <tt>0</tt>.</p>
84
+ * <br><p><b>Note</b>: If the Grid's {@link Ext.grid.GridView view} is configured with
85
+ * <tt>{@link Ext.grid.GridView#forceFit forceFit}=true</tt> the <tt>autoExpandColumn</tt>
86
+ * is ignored. See {@link Ext.grid.Column}.<tt>{@link Ext.grid.Column#width width}</tt>
87
+ * for additional details.</p>
88
+ * <p>See <tt>{@link #autoExpandMax}</tt> and <tt>{@link #autoExpandMin}</tt> also.</p>
89
+ */
90
+ autoExpandColumn : false,
91
+ /**
92
+ * @cfg {Number} autoExpandMax The maximum width the <tt>{@link #autoExpandColumn}</tt>
93
+ * can have (if enabled). Defaults to <tt>1000</tt>.
94
+ */
95
+ autoExpandMax : 1000,
96
+ /**
97
+ * @cfg {Number} autoExpandMin The minimum width the <tt>{@link #autoExpandColumn}</tt>
98
+ * can have (if enabled). Defaults to <tt>50</tt>.
99
+ */
100
+ autoExpandMin : 50,
101
+ /**
102
+ * @cfg {Boolean} columnLines <tt>true</tt> to add css for column separation lines.
103
+ * Default is <tt>false</tt>.
104
+ */
105
+ columnLines : false,
106
+ /**
107
+ * @cfg {Object} cm Shorthand for <tt>{@link #colModel}</tt>.
108
+ */
109
+ /**
110
+ * @cfg {Object} colModel The {@link Ext.grid.ColumnModel} to use when rendering the grid (required).
111
+ */
112
+ /**
113
+ * @cfg {Array} columns An array of {@link Ext.grid.Column columns} to auto create a
114
+ * {@link Ext.grid.ColumnModel}. The ColumnModel may be explicitly created via the
115
+ * <tt>{@link #colModel}</tt> configuration property.
116
+ */
117
+ /**
118
+ * @cfg {String} ddGroup The DD group this GridPanel belongs to. Defaults to <tt>'GridDD'</tt> if not specified.
119
+ */
120
+ /**
121
+ * @cfg {String} ddText
122
+ * Configures the text in the drag proxy. Defaults to:
123
+ * <pre><code>
124
+ * ddText : '{0} selected row{1}'
125
+ * </code></pre>
126
+ * <tt>{0}</tt> is replaced with the number of selected rows.
127
+ */
128
+ ddText : '{0} selected row{1}',
129
+ /**
130
+ * @cfg {Boolean} deferRowRender <P>Defaults to <tt>true</tt> to enable deferred row rendering.</p>
131
+ * <p>This allows the GridPanel to be initially rendered empty, with the expensive update of the row
132
+ * structure deferred so that layouts with GridPanels appear more quickly.</p>
133
+ */
134
+ deferRowRender : true,
135
+ /**
136
+ * @cfg {Boolean} disableSelection <p><tt>true</tt> to disable selections in the grid. Defaults to <tt>false</tt>.</p>
137
+ * <p>Ignored if a {@link #selModel SelectionModel} is specified.</p>
138
+ */
139
+ /**
140
+ * @cfg {Boolean} enableColumnResize <tt>false</tt> to turn off column resizing for the whole grid. Defaults to <tt>true</tt>.
141
+ */
142
+ /**
143
+ * @cfg {Boolean} enableColumnHide Defaults to <tt>true</tt> to enable hiding of columns with the header context menu.
144
+ */
145
+ enableColumnHide : true,
146
+ /**
147
+ * @cfg {Boolean} enableColumnMove Defaults to <tt>true</tt> to enable drag and drop reorder of columns. <tt>false</tt>
148
+ * to turn off column reordering via drag drop.
149
+ */
150
+ enableColumnMove : true,
151
+ /**
152
+ * @cfg {Boolean} enableDragDrop <p>Enables dragging of the selected rows of the GridPanel. Defaults to <tt>false</tt>.</p>
153
+ * <p>Setting this to <b><tt>true</tt></b> causes this GridPanel's {@link #getView GridView} to
154
+ * create an instance of {@link Ext.grid.GridDragZone}. <b>Note</b>: this is available only <b>after</b>
155
+ * the Grid has been rendered as the GridView's <tt>{@link Ext.grid.GridView#dragZone dragZone}</tt>
156
+ * property.</p>
157
+ * <p>A cooperating {@link Ext.dd.DropZone DropZone} must be created who's implementations of
158
+ * {@link Ext.dd.DropZone#onNodeEnter onNodeEnter}, {@link Ext.dd.DropZone#onNodeOver onNodeOver},
159
+ * {@link Ext.dd.DropZone#onNodeOut onNodeOut} and {@link Ext.dd.DropZone#onNodeDrop onNodeDrop} are able
160
+ * to process the {@link Ext.grid.GridDragZone#getDragData data} which is provided.</p>
161
+ */
162
+ enableDragDrop : false,
163
+ /**
164
+ * @cfg {Boolean} enableHdMenu Defaults to <tt>true</tt> to enable the drop down button for menu in the headers.
165
+ */
166
+ enableHdMenu : true,
167
+ /**
168
+ * @cfg {Boolean} hideHeaders True to hide the grid's header. Defaults to <code>false</code>.
169
+ */
170
+ /**
171
+ * @cfg {Object} loadMask An {@link Ext.LoadMask} config or true to mask the grid while
172
+ * loading. Defaults to <code>false</code>.
173
+ */
174
+ loadMask : false,
175
+ /**
176
+ * @cfg {Number} maxHeight Sets the maximum height of the grid - ignored if <tt>autoHeight</tt> is not on.
177
+ */
178
+ /**
179
+ * @cfg {Number} minColumnWidth The minimum width a column can be resized to. Defaults to <tt>25</tt>.
180
+ */
181
+ minColumnWidth : 25,
182
+ /**
183
+ * @cfg {Object} sm Shorthand for <tt>{@link #selModel}</tt>.
184
+ */
185
+ /**
186
+ * @cfg {Object} selModel Any subclass of {@link Ext.grid.AbstractSelectionModel} that will provide
187
+ * the selection model for the grid (defaults to {@link Ext.grid.RowSelectionModel} if not specified).
188
+ */
189
+ /**
190
+ * @cfg {Ext.data.Store} store The {@link Ext.data.Store} the grid should use as its data source (required).
191
+ */
192
+ /**
193
+ * @cfg {Boolean} stripeRows <tt>true</tt> to stripe the rows. Default is <tt>false</tt>.
194
+ * <p>This causes the CSS class <tt><b>x-grid3-row-alt</b></tt> to be added to alternate rows of
195
+ * the grid. A default CSS rule is provided which sets a background colour, but you can override this
196
+ * with a rule which either overrides the <b>background-color</b> style using the '!important'
197
+ * modifier, or which uses a CSS selector of higher specificity.</p>
198
+ */
199
+ stripeRows : false,
200
+ /**
201
+ * @cfg {Boolean} trackMouseOver True to highlight rows when the mouse is over. Default is <tt>true</tt>
202
+ * for GridPanel, but <tt>false</tt> for EditorGridPanel.
203
+ */
204
+ trackMouseOver : true,
205
+ /**
206
+ * @cfg {Array} stateEvents
207
+ * An array of events that, when fired, should trigger this component to save its state.
208
+ * Defaults to:<pre><code>
209
+ * stateEvents: ['columnmove', 'columnresize', 'sortchange']
210
+ * </code></pre>
211
+ * <p>These can be any types of events supported by this component, including browser or
212
+ * custom events (e.g., <tt>['click', 'customerchange']</tt>).</p>
213
+ * <p>See {@link Ext.Component#stateful} for an explanation of saving and restoring
214
+ * Component state.</p>
215
+ */
216
+ stateEvents : ['columnmove', 'columnresize', 'sortchange'],
217
+ /**
218
+ * @cfg {Object} view The {@link Ext.grid.GridView} used by the grid. This can be set
219
+ * before a call to {@link Ext.Component#render render()}.
220
+ */
221
+ view : null,
222
+ /**
223
+ * @cfg {Object} viewConfig A config object that will be applied to the grid's UI view. Any of
224
+ * the config options available for {@link Ext.grid.GridView} can be specified here. This option
225
+ * is ignored if <tt>{@link #view}</tt> is specified.
226
+ */
227
+
228
+ // private
229
+ rendered : false,
230
+ // private
231
+ viewReady : false,
232
+
233
+ // private
234
+ initComponent : function(){
235
+ Ext.grid.GridPanel.superclass.initComponent.call(this);
236
+
237
+ if(this.columnLines){
238
+ this.cls = (this.cls || '') + ' x-grid-with-col-lines';
239
+ }
240
+ // override any provided value since it isn't valid
241
+ // and is causing too many bug reports ;)
242
+ this.autoScroll = false;
243
+ this.autoWidth = false;
244
+
245
+ if(Ext.isArray(this.columns)){
246
+ this.colModel = new Ext.grid.ColumnModel(this.columns);
247
+ delete this.columns;
248
+ }
249
+
250
+ // check and correct shorthanded configs
251
+ if(this.ds){
252
+ this.store = this.ds;
253
+ delete this.ds;
254
+ }
255
+ if(this.cm){
256
+ this.colModel = this.cm;
257
+ delete this.cm;
258
+ }
259
+ if(this.sm){
260
+ this.selModel = this.sm;
261
+ delete this.sm;
262
+ }
263
+ this.store = Ext.StoreMgr.lookup(this.store);
264
+
265
+ this.addEvents(
266
+ // raw events
267
+ /**
268
+ * @event click
269
+ * The raw click event for the entire grid.
270
+ * @param {Ext.EventObject} e
271
+ */
272
+ 'click',
273
+ /**
274
+ * @event dblclick
275
+ * The raw dblclick event for the entire grid.
276
+ * @param {Ext.EventObject} e
277
+ */
278
+ 'dblclick',
279
+ /**
280
+ * @event contextmenu
281
+ * The raw contextmenu event for the entire grid.
282
+ * @param {Ext.EventObject} e
283
+ */
284
+ 'contextmenu',
285
+ /**
286
+ * @event mousedown
287
+ * The raw mousedown event for the entire grid.
288
+ * @param {Ext.EventObject} e
289
+ */
290
+ 'mousedown',
291
+ /**
292
+ * @event mouseup
293
+ * The raw mouseup event for the entire grid.
294
+ * @param {Ext.EventObject} e
295
+ */
296
+ 'mouseup',
297
+ /**
298
+ * @event mouseover
299
+ * The raw mouseover event for the entire grid.
300
+ * @param {Ext.EventObject} e
301
+ */
302
+ 'mouseover',
303
+ /**
304
+ * @event mouseout
305
+ * The raw mouseout event for the entire grid.
306
+ * @param {Ext.EventObject} e
307
+ */
308
+ 'mouseout',
309
+ /**
310
+ * @event keypress
311
+ * The raw keypress event for the entire grid.
312
+ * @param {Ext.EventObject} e
313
+ */
314
+ 'keypress',
315
+ /**
316
+ * @event keydown
317
+ * The raw keydown event for the entire grid.
318
+ * @param {Ext.EventObject} e
319
+ */
320
+ 'keydown',
321
+
322
+ // custom events
323
+ /**
324
+ * @event cellmousedown
325
+ * Fires before a cell is clicked
326
+ * @param {Grid} this
327
+ * @param {Number} rowIndex
328
+ * @param {Number} columnIndex
329
+ * @param {Ext.EventObject} e
330
+ */
331
+ 'cellmousedown',
332
+ /**
333
+ * @event rowmousedown
334
+ * Fires before a row is clicked
335
+ * @param {Grid} this
336
+ * @param {Number} rowIndex
337
+ * @param {Ext.EventObject} e
338
+ */
339
+ 'rowmousedown',
340
+ /**
341
+ * @event headermousedown
342
+ * Fires before a header is clicked
343
+ * @param {Grid} this
344
+ * @param {Number} columnIndex
345
+ * @param {Ext.EventObject} e
346
+ */
347
+ 'headermousedown',
348
+
349
+ /**
350
+ * @event cellclick
351
+ * Fires when a cell is clicked.
352
+ * The data for the cell is drawn from the {@link Ext.data.Record Record}
353
+ * for this row. To access the data in the listener function use the
354
+ * following technique:
355
+ * <pre><code>
356
+ function(grid, rowIndex, columnIndex, e) {
357
+ var record = grid.getStore().getAt(rowIndex); // Get the Record
358
+ var fieldName = grid.getColumnModel().getDataIndex(columnIndex); // Get field name
359
+ var data = record.get(fieldName);
360
+ }
361
+ </code></pre>
362
+ * @param {Grid} this
363
+ * @param {Number} rowIndex
364
+ * @param {Number} columnIndex
365
+ * @param {Ext.EventObject} e
366
+ */
367
+ 'cellclick',
368
+ /**
369
+ * @event celldblclick
370
+ * Fires when a cell is double clicked
371
+ * @param {Grid} this
372
+ * @param {Number} rowIndex
373
+ * @param {Number} columnIndex
374
+ * @param {Ext.EventObject} e
375
+ */
376
+ 'celldblclick',
377
+ /**
378
+ * @event rowclick
379
+ * Fires when a row is clicked
380
+ * @param {Grid} this
381
+ * @param {Number} rowIndex
382
+ * @param {Ext.EventObject} e
383
+ */
384
+ 'rowclick',
385
+ /**
386
+ * @event rowdblclick
387
+ * Fires when a row is double clicked
388
+ * @param {Grid} this
389
+ * @param {Number} rowIndex
390
+ * @param {Ext.EventObject} e
391
+ */
392
+ 'rowdblclick',
393
+ /**
394
+ * @event headerclick
395
+ * Fires when a header is clicked
396
+ * @param {Grid} this
397
+ * @param {Number} columnIndex
398
+ * @param {Ext.EventObject} e
399
+ */
400
+ 'headerclick',
401
+ /**
402
+ * @event headerdblclick
403
+ * Fires when a header cell is double clicked
404
+ * @param {Grid} this
405
+ * @param {Number} columnIndex
406
+ * @param {Ext.EventObject} e
407
+ */
408
+ 'headerdblclick',
409
+ /**
410
+ * @event rowcontextmenu
411
+ * Fires when a row is right clicked
412
+ * @param {Grid} this
413
+ * @param {Number} rowIndex
414
+ * @param {Ext.EventObject} e
415
+ */
416
+ 'rowcontextmenu',
417
+ /**
418
+ * @event cellcontextmenu
419
+ * Fires when a cell is right clicked
420
+ * @param {Grid} this
421
+ * @param {Number} rowIndex
422
+ * @param {Number} cellIndex
423
+ * @param {Ext.EventObject} e
424
+ */
425
+ 'cellcontextmenu',
426
+ /**
427
+ * @event headercontextmenu
428
+ * Fires when a header is right clicked
429
+ * @param {Grid} this
430
+ * @param {Number} columnIndex
431
+ * @param {Ext.EventObject} e
432
+ */
433
+ 'headercontextmenu',
434
+ /**
435
+ * @event bodyscroll
436
+ * Fires when the body element is scrolled
437
+ * @param {Number} scrollLeft
438
+ * @param {Number} scrollTop
439
+ */
440
+ 'bodyscroll',
441
+ /**
442
+ * @event columnresize
443
+ * Fires when the user resizes a column
444
+ * @param {Number} columnIndex
445
+ * @param {Number} newSize
446
+ */
447
+ 'columnresize',
448
+ /**
449
+ * @event columnmove
450
+ * Fires when the user moves a column
451
+ * @param {Number} oldIndex
452
+ * @param {Number} newIndex
453
+ */
454
+ 'columnmove',
455
+ /**
456
+ * @event sortchange
457
+ * Fires when the grid's store sort changes
458
+ * @param {Grid} this
459
+ * @param {Object} sortInfo An object with the keys field and direction
460
+ */
461
+ 'sortchange',
462
+ /**
463
+ * @event reconfigure
464
+ * Fires when the grid is reconfigured with a new store and/or column model.
465
+ * @param {Grid} this
466
+ * @param {Ext.data.Store} store The new store
467
+ * @param {Ext.grid.ColumnModel} colModel The new column model
468
+ */
469
+ 'reconfigure'
470
+ );
471
+ },
472
+
473
+ // private
474
+ onRender : function(ct, position){
475
+ Ext.grid.GridPanel.superclass.onRender.apply(this, arguments);
476
+
477
+ var c = this.body;
478
+
479
+ this.el.addClass('x-grid-panel');
480
+
481
+ var view = this.getView();
482
+ view.init(this);
483
+
484
+ this.mon(c, {
485
+ mousedown: this.onMouseDown,
486
+ click: this.onClick,
487
+ dblclick: this.onDblClick,
488
+ contextmenu: this.onContextMenu,
489
+ keydown: this.onKeyDown,
490
+ scope: this
491
+ });
492
+
493
+ this.relayEvents(c, ['mousedown','mouseup','mouseover','mouseout','keypress']);
494
+
495
+ this.getSelectionModel().init(this);
496
+ this.view.render();
497
+ },
498
+
499
+ // private
500
+ initEvents : function(){
501
+ Ext.grid.GridPanel.superclass.initEvents.call(this);
502
+
503
+ if(this.loadMask){
504
+ this.loadMask = new Ext.LoadMask(this.bwrap,
505
+ Ext.apply({store:this.store}, this.loadMask));
506
+ }
507
+ },
508
+
509
+ initStateEvents : function(){
510
+ Ext.grid.GridPanel.superclass.initStateEvents.call(this);
511
+ this.mon(this.colModel, 'hiddenchange', this.saveState, this, {delay: 100});
512
+ },
513
+
514
+ applyState : function(state){
515
+ var cm = this.colModel;
516
+ var cs = state.columns;
517
+ if(cs){
518
+ for(var i = 0, len = cs.length; i < len; i++){
519
+ var s = cs[i];
520
+ var c = cm.getColumnById(s.id);
521
+ if(c){
522
+ c.hidden = s.hidden;
523
+ c.width = s.width;
524
+ var oldIndex = cm.getIndexById(s.id);
525
+ if(oldIndex != i){
526
+ cm.moveColumn(oldIndex, i);
527
+ }
528
+ }
529
+ }
530
+ }
531
+ if(state.sort && this.store){
532
+ this.store[this.store.remoteSort ? 'setDefaultSort' : 'sort'](state.sort.field, state.sort.direction);
533
+ }
534
+ delete state.columns;
535
+ delete state.sort;
536
+ Ext.grid.GridPanel.superclass.applyState.call(this, state);
537
+ },
538
+
539
+ getState : function(){
540
+ var o = {columns: []};
541
+ for(var i = 0, c; (c = this.colModel.config[i]); i++){
542
+ o.columns[i] = {
543
+ id: c.id,
544
+ width: c.width
545
+ };
546
+ if(c.hidden){
547
+ o.columns[i].hidden = true;
548
+ }
549
+ }
550
+ if(this.store){
551
+ var ss = this.store.getSortState();
552
+ if(ss){
553
+ o.sort = ss;
554
+ }
555
+ }
556
+ return o;
557
+ },
558
+
559
+ // private
560
+ afterRender : function(){
561
+ Ext.grid.GridPanel.superclass.afterRender.call(this);
562
+ this.view.layout();
563
+ if(this.deferRowRender){
564
+ this.view.afterRender.defer(10, this.view);
565
+ }else{
566
+ this.view.afterRender();
567
+ }
568
+ this.viewReady = true;
569
+ },
570
+
571
+ /**
572
+ * <p>Reconfigures the grid to use a different Store and Column Model
573
+ * and fires the 'reconfigure' event. The View will be bound to the new
574
+ * objects and refreshed.</p>
575
+ * <p>Be aware that upon reconfiguring a GridPanel, certain existing settings <i>may</i> become
576
+ * invalidated. For example the configured {@link #autoExpandColumn} may no longer exist in the
577
+ * new ColumnModel. Also, an existing {@link Ext.PagingToolbar PagingToolbar} will still be bound
578
+ * to the old Store, and will need rebinding. Any {@link #plugins} might also need reconfiguring
579
+ * with the new data.</p>
580
+ * @param {Ext.data.Store} store The new {@link Ext.data.Store} object
581
+ * @param {Ext.grid.ColumnModel} colModel The new {@link Ext.grid.ColumnModel} object
582
+ */
583
+ reconfigure : function(store, colModel){
584
+ if(this.loadMask){
585
+ this.loadMask.destroy();
586
+ this.loadMask = new Ext.LoadMask(this.bwrap,
587
+ Ext.apply({}, {store:store}, this.initialConfig.loadMask));
588
+ }
589
+ this.view.initData(store, colModel);
590
+ this.store = store;
591
+ this.colModel = colModel;
592
+ if(this.rendered){
593
+ this.view.refresh(true);
594
+ }
595
+ this.fireEvent('reconfigure', this, store, colModel);
596
+ },
597
+
598
+ // private
599
+ onKeyDown : function(e){
600
+ this.fireEvent('keydown', e);
601
+ },
602
+
603
+ // private
604
+ onDestroy : function(){
605
+ if(this.rendered){
606
+ var c = this.body;
607
+ c.removeAllListeners();
608
+ c.update('');
609
+ Ext.destroy(this.view, this.loadMask);
610
+ }else if(this.store && this.store.autoDestroy){
611
+ this.store.destroy();
612
+ }
613
+ Ext.destroy(this.colModel, this.selModel);
614
+ this.store = this.selModel = this.colModel = this.view = this.loadMask = null;
615
+ Ext.grid.GridPanel.superclass.onDestroy.call(this);
616
+ },
617
+
618
+ // private
619
+ processEvent : function(name, e){
620
+ this.fireEvent(name, e);
621
+ var t = e.getTarget();
622
+ var v = this.view;
623
+ var header = v.findHeaderIndex(t);
624
+ if(header !== false){
625
+ this.fireEvent('header' + name, this, header, e);
626
+ }else{
627
+ var row = v.findRowIndex(t);
628
+ var cell = v.findCellIndex(t);
629
+ if(row !== false){
630
+ this.fireEvent('row' + name, this, row, e);
631
+ if(cell !== false){
632
+ this.fireEvent('cell' + name, this, row, cell, e);
633
+ }
634
+ }
635
+ }
636
+ },
637
+
638
+ // private
639
+ onClick : function(e){
640
+ this.processEvent('click', e);
641
+ },
642
+
643
+ // private
644
+ onMouseDown : function(e){
645
+ this.processEvent('mousedown', e);
646
+ },
647
+
648
+ // private
649
+ onContextMenu : function(e, t){
650
+ this.processEvent('contextmenu', e);
651
+ },
652
+
653
+ // private
654
+ onDblClick : function(e){
655
+ this.processEvent('dblclick', e);
656
+ },
657
+
658
+ // private
659
+ walkCells : function(row, col, step, fn, scope){
660
+ var cm = this.colModel, clen = cm.getColumnCount();
661
+ var ds = this.store, rlen = ds.getCount(), first = true;
662
+ if(step < 0){
663
+ if(col < 0){
664
+ row--;
665
+ first = false;
666
+ }
667
+ while(row >= 0){
668
+ if(!first){
669
+ col = clen-1;
670
+ }
671
+ first = false;
672
+ while(col >= 0){
673
+ if(fn.call(scope || this, row, col, cm) === true){
674
+ return [row, col];
675
+ }
676
+ col--;
677
+ }
678
+ row--;
679
+ }
680
+ } else {
681
+ if(col >= clen){
682
+ row++;
683
+ first = false;
684
+ }
685
+ while(row < rlen){
686
+ if(!first){
687
+ col = 0;
688
+ }
689
+ first = false;
690
+ while(col < clen){
691
+ if(fn.call(scope || this, row, col, cm) === true){
692
+ return [row, col];
693
+ }
694
+ col++;
695
+ }
696
+ row++;
697
+ }
698
+ }
699
+ return null;
700
+ },
701
+
702
+ // private
703
+ onResize : function(){
704
+ Ext.grid.GridPanel.superclass.onResize.apply(this, arguments);
705
+ if(this.viewReady){
706
+ this.view.layout();
707
+ }
708
+ },
709
+
710
+ /**
711
+ * Returns the grid's underlying element.
712
+ * @return {Element} The element
713
+ */
714
+ getGridEl : function(){
715
+ return this.body;
716
+ },
717
+
718
+ // private for compatibility, overridden by editor grid
719
+ stopEditing : Ext.emptyFn,
720
+
721
+ /**
722
+ * Returns the grid's selection model configured by the <code>{@link #selModel}</code>
723
+ * configuration option. If no selection model was configured, this will create
724
+ * and return a {@link Ext.grid.RowSelectionModel RowSelectionModel}.
725
+ * @return {SelectionModel}
726
+ */
727
+ getSelectionModel : function(){
728
+ if(!this.selModel){
729
+ this.selModel = new Ext.grid.RowSelectionModel(
730
+ this.disableSelection ? {selectRow: Ext.emptyFn} : null);
731
+ }
732
+ return this.selModel;
733
+ },
734
+
735
+ /**
736
+ * Returns the grid's data store.
737
+ * @return {Ext.data.Store} The store
738
+ */
739
+ getStore : function(){
740
+ return this.store;
741
+ },
742
+
743
+ /**
744
+ * Returns the grid's ColumnModel.
745
+ * @return {Ext.grid.ColumnModel} The column model
746
+ */
747
+ getColumnModel : function(){
748
+ return this.colModel;
749
+ },
750
+
751
+ /**
752
+ * Returns the grid's GridView object.
753
+ * @return {Ext.grid.GridView} The grid view
754
+ */
755
+ getView : function(){
756
+ if(!this.view){
757
+ this.view = new Ext.grid.GridView(this.viewConfig);
758
+ }
759
+ return this.view;
760
+ },
761
+ /**
762
+ * Called to get grid's drag proxy text, by default returns this.ddText.
763
+ * @return {String} The text
764
+ */
765
+ getDragDropText : function(){
766
+ var count = this.selModel.getCount();
767
+ return String.format(this.ddText, count, count == 1 ? '' : 's');
768
+ }
769
+
770
+ /**
771
+ * @cfg {String/Number} activeItem
772
+ * @hide
773
+ */
774
+ /**
775
+ * @cfg {Boolean} autoDestroy
776
+ * @hide
777
+ */
778
+ /**
779
+ * @cfg {Object/String/Function} autoLoad
780
+ * @hide
781
+ */
782
+ /**
783
+ * @cfg {Boolean} autoWidth
784
+ * @hide
785
+ */
786
+ /**
787
+ * @cfg {Boolean/Number} bufferResize
788
+ * @hide
789
+ */
790
+ /**
791
+ * @cfg {String} defaultType
792
+ * @hide
793
+ */
794
+ /**
795
+ * @cfg {Object} defaults
796
+ * @hide
797
+ */
798
+ /**
799
+ * @cfg {Boolean} hideBorders
800
+ * @hide
801
+ */
802
+ /**
803
+ * @cfg {Mixed} items
804
+ * @hide
805
+ */
806
+ /**
807
+ * @cfg {String} layout
808
+ * @hide
809
+ */
810
+ /**
811
+ * @cfg {Object} layoutConfig
812
+ * @hide
813
+ */
814
+ /**
815
+ * @cfg {Boolean} monitorResize
816
+ * @hide
817
+ */
818
+ /**
819
+ * @property items
820
+ * @hide
821
+ */
822
+ /**
823
+ * @method add
824
+ * @hide
825
+ */
826
+ /**
827
+ * @method cascade
828
+ * @hide
829
+ */
830
+ /**
831
+ * @method doLayout
832
+ * @hide
833
+ */
834
+ /**
835
+ * @method find
836
+ * @hide
837
+ */
838
+ /**
839
+ * @method findBy
840
+ * @hide
841
+ */
842
+ /**
843
+ * @method findById
844
+ * @hide
845
+ */
846
+ /**
847
+ * @method findByType
848
+ * @hide
849
+ */
850
+ /**
851
+ * @method getComponent
852
+ * @hide
853
+ */
854
+ /**
855
+ * @method getLayout
856
+ * @hide
857
+ */
858
+ /**
859
+ * @method getUpdater
860
+ * @hide
861
+ */
862
+ /**
863
+ * @method insert
864
+ * @hide
865
+ */
866
+ /**
867
+ * @method load
868
+ * @hide
869
+ */
870
+ /**
871
+ * @method remove
872
+ * @hide
873
+ */
874
+ /**
875
+ * @event add
876
+ * @hide
877
+ */
878
+ /**
879
+ * @event afterLayout
880
+ * @hide
881
+ */
882
+ /**
883
+ * @event beforeadd
884
+ * @hide
885
+ */
886
+ /**
887
+ * @event beforeremove
888
+ * @hide
889
+ */
890
+ /**
891
+ * @event remove
892
+ * @hide
893
+ */
894
+
895
+
896
+
897
+ /**
898
+ * @cfg {String} allowDomMove @hide
899
+ */
900
+ /**
901
+ * @cfg {String} autoEl @hide
902
+ */
903
+ /**
904
+ * @cfg {String} applyTo @hide
905
+ */
906
+ /**
907
+ * @cfg {String} autoScroll @hide
908
+ */
909
+ /**
910
+ * @cfg {String} bodyBorder @hide
911
+ */
912
+ /**
913
+ * @cfg {String} bodyStyle @hide
914
+ */
915
+ /**
916
+ * @cfg {String} contentEl @hide
917
+ */
918
+ /**
919
+ * @cfg {String} disabledClass @hide
920
+ */
921
+ /**
922
+ * @cfg {String} elements @hide
923
+ */
924
+ /**
925
+ * @cfg {String} html @hide
926
+ */
927
+ /**
928
+ * @cfg {Boolean} preventBodyReset
929
+ * @hide
930
+ */
931
+ /**
932
+ * @property disabled
933
+ * @hide
934
+ */
935
+ /**
936
+ * @method applyToMarkup
937
+ * @hide
938
+ */
939
+ /**
940
+ * @method enable
941
+ * @hide
942
+ */
943
+ /**
944
+ * @method disable
945
+ * @hide
946
+ */
947
+ /**
948
+ * @method setDisabled
949
+ * @hide
950
+ */
951
+ });
952
+ Ext.reg('grid', Ext.grid.GridPanel);/**
953
+ * @class Ext.grid.GridView
954
+ * @extends Ext.util.Observable
955
+ * <p>This class encapsulates the user interface of an {@link Ext.grid.GridPanel}.
956
+ * Methods of this class may be used to access user interface elements to enable
957
+ * special display effects. Do not change the DOM structure of the user interface.</p>
958
+ * <p>This class does not provide ways to manipulate the underlying data. The data
959
+ * model of a Grid is held in an {@link Ext.data.Store}.</p>
960
+ * @constructor
961
+ * @param {Object} config
962
+ */
963
+ Ext.grid.GridView = function(config){
964
+ Ext.apply(this, config);
965
+ // These events are only used internally by the grid components
966
+ this.addEvents(
967
+ /**
968
+ * @event beforerowremoved
969
+ * Internal UI Event. Fired before a row is removed.
970
+ * @param {Ext.grid.GridView} view
971
+ * @param {Number} rowIndex The index of the row to be removed.
972
+ * @param {Ext.data.Record} record The Record to be removed
973
+ */
974
+ "beforerowremoved",
975
+ /**
976
+ * @event beforerowsinserted
977
+ * Internal UI Event. Fired before rows are inserted.
978
+ * @param {Ext.grid.GridView} view
979
+ * @param {Number} firstRow The index of the first row to be inserted.
980
+ * @param {Number} lastRow The index of the last row to be inserted.
981
+ */
982
+ "beforerowsinserted",
983
+ /**
984
+ * @event beforerefresh
985
+ * Internal UI Event. Fired before the view is refreshed.
986
+ * @param {Ext.grid.GridView} view
987
+ */
988
+ "beforerefresh",
989
+ /**
990
+ * @event rowremoved
991
+ * Internal UI Event. Fired after a row is removed.
992
+ * @param {Ext.grid.GridView} view
993
+ * @param {Number} rowIndex The index of the row that was removed.
994
+ * @param {Ext.data.Record} record The Record that was removed
995
+ */
996
+ "rowremoved",
997
+ /**
998
+ * @event rowsinserted
999
+ * Internal UI Event. Fired after rows are inserted.
1000
+ * @param {Ext.grid.GridView} view
1001
+ * @param {Number} firstRow The index of the first inserted.
1002
+ * @param {Number} lastRow The index of the last row inserted.
1003
+ */
1004
+ "rowsinserted",
1005
+ /**
1006
+ * @event rowupdated
1007
+ * Internal UI Event. Fired after a row has been updated.
1008
+ * @param {Ext.grid.GridView} view
1009
+ * @param {Number} firstRow The index of the row updated.
1010
+ * @param {Ext.data.record} record The Record backing the row updated.
1011
+ */
1012
+ "rowupdated",
1013
+ /**
1014
+ * @event refresh
1015
+ * Internal UI Event. Fired after the GridView's body has been refreshed.
1016
+ * @param {Ext.grid.GridView} view
1017
+ */
1018
+ "refresh"
1019
+ );
1020
+ Ext.grid.GridView.superclass.constructor.call(this);
1021
+ };
1022
+
1023
+ Ext.extend(Ext.grid.GridView, Ext.util.Observable, {
1024
+ /**
1025
+ * Override this function to apply custom CSS classes to rows during rendering. You can also supply custom
1026
+ * parameters to the row template for the current row to customize how it is rendered using the <b>rowParams</b>
1027
+ * parameter. This function should return the CSS class name (or empty string '' for none) that will be added
1028
+ * to the row's wrapping div. To apply multiple class names, simply return them space-delimited within the string
1029
+ * (e.g., 'my-class another-class'). Example usage:
1030
+ <pre><code>
1031
+ viewConfig: {
1032
+ forceFit: true,
1033
+ showPreview: true, // custom property
1034
+ enableRowBody: true, // required to create a second, full-width row to show expanded Record data
1035
+ getRowClass: function(record, rowIndex, rp, ds){ // rp = rowParams
1036
+ if(this.showPreview){
1037
+ rp.body = '&lt;p>'+record.data.excerpt+'&lt;/p>';
1038
+ return 'x-grid3-row-expanded';
1039
+ }
1040
+ return 'x-grid3-row-collapsed';
1041
+ }
1042
+ },
1043
+ </code></pre>
1044
+ * @param {Record} record The {@link Ext.data.Record} corresponding to the current row.
1045
+ * @param {Number} index The row index.
1046
+ * @param {Object} rowParams A config object that is passed to the row template during rendering that allows
1047
+ * customization of various aspects of a grid row.
1048
+ * <p>If {@link #enableRowBody} is configured <b><tt></tt>true</b>, then the following properties may be set
1049
+ * by this function, and will be used to render a full-width expansion row below each grid row:</p>
1050
+ * <ul>
1051
+ * <li><code>body</code> : String <div class="sub-desc">An HTML fragment to be used as the expansion row's body content (defaults to '').</div></li>
1052
+ * <li><code>bodyStyle</code> : String <div class="sub-desc">A CSS style specification that will be applied to the expansion row's &lt;tr> element. (defaults to '').</div></li>
1053
+ * </ul>
1054
+ * The following property will be passed in, and may be appended to:
1055
+ * <ul>
1056
+ * <li><code>tstyle</code> : String <div class="sub-desc">A CSS style specification that willl be applied to the &lt;table> element which encapsulates
1057
+ * both the standard grid row, and any expansion row.</div></li>
1058
+ * </ul>
1059
+ * @param {Store} store The {@link Ext.data.Store} this grid is bound to
1060
+ * @method getRowClass
1061
+ * @return {String} a CSS class name to add to the row.
1062
+ */
1063
+ /**
1064
+ * @cfg {Boolean} enableRowBody True to add a second TR element per row that can be used to provide a row body
1065
+ * that spans beneath the data row. Use the {@link #getRowClass} method's rowParams config to customize the row body.
1066
+ */
1067
+ /**
1068
+ * @cfg {String} emptyText Default text (html tags are accepted) to display in the grid body when no rows
1069
+ * are available (defaults to ''). This value will be used to update the <tt>{@link #mainBody}</tt>:
1070
+ <pre><code>
1071
+ this.mainBody.update('&lt;div class="x-grid-empty">' + this.emptyText + '&lt;/div>');
1072
+ </code></pre>
1073
+ */
1074
+ /**
1075
+ * @cfg {Boolean} headersDisabled True to disable the grid column headers (defaults to <tt>false</tt>).
1076
+ * Use the {@link Ext.grid.ColumnModel ColumnModel} <tt>{@link Ext.grid.ColumnModel#menuDisabled menuDisabled}</tt>
1077
+ * config to disable the <i>menu</i> for individual columns. While this config is true the
1078
+ * following will be disabled:<div class="mdetail-params"><ul>
1079
+ * <li>clicking on header to sort</li>
1080
+ * <li>the trigger to reveal the menu.</li>
1081
+ * </ul></div>
1082
+ */
1083
+ /**
1084
+ * <p>A customized implementation of a {@link Ext.dd.DragZone DragZone} which provides default implementations
1085
+ * of the template methods of DragZone to enable dragging of the selected rows of a GridPanel.
1086
+ * See {@link Ext.grid.GridDragZone} for details.</p>
1087
+ * <p>This will <b>only</b> be present:<div class="mdetail-params"><ul>
1088
+ * <li><i>if</i> the owning GridPanel was configured with {@link Ext.grid.GridPanel#enableDragDrop enableDragDrop}: <tt>true</tt>.</li>
1089
+ * <li><i>after</i> the owning GridPanel has been rendered.</li>
1090
+ * </ul></div>
1091
+ * @property dragZone
1092
+ * @type {Ext.grid.GridDragZone}
1093
+ */
1094
+ /**
1095
+ * @cfg {Boolean} deferEmptyText True to defer <tt>{@link #emptyText}</tt> being applied until the store's
1096
+ * first load (defaults to <tt>true</tt>).
1097
+ */
1098
+ deferEmptyText : true,
1099
+ /**
1100
+ * @cfg {Number} scrollOffset The amount of space to reserve for the vertical scrollbar
1101
+ * (defaults to <tt>19</tt> pixels).
1102
+ */
1103
+ scrollOffset : 19,
1104
+ /**
1105
+ * @cfg {Boolean} autoFill
1106
+ * Defaults to <tt>false</tt>. Specify <tt>true</tt> to have the column widths re-proportioned
1107
+ * when the grid is <b>initially rendered</b>. The
1108
+ * {@link Ext.grid.Column#width initially configured width}</tt> of each column will be adjusted
1109
+ * to fit the grid width and prevent horizontal scrolling. If columns are later resized (manually
1110
+ * or programmatically), the other columns in the grid will <b>not</b> be resized to fit the grid width.
1111
+ * See <tt>{@link #forceFit}</tt> also.
1112
+ */
1113
+ autoFill : false,
1114
+ /**
1115
+ * @cfg {Boolean} forceFit
1116
+ * Defaults to <tt>false</tt>. Specify <tt>true</tt> to have the column widths re-proportioned
1117
+ * at <b>all times</b>. The {@link Ext.grid.Column#width initially configured width}</tt> of each
1118
+ * column will be adjusted to fit the grid width and prevent horizontal scrolling. If columns are
1119
+ * later resized (manually or programmatically), the other columns in the grid <b>will</b> be resized
1120
+ * to fit the grid width. See <tt>{@link #autoFill}</tt> also.
1121
+ */
1122
+ forceFit : false,
1123
+ /**
1124
+ * @cfg {Array} sortClasses The CSS classes applied to a header when it is sorted. (defaults to <tt>["sort-asc", "sort-desc"]</tt>)
1125
+ */
1126
+ sortClasses : ["sort-asc", "sort-desc"],
1127
+ /**
1128
+ * @cfg {String} sortAscText The text displayed in the "Sort Ascending" menu item (defaults to <tt>"Sort Ascending"</tt>)
1129
+ */
1130
+ sortAscText : "Sort Ascending",
1131
+ /**
1132
+ * @cfg {String} sortDescText The text displayed in the "Sort Descending" menu item (defaults to <tt>"Sort Descending"</tt>)
1133
+ */
1134
+ sortDescText : "Sort Descending",
1135
+ /**
1136
+ * @cfg {String} columnsText The text displayed in the "Columns" menu item (defaults to <tt>"Columns"</tt>)
1137
+ */
1138
+ columnsText : "Columns",
1139
+
1140
+ /**
1141
+ * @cfg {String} selectedRowClass The CSS class applied to a selected row (defaults to <tt>"x-grid3-row-selected"</tt>). An
1142
+ * example overriding the default styling:
1143
+ <pre><code>
1144
+ .x-grid3-row-selected {background-color: yellow;}
1145
+ </code></pre>
1146
+ * Note that this only controls the row, and will not do anything for the text inside it. To style inner
1147
+ * facets (like text) use something like:
1148
+ <pre><code>
1149
+ .x-grid3-row-selected .x-grid3-cell-inner {
1150
+ color: #FFCC00;
1151
+ }
1152
+ </code></pre>
1153
+ * @type String
1154
+ */
1155
+ selectedRowClass : "x-grid3-row-selected",
1156
+
1157
+ // private
1158
+ borderWidth : 2,
1159
+ tdClass : 'x-grid3-cell',
1160
+ hdCls : 'x-grid3-hd',
1161
+ markDirty : true,
1162
+
1163
+ /**
1164
+ * @cfg {Number} cellSelectorDepth The number of levels to search for cells in event delegation (defaults to <tt>4</tt>)
1165
+ */
1166
+ cellSelectorDepth : 4,
1167
+ /**
1168
+ * @cfg {Number} rowSelectorDepth The number of levels to search for rows in event delegation (defaults to <tt>10</tt>)
1169
+ */
1170
+ rowSelectorDepth : 10,
1171
+
1172
+ /**
1173
+ * @cfg {String} cellSelector The selector used to find cells internally (defaults to <tt>'td.x-grid3-cell'</tt>)
1174
+ */
1175
+ cellSelector : 'td.x-grid3-cell',
1176
+ /**
1177
+ * @cfg {String} rowSelector The selector used to find rows internally (defaults to <tt>'div.x-grid3-row'</tt>)
1178
+ */
1179
+ rowSelector : 'div.x-grid3-row',
1180
+
1181
+ // private
1182
+ firstRowCls: 'x-grid3-row-first',
1183
+ lastRowCls: 'x-grid3-row-last',
1184
+ rowClsRe: /(?:^|\s+)x-grid3-row-(first|last|alt)(?:\s+|$)/g,
1185
+
1186
+ /* -------------------------------- UI Specific ----------------------------- */
1187
+
1188
+ // private
1189
+ initTemplates : function(){
1190
+ var ts = this.templates || {};
1191
+ if(!ts.master){
1192
+ ts.master = new Ext.Template(
1193
+ '<div class="x-grid3" hidefocus="true">',
1194
+ '<div class="x-grid3-viewport">',
1195
+ '<div class="x-grid3-header"><div class="x-grid3-header-inner"><div class="x-grid3-header-offset" style="{ostyle}">{header}</div></div><div class="x-clear"></div></div>',
1196
+ '<div class="x-grid3-scroller"><div class="x-grid3-body" style="{bstyle}">{body}</div><a href="#" class="x-grid3-focus" tabIndex="-1"></a></div>',
1197
+ '</div>',
1198
+ '<div class="x-grid3-resize-marker">&#160;</div>',
1199
+ '<div class="x-grid3-resize-proxy">&#160;</div>',
1200
+ '</div>'
1201
+ );
1202
+ }
1203
+
1204
+ if(!ts.header){
1205
+ ts.header = new Ext.Template(
1206
+ '<table border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
1207
+ '<thead><tr class="x-grid3-hd-row">{cells}</tr></thead>',
1208
+ '</table>'
1209
+ );
1210
+ }
1211
+
1212
+ if(!ts.hcell){
1213
+ ts.hcell = new Ext.Template(
1214
+ '<td class="x-grid3-hd x-grid3-cell x-grid3-td-{id} {css}" style="{style}"><div {tooltip} {attr} class="x-grid3-hd-inner x-grid3-hd-{id}" unselectable="on" style="{istyle}">', this.grid.enableHdMenu ? '<a class="x-grid3-hd-btn" href="#"></a>' : '',
1215
+ '{value}<img class="x-grid3-sort-icon" src="', Ext.BLANK_IMAGE_URL, '" />',
1216
+ '</div></td>'
1217
+ );
1218
+ }
1219
+
1220
+ if(!ts.body){
1221
+ ts.body = new Ext.Template('{rows}');
1222
+ }
1223
+
1224
+ if(!ts.row){
1225
+ ts.row = new Ext.Template(
1226
+ '<div class="x-grid3-row {alt}" style="{tstyle}"><table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
1227
+ '<tbody><tr>{cells}</tr>',
1228
+ (this.enableRowBody ? '<tr class="x-grid3-row-body-tr" style="{bodyStyle}"><td colspan="{cols}" class="x-grid3-body-cell" tabIndex="0" hidefocus="on"><div class="x-grid3-row-body">{body}</div></td></tr>' : ''),
1229
+ '</tbody></table></div>'
1230
+ );
1231
+ }
1232
+
1233
+ if(!ts.cell){
1234
+ ts.cell = new Ext.Template(
1235
+ '<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}" tabIndex="0" {cellAttr}>',
1236
+ '<div class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on" {attr}>{value}</div>',
1237
+ '</td>'
1238
+ );
1239
+ }
1240
+
1241
+ for(var k in ts){
1242
+ var t = ts[k];
1243
+ if(t && typeof t.compile == 'function' && !t.compiled){
1244
+ t.disableFormats = true;
1245
+ t.compile();
1246
+ }
1247
+ }
1248
+
1249
+ this.templates = ts;
1250
+ this.colRe = new RegExp("x-grid3-td-([^\\s]+)", "");
1251
+ },
1252
+
1253
+ // private
1254
+ fly : function(el){
1255
+ if(!this._flyweight){
1256
+ this._flyweight = new Ext.Element.Flyweight(document.body);
1257
+ }
1258
+ this._flyweight.dom = el;
1259
+ return this._flyweight;
1260
+ },
1261
+
1262
+ // private
1263
+ getEditorParent : function(){
1264
+ return this.scroller.dom;
1265
+ },
1266
+
1267
+ // private
1268
+ initElements : function(){
1269
+ var E = Ext.Element;
1270
+
1271
+ var el = this.grid.getGridEl().dom.firstChild;
1272
+ var cs = el.childNodes;
1273
+
1274
+ this.el = new E(el);
1275
+
1276
+ this.mainWrap = new E(cs[0]);
1277
+ this.mainHd = new E(this.mainWrap.dom.firstChild);
1278
+
1279
+ if(this.grid.hideHeaders){
1280
+ this.mainHd.setDisplayed(false);
1281
+ }
1282
+
1283
+ this.innerHd = this.mainHd.dom.firstChild;
1284
+ this.scroller = new E(this.mainWrap.dom.childNodes[1]);
1285
+ if(this.forceFit){
1286
+ this.scroller.setStyle('overflow-x', 'hidden');
1287
+ }
1288
+ /**
1289
+ * <i>Read-only</i>. The GridView's body Element which encapsulates all rows in the Grid.
1290
+ * This {@link Ext.Element Element} is only available after the GridPanel has been rendered.
1291
+ * @type Ext.Element
1292
+ * @property mainBody
1293
+ */
1294
+ this.mainBody = new E(this.scroller.dom.firstChild);
1295
+
1296
+ this.focusEl = new E(this.scroller.dom.childNodes[1]);
1297
+ this.focusEl.swallowEvent("click", true);
1298
+
1299
+ this.resizeMarker = new E(cs[1]);
1300
+ this.resizeProxy = new E(cs[2]);
1301
+ },
1302
+
1303
+ // private
1304
+ getRows : function(){
1305
+ return this.hasRows() ? this.mainBody.dom.childNodes : [];
1306
+ },
1307
+
1308
+ // finder methods, used with delegation
1309
+
1310
+ // private
1311
+ findCell : function(el){
1312
+ if(!el){
1313
+ return false;
1314
+ }
1315
+ return this.fly(el).findParent(this.cellSelector, this.cellSelectorDepth);
1316
+ },
1317
+
1318
+ /**
1319
+ * <p>Return the index of the grid column which contains the passed element.</p>
1320
+ * See also {@link #findRowIndex}
1321
+ * @param {Element} el The target element
1322
+ * @return The column index, or <b>false</b> if the target element is not within a row of this GridView.
1323
+ */
1324
+ findCellIndex : function(el, requiredCls){
1325
+ var cell = this.findCell(el);
1326
+ if(cell && (!requiredCls || this.fly(cell).hasClass(requiredCls))){
1327
+ return this.getCellIndex(cell);
1328
+ }
1329
+ return false;
1330
+ },
1331
+
1332
+ // private
1333
+ getCellIndex : function(el){
1334
+ if(el){
1335
+ var m = el.className.match(this.colRe);
1336
+ if(m && m[1]){
1337
+ return this.cm.getIndexById(m[1]);
1338
+ }
1339
+ }
1340
+ return false;
1341
+ },
1342
+
1343
+ // private
1344
+ findHeaderCell : function(el){
1345
+ var cell = this.findCell(el);
1346
+ return cell && this.fly(cell).hasClass(this.hdCls) ? cell : null;
1347
+ },
1348
+
1349
+ // private
1350
+ findHeaderIndex : function(el){
1351
+ return this.findCellIndex(el, this.hdCls);
1352
+ },
1353
+
1354
+ /**
1355
+ * Return the HtmlElement representing the grid row which contains the passed element.
1356
+ * @param {Element} el The target element
1357
+ * @return The row element, or null if the target element is not within a row of this GridView.
1358
+ */
1359
+ findRow : function(el){
1360
+ if(!el){
1361
+ return false;
1362
+ }
1363
+ return this.fly(el).findParent(this.rowSelector, this.rowSelectorDepth);
1364
+ },
1365
+
1366
+ /**
1367
+ * <p>Return the index of the grid row which contains the passed element.</p>
1368
+ * See also {@link #findCellIndex}
1369
+ * @param {Element} el The target element
1370
+ * @return The row index, or <b>false</b> if the target element is not within a row of this GridView.
1371
+ */
1372
+ findRowIndex : function(el){
1373
+ var r = this.findRow(el);
1374
+ return r ? r.rowIndex : false;
1375
+ },
1376
+
1377
+ // getter methods for fetching elements dynamically in the grid
1378
+
1379
+ /**
1380
+ * Return the <tt>&lt;div></tt> HtmlElement which represents a Grid row for the specified index.
1381
+ * @param {Number} index The row index
1382
+ * @return {HtmlElement} The div element.
1383
+ */
1384
+ getRow : function(row){
1385
+ return this.getRows()[row];
1386
+ },
1387
+
1388
+ /**
1389
+ * Returns the grid's <tt>&lt;td></tt> HtmlElement at the specified coordinates.
1390
+ * @param {Number} row The row index in which to find the cell.
1391
+ * @param {Number} col The column index of the cell.
1392
+ * @return {HtmlElement} The td at the specified coordinates.
1393
+ */
1394
+ getCell : function(row, col){
1395
+ return this.getRow(row).getElementsByTagName('td')[col];
1396
+ },
1397
+
1398
+ /**
1399
+ * Return the <tt>&lt;td></tt> HtmlElement which represents the Grid's header cell for the specified column index.
1400
+ * @param {Number} index The column index
1401
+ * @return {HtmlElement} The td element.
1402
+ */
1403
+ getHeaderCell : function(index){
1404
+ return this.mainHd.dom.getElementsByTagName('td')[index];
1405
+ },
1406
+
1407
+ // manipulating elements
1408
+
1409
+ // private - use getRowClass to apply custom row classes
1410
+ addRowClass : function(row, cls){
1411
+ var r = this.getRow(row);
1412
+ if(r){
1413
+ this.fly(r).addClass(cls);
1414
+ }
1415
+ },
1416
+
1417
+ // private
1418
+ removeRowClass : function(row, cls){
1419
+ var r = this.getRow(row);
1420
+ if(r){
1421
+ this.fly(r).removeClass(cls);
1422
+ }
1423
+ },
1424
+
1425
+ // private
1426
+ removeRow : function(row){
1427
+ Ext.removeNode(this.getRow(row));
1428
+ this.syncFocusEl(row);
1429
+ },
1430
+
1431
+ // private
1432
+ removeRows : function(firstRow, lastRow){
1433
+ var bd = this.mainBody.dom;
1434
+ for(var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){
1435
+ Ext.removeNode(bd.childNodes[firstRow]);
1436
+ }
1437
+ this.syncFocusEl(firstRow);
1438
+ },
1439
+
1440
+ // scrolling stuff
1441
+
1442
+ // private
1443
+ getScrollState : function(){
1444
+ var sb = this.scroller.dom;
1445
+ return {left: sb.scrollLeft, top: sb.scrollTop};
1446
+ },
1447
+
1448
+ // private
1449
+ restoreScroll : function(state){
1450
+ var sb = this.scroller.dom;
1451
+ sb.scrollLeft = state.left;
1452
+ sb.scrollTop = state.top;
1453
+ },
1454
+
1455
+ /**
1456
+ * Scrolls the grid to the top
1457
+ */
1458
+ scrollToTop : function(){
1459
+ this.scroller.dom.scrollTop = 0;
1460
+ this.scroller.dom.scrollLeft = 0;
1461
+ },
1462
+
1463
+ // private
1464
+ syncScroll : function(){
1465
+ this.syncHeaderScroll();
1466
+ var mb = this.scroller.dom;
1467
+ this.grid.fireEvent("bodyscroll", mb.scrollLeft, mb.scrollTop);
1468
+ },
1469
+
1470
+ // private
1471
+ syncHeaderScroll : function(){
1472
+ var mb = this.scroller.dom;
1473
+ this.innerHd.scrollLeft = mb.scrollLeft;
1474
+ this.innerHd.scrollLeft = mb.scrollLeft; // second time for IE (1/2 time first fails, other browsers ignore)
1475
+ },
1476
+
1477
+ // private
1478
+ updateSortIcon : function(col, dir){
1479
+ var sc = this.sortClasses;
1480
+ var hds = this.mainHd.select('td').removeClass(sc);
1481
+ hds.item(col).addClass(sc[dir == "DESC" ? 1 : 0]);
1482
+ },
1483
+
1484
+ // private
1485
+ updateAllColumnWidths : function(){
1486
+ var tw = this.getTotalWidth(),
1487
+ clen = this.cm.getColumnCount(),
1488
+ ws = [],
1489
+ len,
1490
+ i;
1491
+ for(i = 0; i < clen; i++){
1492
+ ws[i] = this.getColumnWidth(i);
1493
+ }
1494
+ this.innerHd.firstChild.style.width = this.getOffsetWidth();
1495
+ this.innerHd.firstChild.firstChild.style.width = tw;
1496
+ this.mainBody.dom.style.width = tw;
1497
+ for(i = 0; i < clen; i++){
1498
+ var hd = this.getHeaderCell(i);
1499
+ hd.style.width = ws[i];
1500
+ }
1501
+
1502
+ var ns = this.getRows(), row, trow;
1503
+ for(i = 0, len = ns.length; i < len; i++){
1504
+ row = ns[i];
1505
+ row.style.width = tw;
1506
+ if(row.firstChild){
1507
+ row.firstChild.style.width = tw;
1508
+ trow = row.firstChild.rows[0];
1509
+ for (var j = 0; j < clen; j++) {
1510
+ trow.childNodes[j].style.width = ws[j];
1511
+ }
1512
+ }
1513
+ }
1514
+
1515
+ this.onAllColumnWidthsUpdated(ws, tw);
1516
+ },
1517
+
1518
+ // private
1519
+ updateColumnWidth : function(col, width){
1520
+ var w = this.getColumnWidth(col);
1521
+ var tw = this.getTotalWidth();
1522
+ this.innerHd.firstChild.style.width = this.getOffsetWidth();
1523
+ this.innerHd.firstChild.firstChild.style.width = tw;
1524
+ this.mainBody.dom.style.width = tw;
1525
+ var hd = this.getHeaderCell(col);
1526
+ hd.style.width = w;
1527
+
1528
+ var ns = this.getRows(), row;
1529
+ for(var i = 0, len = ns.length; i < len; i++){
1530
+ row = ns[i];
1531
+ row.style.width = tw;
1532
+ if(row.firstChild){
1533
+ row.firstChild.style.width = tw;
1534
+ row.firstChild.rows[0].childNodes[col].style.width = w;
1535
+ }
1536
+ }
1537
+
1538
+ this.onColumnWidthUpdated(col, w, tw);
1539
+ },
1540
+
1541
+ // private
1542
+ updateColumnHidden : function(col, hidden){
1543
+ var tw = this.getTotalWidth();
1544
+ this.innerHd.firstChild.style.width = this.getOffsetWidth();
1545
+ this.innerHd.firstChild.firstChild.style.width = tw;
1546
+ this.mainBody.dom.style.width = tw;
1547
+ var display = hidden ? 'none' : '';
1548
+
1549
+ var hd = this.getHeaderCell(col);
1550
+ hd.style.display = display;
1551
+
1552
+ var ns = this.getRows(), row;
1553
+ for(var i = 0, len = ns.length; i < len; i++){
1554
+ row = ns[i];
1555
+ row.style.width = tw;
1556
+ if(row.firstChild){
1557
+ row.firstChild.style.width = tw;
1558
+ row.firstChild.rows[0].childNodes[col].style.display = display;
1559
+ }
1560
+ }
1561
+
1562
+ this.onColumnHiddenUpdated(col, hidden, tw);
1563
+ delete this.lastViewWidth; // force recalc
1564
+ this.layout();
1565
+ },
1566
+
1567
+ // private
1568
+ doRender : function(cs, rs, ds, startRow, colCount, stripe){
1569
+ var ts = this.templates, ct = ts.cell, rt = ts.row, last = colCount-1;
1570
+ var tstyle = 'width:'+this.getTotalWidth()+';';
1571
+ // buffers
1572
+ var buf = [], cb, c, p = {}, rp = {tstyle: tstyle}, r;
1573
+ for(var j = 0, len = rs.length; j < len; j++){
1574
+ r = rs[j]; cb = [];
1575
+ var rowIndex = (j+startRow);
1576
+ for(var i = 0; i < colCount; i++){
1577
+ c = cs[i];
1578
+ p.id = c.id;
1579
+ p.css = i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
1580
+ p.attr = p.cellAttr = "";
1581
+ p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds);
1582
+ p.style = c.style;
1583
+ if(Ext.isEmpty(p.value)){
1584
+ p.value = "&#160;";
1585
+ }
1586
+ if(this.markDirty && r.dirty && typeof r.modified[c.name] !== 'undefined'){
1587
+ p.css += ' x-grid3-dirty-cell';
1588
+ }
1589
+ cb[cb.length] = ct.apply(p);
1590
+ }
1591
+ var alt = [];
1592
+ if(stripe && ((rowIndex+1) % 2 === 0)){
1593
+ alt[0] = "x-grid3-row-alt";
1594
+ }
1595
+ if(r.dirty){
1596
+ alt[1] = " x-grid3-dirty-row";
1597
+ }
1598
+ rp.cols = colCount;
1599
+ if(this.getRowClass){
1600
+ alt[2] = this.getRowClass(r, rowIndex, rp, ds);
1601
+ }
1602
+ rp.alt = alt.join(" ");
1603
+ rp.cells = cb.join("");
1604
+ buf[buf.length] = rt.apply(rp);
1605
+ }
1606
+ return buf.join("");
1607
+ },
1608
+
1609
+ // private
1610
+ processRows : function(startRow, skipStripe){
1611
+ if(!this.ds || this.ds.getCount() < 1){
1612
+ return;
1613
+ }
1614
+ var rows = this.getRows();
1615
+ skipStripe = skipStripe || !this.grid.stripeRows;
1616
+ startRow = startRow || 0;
1617
+ Ext.each(rows, function(row, idx){
1618
+ row.rowIndex = idx;
1619
+ row.className = row.className.replace(this.rowClsRe, ' ');
1620
+ if (!skipStripe && (idx + 1) % 2 === 0) {
1621
+ row.className += ' x-grid3-row-alt';
1622
+ }
1623
+ });
1624
+ // add first/last-row classes
1625
+ if(startRow === 0){
1626
+ Ext.fly(rows[0]).addClass(this.firstRowCls);
1627
+ }
1628
+ Ext.fly(rows[rows.length - 1]).addClass(this.lastRowCls);
1629
+ },
1630
+
1631
+ afterRender : function(){
1632
+ if(!this.ds || !this.cm){
1633
+ return;
1634
+ }
1635
+ this.mainBody.dom.innerHTML = this.renderRows() || '&#160;';
1636
+ this.processRows(0, true);
1637
+
1638
+ if(this.deferEmptyText !== true){
1639
+ this.applyEmptyText();
1640
+ }
1641
+ },
1642
+
1643
+ // private
1644
+ renderUI : function(){
1645
+
1646
+ var header = this.renderHeaders();
1647
+ var body = this.templates.body.apply({rows:'&#160;'});
1648
+
1649
+
1650
+ var html = this.templates.master.apply({
1651
+ body: body,
1652
+ header: header,
1653
+ ostyle: 'width:'+this.getOffsetWidth()+';',
1654
+ bstyle: 'width:'+this.getTotalWidth()+';'
1655
+ });
1656
+
1657
+ var g = this.grid;
1658
+
1659
+ g.getGridEl().dom.innerHTML = html;
1660
+
1661
+ this.initElements();
1662
+
1663
+ // get mousedowns early
1664
+ Ext.fly(this.innerHd).on("click", this.handleHdDown, this);
1665
+ this.mainHd.on({
1666
+ scope: this,
1667
+ mouseover: this.handleHdOver,
1668
+ mouseout: this.handleHdOut,
1669
+ mousemove: this.handleHdMove
1670
+ });
1671
+
1672
+ this.scroller.on('scroll', this.syncScroll, this);
1673
+ if(g.enableColumnResize !== false){
1674
+ this.splitZone = new Ext.grid.GridView.SplitDragZone(g, this.mainHd.dom);
1675
+ }
1676
+
1677
+ if(g.enableColumnMove){
1678
+ this.columnDrag = new Ext.grid.GridView.ColumnDragZone(g, this.innerHd);
1679
+ this.columnDrop = new Ext.grid.HeaderDropZone(g, this.mainHd.dom);
1680
+ }
1681
+
1682
+ if(g.enableHdMenu !== false){
1683
+ this.hmenu = new Ext.menu.Menu({id: g.id + "-hctx"});
1684
+ this.hmenu.add(
1685
+ {itemId:"asc", text: this.sortAscText, cls: "xg-hmenu-sort-asc"},
1686
+ {itemId:"desc", text: this.sortDescText, cls: "xg-hmenu-sort-desc"}
1687
+ );
1688
+ if(g.enableColumnHide !== false){
1689
+ this.colMenu = new Ext.menu.Menu({id:g.id + "-hcols-menu"});
1690
+ this.colMenu.on({
1691
+ scope: this,
1692
+ beforeshow: this.beforeColMenuShow,
1693
+ itemclick: this.handleHdMenuClick
1694
+ });
1695
+ this.hmenu.add('-', {
1696
+ itemId:"columns",
1697
+ hideOnClick: false,
1698
+ text: this.columnsText,
1699
+ menu: this.colMenu,
1700
+ iconCls: 'x-cols-icon'
1701
+ });
1702
+ }
1703
+ this.hmenu.on("itemclick", this.handleHdMenuClick, this);
1704
+ }
1705
+
1706
+ if(g.trackMouseOver){
1707
+ this.mainBody.on({
1708
+ scope: this,
1709
+ mouseover: this.onRowOver,
1710
+ mouseout: this.onRowOut
1711
+ });
1712
+ }
1713
+
1714
+ if(g.enableDragDrop || g.enableDrag){
1715
+ this.dragZone = new Ext.grid.GridDragZone(g, {
1716
+ ddGroup : g.ddGroup || 'GridDD'
1717
+ });
1718
+ }
1719
+
1720
+ this.updateHeaderSortState();
1721
+
1722
+ },
1723
+
1724
+ // private
1725
+ layout : function(){
1726
+ if(!this.mainBody){
1727
+ return; // not rendered
1728
+ }
1729
+ var g = this.grid;
1730
+ var c = g.getGridEl();
1731
+ var csize = c.getSize(true);
1732
+ var vw = csize.width;
1733
+
1734
+ if(!g.hideHeaders && (vw < 20 || csize.height < 20)){ // display: none?
1735
+ return;
1736
+ }
1737
+
1738
+ if(g.autoHeight){
1739
+ this.scroller.dom.style.overflow = 'visible';
1740
+ if(Ext.isWebKit){
1741
+ this.scroller.dom.style.position = 'static';
1742
+ }
1743
+ }else{
1744
+ this.el.setSize(csize.width, csize.height);
1745
+
1746
+ var hdHeight = this.mainHd.getHeight();
1747
+ var vh = csize.height - (hdHeight);
1748
+
1749
+ this.scroller.setSize(vw, vh);
1750
+ if(this.innerHd){
1751
+ this.innerHd.style.width = (vw)+'px';
1752
+ }
1753
+ }
1754
+ if(this.forceFit){
1755
+ if(this.lastViewWidth != vw){
1756
+ this.fitColumns(false, false);
1757
+ this.lastViewWidth = vw;
1758
+ }
1759
+ }else {
1760
+ this.autoExpand();
1761
+ this.syncHeaderScroll();
1762
+ }
1763
+ this.onLayout(vw, vh);
1764
+ },
1765
+
1766
+ // template functions for subclasses and plugins
1767
+ // these functions include precalculated values
1768
+ onLayout : function(vw, vh){
1769
+ // do nothing
1770
+ },
1771
+
1772
+ onColumnWidthUpdated : function(col, w, tw){
1773
+ //template method
1774
+ },
1775
+
1776
+ onAllColumnWidthsUpdated : function(ws, tw){
1777
+ //template method
1778
+ },
1779
+
1780
+ onColumnHiddenUpdated : function(col, hidden, tw){
1781
+ // template method
1782
+ },
1783
+
1784
+ updateColumnText : function(col, text){
1785
+ // template method
1786
+ },
1787
+
1788
+ afterMove : function(colIndex){
1789
+ // template method
1790
+ },
1791
+
1792
+ /* ----------------------------------- Core Specific -------------------------------------------*/
1793
+ // private
1794
+ init : function(grid){
1795
+ this.grid = grid;
1796
+
1797
+ this.initTemplates();
1798
+ this.initData(grid.store, grid.colModel);
1799
+ this.initUI(grid);
1800
+ },
1801
+
1802
+ // private
1803
+ getColumnId : function(index){
1804
+ return this.cm.getColumnId(index);
1805
+ },
1806
+
1807
+ // private
1808
+ getOffsetWidth : function() {
1809
+ return (this.cm.getTotalWidth() + this.scrollOffset) + 'px';
1810
+ },
1811
+
1812
+ // private
1813
+ renderHeaders : function(){
1814
+ var cm = this.cm,
1815
+ ts = this.templates,
1816
+ ct = ts.hcell,
1817
+ cb = [],
1818
+ p = {},
1819
+ len = cm.getColumnCount(),
1820
+ last = len - 1;
1821
+
1822
+ for(var i = 0; i < len; i++){
1823
+ p.id = cm.getColumnId(i);
1824
+ p.value = cm.getColumnHeader(i) || "";
1825
+ p.style = this.getColumnStyle(i, true);
1826
+ p.tooltip = this.getColumnTooltip(i);
1827
+ p.css = i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
1828
+ if(cm.config[i].align == 'right'){
1829
+ p.istyle = 'padding-right:16px';
1830
+ } else {
1831
+ delete p.istyle;
1832
+ }
1833
+ cb[cb.length] = ct.apply(p);
1834
+ }
1835
+ return ts.header.apply({cells: cb.join(""), tstyle:'width:'+this.getTotalWidth()+';'});
1836
+ },
1837
+
1838
+ // private
1839
+ getColumnTooltip : function(i){
1840
+ var tt = this.cm.getColumnTooltip(i);
1841
+ if(tt){
1842
+ if(Ext.QuickTips.isEnabled()){
1843
+ return 'ext:qtip="'+tt+'"';
1844
+ }else{
1845
+ return 'title="'+tt+'"';
1846
+ }
1847
+ }
1848
+ return "";
1849
+ },
1850
+
1851
+ // private
1852
+ beforeUpdate : function(){
1853
+ this.grid.stopEditing(true);
1854
+ },
1855
+
1856
+ // private
1857
+ updateHeaders : function(){
1858
+ this.innerHd.firstChild.innerHTML = this.renderHeaders();
1859
+ this.innerHd.firstChild.style.width = this.getOffsetWidth();
1860
+ this.innerHd.firstChild.firstChild.style.width = this.getTotalWidth();
1861
+ },
1862
+
1863
+ /**
1864
+ * Focuses the specified row.
1865
+ * @param {Number} row The row index
1866
+ */
1867
+ focusRow : function(row){
1868
+ this.focusCell(row, 0, false);
1869
+ },
1870
+
1871
+ /**
1872
+ * Focuses the specified cell.
1873
+ * @param {Number} row The row index
1874
+ * @param {Number} col The column index
1875
+ */
1876
+ focusCell : function(row, col, hscroll){
1877
+ this.syncFocusEl(this.ensureVisible(row, col, hscroll));
1878
+ if(Ext.isGecko){
1879
+ this.focusEl.focus();
1880
+ }else{
1881
+ this.focusEl.focus.defer(1, this.focusEl);
1882
+ }
1883
+ },
1884
+
1885
+ resolveCell : function(row, col, hscroll){
1886
+ if(typeof row != "number"){
1887
+ row = row.rowIndex;
1888
+ }
1889
+ if(!this.ds){
1890
+ return null;
1891
+ }
1892
+ if(row < 0 || row >= this.ds.getCount()){
1893
+ return null;
1894
+ }
1895
+ col = (col !== undefined ? col : 0);
1896
+
1897
+ var rowEl = this.getRow(row),
1898
+ cm = this.cm,
1899
+ colCount = cm.getColumnCount(),
1900
+ cellEl;
1901
+ if(!(hscroll === false && col === 0)){
1902
+ while(col < colCount && cm.isHidden(col)){
1903
+ col++;
1904
+ }
1905
+ cellEl = this.getCell(row, col);
1906
+ }
1907
+
1908
+ return {row: rowEl, cell: cellEl};
1909
+ },
1910
+
1911
+ getResolvedXY : function(resolved){
1912
+ if(!resolved){
1913
+ return null;
1914
+ }
1915
+ var s = this.scroller.dom, c = resolved.cell, r = resolved.row;
1916
+ return c ? Ext.fly(c).getXY() : [this.el.getX(), Ext.fly(r).getY()];
1917
+ },
1918
+
1919
+ syncFocusEl : function(row, col, hscroll){
1920
+ var xy = row;
1921
+ if(!Ext.isArray(xy)){
1922
+ row = Math.min(row, Math.max(0, this.getRows().length-1));
1923
+ xy = this.getResolvedXY(this.resolveCell(row, col, hscroll));
1924
+ }
1925
+ this.focusEl.setXY(xy||this.scroller.getXY());
1926
+ },
1927
+
1928
+ ensureVisible : function(row, col, hscroll){
1929
+ var resolved = this.resolveCell(row, col, hscroll);
1930
+ if(!resolved || !resolved.row){
1931
+ return;
1932
+ }
1933
+
1934
+ var rowEl = resolved.row,
1935
+ cellEl = resolved.cell,
1936
+ c = this.scroller.dom,
1937
+ ctop = 0,
1938
+ p = rowEl,
1939
+ stop = this.el.dom;
1940
+
1941
+ while(p && p != stop){
1942
+ ctop += p.offsetTop;
1943
+ p = p.offsetParent;
1944
+ }
1945
+ ctop -= this.mainHd.dom.offsetHeight;
1946
+
1947
+ var cbot = ctop + rowEl.offsetHeight,
1948
+ ch = c.clientHeight,
1949
+ sbot = stop + ch;
1950
+
1951
+ stop = parseInt(c.scrollTop, 10);
1952
+
1953
+
1954
+ if(ctop < stop){
1955
+ c.scrollTop = ctop;
1956
+ }else if(cbot > sbot){
1957
+ c.scrollTop = cbot-ch;
1958
+ }
1959
+
1960
+ if(hscroll !== false){
1961
+ var cleft = parseInt(cellEl.offsetLeft, 10);
1962
+ var cright = cleft + cellEl.offsetWidth;
1963
+
1964
+ var sleft = parseInt(c.scrollLeft, 10);
1965
+ var sright = sleft + c.clientWidth;
1966
+ if(cleft < sleft){
1967
+ c.scrollLeft = cleft;
1968
+ }else if(cright > sright){
1969
+ c.scrollLeft = cright-c.clientWidth;
1970
+ }
1971
+ }
1972
+ return this.getResolvedXY(resolved);
1973
+ },
1974
+
1975
+ // private
1976
+ insertRows : function(dm, firstRow, lastRow, isUpdate){
1977
+ var last = dm.getCount() - 1;
1978
+ if(!isUpdate && firstRow === 0 && lastRow >= last){
1979
+ this.refresh();
1980
+ }else{
1981
+ if(!isUpdate){
1982
+ this.fireEvent("beforerowsinserted", this, firstRow, lastRow);
1983
+ }
1984
+ var html = this.renderRows(firstRow, lastRow),
1985
+ before = this.getRow(firstRow);
1986
+ if(before){
1987
+ if(firstRow === 0){
1988
+ Ext.fly(this.getRow(0)).removeClass(this.firstRowCls);
1989
+ }
1990
+ Ext.DomHelper.insertHtml('beforeBegin', before, html);
1991
+ }else{
1992
+ var r = this.getRow(last - 1);
1993
+ if(r){
1994
+ Ext.fly(r).removeClass(this.lastRowCls);
1995
+ }
1996
+ Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html);
1997
+ }
1998
+ if(!isUpdate){
1999
+ this.fireEvent("rowsinserted", this, firstRow, lastRow);
2000
+ this.processRows(firstRow);
2001
+ }else if(firstRow === 0 || firstRow >= last){
2002
+ //ensure first/last row is kept after an update.
2003
+ Ext.fly(this.getRow(firstRow)).addClass(firstRow === 0 ? this.firstRowCls : this.lastRowCls);
2004
+ }
2005
+ }
2006
+ this.syncFocusEl(firstRow);
2007
+ },
2008
+
2009
+ // private
2010
+ deleteRows : function(dm, firstRow, lastRow){
2011
+ if(dm.getRowCount()<1){
2012
+ this.refresh();
2013
+ }else{
2014
+ this.fireEvent("beforerowsdeleted", this, firstRow, lastRow);
2015
+
2016
+ this.removeRows(firstRow, lastRow);
2017
+
2018
+ this.processRows(firstRow);
2019
+ this.fireEvent("rowsdeleted", this, firstRow, lastRow);
2020
+ }
2021
+ },
2022
+
2023
+ // private
2024
+ getColumnStyle : function(col, isHeader){
2025
+ var style = !isHeader ? (this.cm.config[col].css || '') : '';
2026
+ style += 'width:'+this.getColumnWidth(col)+';';
2027
+ if(this.cm.isHidden(col)){
2028
+ style += 'display:none;';
2029
+ }
2030
+ var align = this.cm.config[col].align;
2031
+ if(align){
2032
+ style += 'text-align:'+align+';';
2033
+ }
2034
+ return style;
2035
+ },
2036
+
2037
+ // private
2038
+ getColumnWidth : function(col){
2039
+ var w = this.cm.getColumnWidth(col);
2040
+ if(typeof w == 'number'){
2041
+ return (Ext.isBorderBox ? w : (w-this.borderWidth > 0 ? w-this.borderWidth:0)) + 'px';
2042
+ }
2043
+ return w;
2044
+ },
2045
+
2046
+ // private
2047
+ getTotalWidth : function(){
2048
+ return this.cm.getTotalWidth()+'px';
2049
+ },
2050
+
2051
+ // private
2052
+ fitColumns : function(preventRefresh, onlyExpand, omitColumn){
2053
+ var cm = this.cm, i;
2054
+ var tw = cm.getTotalWidth(false);
2055
+ var aw = this.grid.getGridEl().getWidth(true)-this.scrollOffset;
2056
+
2057
+ if(aw < 20){ // not initialized, so don't screw up the default widths
2058
+ return;
2059
+ }
2060
+ var extra = aw - tw;
2061
+
2062
+ if(extra === 0){
2063
+ return false;
2064
+ }
2065
+
2066
+ var vc = cm.getColumnCount(true);
2067
+ var ac = vc-(typeof omitColumn == 'number' ? 1 : 0);
2068
+ if(ac === 0){
2069
+ ac = 1;
2070
+ omitColumn = undefined;
2071
+ }
2072
+ var colCount = cm.getColumnCount();
2073
+ var cols = [];
2074
+ var extraCol = 0;
2075
+ var width = 0;
2076
+ var w;
2077
+ for (i = 0; i < colCount; i++){
2078
+ if(!cm.isHidden(i) && !cm.isFixed(i) && i !== omitColumn){
2079
+ w = cm.getColumnWidth(i);
2080
+ cols.push(i);
2081
+ extraCol = i;
2082
+ cols.push(w);
2083
+ width += w;
2084
+ }
2085
+ }
2086
+ var frac = (aw - cm.getTotalWidth())/width;
2087
+ while (cols.length){
2088
+ w = cols.pop();
2089
+ i = cols.pop();
2090
+ cm.setColumnWidth(i, Math.max(this.grid.minColumnWidth, Math.floor(w + w*frac)), true);
2091
+ }
2092
+
2093
+ if((tw = cm.getTotalWidth(false)) > aw){
2094
+ var adjustCol = ac != vc ? omitColumn : extraCol;
2095
+ cm.setColumnWidth(adjustCol, Math.max(1,
2096
+ cm.getColumnWidth(adjustCol)- (tw-aw)), true);
2097
+ }
2098
+
2099
+ if(preventRefresh !== true){
2100
+ this.updateAllColumnWidths();
2101
+ }
2102
+
2103
+
2104
+ return true;
2105
+ },
2106
+
2107
+ // private
2108
+ autoExpand : function(preventUpdate){
2109
+ var g = this.grid, cm = this.cm;
2110
+ if(!this.userResized && g.autoExpandColumn){
2111
+ var tw = cm.getTotalWidth(false);
2112
+ var aw = this.grid.getGridEl().getWidth(true)-this.scrollOffset;
2113
+ if(tw != aw){
2114
+ var ci = cm.getIndexById(g.autoExpandColumn);
2115
+ var currentWidth = cm.getColumnWidth(ci);
2116
+ var cw = Math.min(Math.max(((aw-tw)+currentWidth), g.autoExpandMin), g.autoExpandMax);
2117
+ if(cw != currentWidth){
2118
+ cm.setColumnWidth(ci, cw, true);
2119
+ if(preventUpdate !== true){
2120
+ this.updateColumnWidth(ci, cw);
2121
+ }
2122
+ }
2123
+ }
2124
+ }
2125
+ },
2126
+
2127
+ // private
2128
+ getColumnData : function(){
2129
+ // build a map for all the columns
2130
+ var cs = [], cm = this.cm, colCount = cm.getColumnCount();
2131
+ for(var i = 0; i < colCount; i++){
2132
+ var name = cm.getDataIndex(i);
2133
+ cs[i] = {
2134
+ name : (typeof name == 'undefined' ? this.ds.fields.get(i).name : name),
2135
+ renderer : cm.getRenderer(i),
2136
+ id : cm.getColumnId(i),
2137
+ style : this.getColumnStyle(i)
2138
+ };
2139
+ }
2140
+ return cs;
2141
+ },
2142
+
2143
+ // private
2144
+ renderRows : function(startRow, endRow){
2145
+ // pull in all the crap needed to render rows
2146
+ var g = this.grid, cm = g.colModel, ds = g.store, stripe = g.stripeRows;
2147
+ var colCount = cm.getColumnCount();
2148
+
2149
+ if(ds.getCount() < 1){
2150
+ return "";
2151
+ }
2152
+
2153
+ var cs = this.getColumnData();
2154
+
2155
+ startRow = startRow || 0;
2156
+ endRow = typeof endRow == "undefined"? ds.getCount()-1 : endRow;
2157
+
2158
+ // records to render
2159
+ var rs = ds.getRange(startRow, endRow);
2160
+
2161
+ return this.doRender(cs, rs, ds, startRow, colCount, stripe);
2162
+ },
2163
+
2164
+ // private
2165
+ renderBody : function(){
2166
+ var markup = this.renderRows() || '&#160;';
2167
+ return this.templates.body.apply({rows: markup});
2168
+ },
2169
+
2170
+ // private
2171
+ refreshRow : function(record){
2172
+ var ds = this.ds, index;
2173
+ if(typeof record == 'number'){
2174
+ index = record;
2175
+ record = ds.getAt(index);
2176
+ if(!record){
2177
+ return;
2178
+ }
2179
+ }else{
2180
+ index = ds.indexOf(record);
2181
+ if(index < 0){
2182
+ return;
2183
+ }
2184
+ }
2185
+ this.insertRows(ds, index, index, true);
2186
+ this.getRow(index).rowIndex = index;
2187
+ this.onRemove(ds, record, index+1, true);
2188
+ this.fireEvent("rowupdated", this, index, record);
2189
+ },
2190
+
2191
+ /**
2192
+ * Refreshs the grid UI
2193
+ * @param {Boolean} headersToo (optional) True to also refresh the headers
2194
+ */
2195
+ refresh : function(headersToo){
2196
+ this.fireEvent("beforerefresh", this);
2197
+ this.grid.stopEditing(true);
2198
+
2199
+ var result = this.renderBody();
2200
+ this.mainBody.update(result).setWidth(this.getTotalWidth());
2201
+ if(headersToo === true){
2202
+ this.updateHeaders();
2203
+ this.updateHeaderSortState();
2204
+ }
2205
+ this.processRows(0, true);
2206
+ this.layout();
2207
+ this.applyEmptyText();
2208
+ this.fireEvent("refresh", this);
2209
+ },
2210
+
2211
+ // private
2212
+ applyEmptyText : function(){
2213
+ if(this.emptyText && !this.hasRows()){
2214
+ this.mainBody.update('<div class="x-grid-empty">' + this.emptyText + '</div>');
2215
+ }
2216
+ },
2217
+
2218
+ // private
2219
+ updateHeaderSortState : function(){
2220
+ var state = this.ds.getSortState();
2221
+ if(!state){
2222
+ return;
2223
+ }
2224
+ if(!this.sortState || (this.sortState.field != state.field || this.sortState.direction != state.direction)){
2225
+ this.grid.fireEvent('sortchange', this.grid, state);
2226
+ }
2227
+ this.sortState = state;
2228
+ var sortColumn = this.cm.findColumnIndex(state.field);
2229
+ if(sortColumn != -1){
2230
+ var sortDir = state.direction;
2231
+ this.updateSortIcon(sortColumn, sortDir);
2232
+ }
2233
+ },
2234
+
2235
+ // private
2236
+ destroy : function(){
2237
+ if(this.colMenu){
2238
+ Ext.menu.MenuMgr.unregister(this.colMenu);
2239
+ this.colMenu.destroy();
2240
+ delete this.colMenu;
2241
+ }
2242
+ if(this.hmenu){
2243
+ Ext.menu.MenuMgr.unregister(this.hmenu);
2244
+ this.hmenu.destroy();
2245
+ delete this.hmenu;
2246
+ }
2247
+ if(this.grid.enableColumnMove){
2248
+ var dds = Ext.dd.DDM.ids['gridHeader' + this.grid.getGridEl().id];
2249
+ if(dds){
2250
+ for(var dd in dds){
2251
+ if(!dds[dd].config.isTarget && dds[dd].dragElId){
2252
+ var elid = dds[dd].dragElId;
2253
+ dds[dd].unreg();
2254
+ Ext.get(elid).remove();
2255
+ } else if(dds[dd].config.isTarget){
2256
+ dds[dd].proxyTop.remove();
2257
+ dds[dd].proxyBottom.remove();
2258
+ dds[dd].unreg();
2259
+ }
2260
+ if(Ext.dd.DDM.locationCache[dd]){
2261
+ delete Ext.dd.DDM.locationCache[dd];
2262
+ }
2263
+ }
2264
+ delete Ext.dd.DDM.ids['gridHeader' + this.grid.getGridEl().id];
2265
+ }
2266
+ }
2267
+
2268
+ if(this.dragZone){
2269
+ this.dragZone.unreg();
2270
+ }
2271
+
2272
+ Ext.fly(this.innerHd).removeAllListeners();
2273
+ Ext.removeNode(this.innerHd);
2274
+
2275
+ Ext.destroy(this.resizeMarker, this.resizeProxy, this.focusEl, this.mainBody,
2276
+ this.scroller, this.mainHd, this.mainWrap, this.dragZone,
2277
+ this.splitZone, this.columnDrag, this.columnDrop);
2278
+
2279
+ this.initData(null, null);
2280
+ Ext.EventManager.removeResizeListener(this.onWindowResize, this);
2281
+ this.purgeListeners();
2282
+ },
2283
+
2284
+ // private
2285
+ onDenyColumnHide : function(){
2286
+
2287
+ },
2288
+
2289
+ // private
2290
+ render : function(){
2291
+ if(this.autoFill){
2292
+ var ct = this.grid.ownerCt;
2293
+ if (ct && ct.getLayout()){
2294
+ ct.on('afterlayout', function(){
2295
+ this.fitColumns(true, true);
2296
+ this.updateHeaders();
2297
+ }, this, {single: true});
2298
+ }else{
2299
+ this.fitColumns(true, true);
2300
+ }
2301
+ }else if(this.forceFit){
2302
+ this.fitColumns(true, false);
2303
+ }else if(this.grid.autoExpandColumn){
2304
+ this.autoExpand(true);
2305
+ }
2306
+
2307
+ this.renderUI();
2308
+ },
2309
+
2310
+ /* --------------------------------- Model Events and Handlers --------------------------------*/
2311
+ // private
2312
+ initData : function(ds, cm){
2313
+ if(this.ds){
2314
+ this.ds.un("load", this.onLoad, this);
2315
+ this.ds.un("datachanged", this.onDataChange, this);
2316
+ this.ds.un("add", this.onAdd, this);
2317
+ this.ds.un("remove", this.onRemove, this);
2318
+ this.ds.un("update", this.onUpdate, this);
2319
+ this.ds.un("clear", this.onClear, this);
2320
+ if(this.ds !== ds && this.ds.autoDestroy){
2321
+ this.ds.destroy();
2322
+ }
2323
+ }
2324
+ if(ds){
2325
+ ds.on({
2326
+ scope: this,
2327
+ load: this.onLoad,
2328
+ datachanged: this.onDataChange,
2329
+ add: this.onAdd,
2330
+ remove: this.onRemove,
2331
+ update: this.onUpdate,
2332
+ clear: this.onClear
2333
+ });
2334
+ }
2335
+ this.ds = ds;
2336
+
2337
+ if(this.cm){
2338
+ this.cm.un("configchange", this.onColConfigChange, this);
2339
+ this.cm.un("widthchange", this.onColWidthChange, this);
2340
+ this.cm.un("headerchange", this.onHeaderChange, this);
2341
+ this.cm.un("hiddenchange", this.onHiddenChange, this);
2342
+ this.cm.un("columnmoved", this.onColumnMove, this);
2343
+ }
2344
+ if(cm){
2345
+ delete this.lastViewWidth;
2346
+ cm.on({
2347
+ scope: this,
2348
+ configchange: this.onColConfigChange,
2349
+ widthchange: this.onColWidthChange,
2350
+ headerchange: this.onHeaderChange,
2351
+ hiddenchange: this.onHiddenChange,
2352
+ columnmoved: this.onColumnMove
2353
+ });
2354
+ }
2355
+ this.cm = cm;
2356
+ },
2357
+
2358
+ // private
2359
+ onDataChange : function(){
2360
+ this.refresh();
2361
+ this.updateHeaderSortState();
2362
+ this.syncFocusEl(0);
2363
+ },
2364
+
2365
+ // private
2366
+ onClear : function(){
2367
+ this.refresh();
2368
+ this.syncFocusEl(0);
2369
+ },
2370
+
2371
+ // private
2372
+ onUpdate : function(ds, record){
2373
+ this.refreshRow(record);
2374
+ },
2375
+
2376
+ // private
2377
+ onAdd : function(ds, records, index){
2378
+ this.insertRows(ds, index, index + (records.length-1));
2379
+ },
2380
+
2381
+ // private
2382
+ onRemove : function(ds, record, index, isUpdate){
2383
+ if(isUpdate !== true){
2384
+ this.fireEvent("beforerowremoved", this, index, record);
2385
+ }
2386
+ this.removeRow(index);
2387
+ if(isUpdate !== true){
2388
+ this.processRows(index);
2389
+ this.applyEmptyText();
2390
+ this.fireEvent("rowremoved", this, index, record);
2391
+ }
2392
+ },
2393
+
2394
+ // private
2395
+ onLoad : function(){
2396
+ this.scrollToTop();
2397
+ },
2398
+
2399
+ // private
2400
+ onColWidthChange : function(cm, col, width){
2401
+ this.updateColumnWidth(col, width);
2402
+ },
2403
+
2404
+ // private
2405
+ onHeaderChange : function(cm, col, text){
2406
+ this.updateHeaders();
2407
+ },
2408
+
2409
+ // private
2410
+ onHiddenChange : function(cm, col, hidden){
2411
+ this.updateColumnHidden(col, hidden);
2412
+ },
2413
+
2414
+ // private
2415
+ onColumnMove : function(cm, oldIndex, newIndex){
2416
+ this.indexMap = null;
2417
+ var s = this.getScrollState();
2418
+ this.refresh(true);
2419
+ this.restoreScroll(s);
2420
+ this.afterMove(newIndex);
2421
+ this.grid.fireEvent('columnmove', oldIndex, newIndex);
2422
+ },
2423
+
2424
+ // private
2425
+ onColConfigChange : function(){
2426
+ delete this.lastViewWidth;
2427
+ this.indexMap = null;
2428
+ this.refresh(true);
2429
+ },
2430
+
2431
+ /* -------------------- UI Events and Handlers ------------------------------ */
2432
+ // private
2433
+ initUI : function(grid){
2434
+ grid.on("headerclick", this.onHeaderClick, this);
2435
+ },
2436
+
2437
+ // private
2438
+ initEvents : function(){
2439
+ },
2440
+
2441
+ // private
2442
+ onHeaderClick : function(g, index){
2443
+ if(this.headersDisabled || !this.cm.isSortable(index)){
2444
+ return;
2445
+ }
2446
+ g.stopEditing(true);
2447
+ g.store.sort(this.cm.getDataIndex(index));
2448
+ },
2449
+
2450
+ // private
2451
+ onRowOver : function(e, t){
2452
+ var row;
2453
+ if((row = this.findRowIndex(t)) !== false){
2454
+ this.addRowClass(row, "x-grid3-row-over");
2455
+ }
2456
+ },
2457
+
2458
+ // private
2459
+ onRowOut : function(e, t){
2460
+ var row;
2461
+ if((row = this.findRowIndex(t)) !== false && !e.within(this.getRow(row), true)){
2462
+ this.removeRowClass(row, "x-grid3-row-over");
2463
+ }
2464
+ },
2465
+
2466
+ // private
2467
+ handleWheel : function(e){
2468
+ e.stopPropagation();
2469
+ },
2470
+
2471
+ // private
2472
+ onRowSelect : function(row){
2473
+ this.addRowClass(row, this.selectedRowClass);
2474
+ },
2475
+
2476
+ // private
2477
+ onRowDeselect : function(row){
2478
+ this.removeRowClass(row, this.selectedRowClass);
2479
+ },
2480
+
2481
+ // private
2482
+ onCellSelect : function(row, col){
2483
+ var cell = this.getCell(row, col);
2484
+ if(cell){
2485
+ this.fly(cell).addClass("x-grid3-cell-selected");
2486
+ }
2487
+ },
2488
+
2489
+ // private
2490
+ onCellDeselect : function(row, col){
2491
+ var cell = this.getCell(row, col);
2492
+ if(cell){
2493
+ this.fly(cell).removeClass("x-grid3-cell-selected");
2494
+ }
2495
+ },
2496
+
2497
+ // private
2498
+ onColumnSplitterMoved : function(i, w){
2499
+ this.userResized = true;
2500
+ var cm = this.grid.colModel;
2501
+ cm.setColumnWidth(i, w, true);
2502
+
2503
+ if(this.forceFit){
2504
+ this.fitColumns(true, false, i);
2505
+ this.updateAllColumnWidths();
2506
+ }else{
2507
+ this.updateColumnWidth(i, w);
2508
+ this.syncHeaderScroll();
2509
+ }
2510
+
2511
+ this.grid.fireEvent("columnresize", i, w);
2512
+ },
2513
+
2514
+ // private
2515
+ handleHdMenuClick : function(item){
2516
+ var index = this.hdCtxIndex;
2517
+ var cm = this.cm, ds = this.ds;
2518
+ switch(item.itemId){
2519
+ case "asc":
2520
+ ds.sort(cm.getDataIndex(index), "ASC");
2521
+ break;
2522
+ case "desc":
2523
+ ds.sort(cm.getDataIndex(index), "DESC");
2524
+ break;
2525
+ default:
2526
+ index = cm.getIndexById(item.itemId.substr(4));
2527
+ if(index != -1){
2528
+ if(item.checked && cm.getColumnsBy(this.isHideableColumn, this).length <= 1){
2529
+ this.onDenyColumnHide();
2530
+ return false;
2531
+ }
2532
+ cm.setHidden(index, item.checked);
2533
+ }
2534
+ }
2535
+ return true;
2536
+ },
2537
+
2538
+ // private
2539
+ isHideableColumn : function(c){
2540
+ return !c.hidden && !c.fixed;
2541
+ },
2542
+
2543
+ // private
2544
+ beforeColMenuShow : function(){
2545
+ var cm = this.cm, colCount = cm.getColumnCount();
2546
+ this.colMenu.removeAll();
2547
+ for(var i = 0; i < colCount; i++){
2548
+ if(cm.config[i].fixed !== true && cm.config[i].hideable !== false){
2549
+ this.colMenu.add(new Ext.menu.CheckItem({
2550
+ itemId: "col-"+cm.getColumnId(i),
2551
+ text: cm.getColumnHeader(i),
2552
+ checked: !cm.isHidden(i),
2553
+ hideOnClick:false,
2554
+ disabled: cm.config[i].hideable === false
2555
+ }));
2556
+ }
2557
+ }
2558
+ },
2559
+
2560
+ // private
2561
+ handleHdDown : function(e, t){
2562
+ if(Ext.fly(t).hasClass('x-grid3-hd-btn')){
2563
+ e.stopEvent();
2564
+ var hd = this.findHeaderCell(t);
2565
+ Ext.fly(hd).addClass('x-grid3-hd-menu-open');
2566
+ var index = this.getCellIndex(hd);
2567
+ this.hdCtxIndex = index;
2568
+ var ms = this.hmenu.items, cm = this.cm;
2569
+ ms.get("asc").setDisabled(!cm.isSortable(index));
2570
+ ms.get("desc").setDisabled(!cm.isSortable(index));
2571
+ this.hmenu.on("hide", function(){
2572
+ Ext.fly(hd).removeClass('x-grid3-hd-menu-open');
2573
+ }, this, {single:true});
2574
+ this.hmenu.show(t, "tl-bl?");
2575
+ }
2576
+ },
2577
+
2578
+ // private
2579
+ handleHdOver : function(e, t){
2580
+ var hd = this.findHeaderCell(t);
2581
+ if(hd && !this.headersDisabled){
2582
+ this.activeHd = hd;
2583
+ this.activeHdIndex = this.getCellIndex(hd);
2584
+ var fly = this.fly(hd);
2585
+ this.activeHdRegion = fly.getRegion();
2586
+ if(!this.cm.isMenuDisabled(this.activeHdIndex)){
2587
+ fly.addClass("x-grid3-hd-over");
2588
+ this.activeHdBtn = fly.child('.x-grid3-hd-btn');
2589
+ if(this.activeHdBtn){
2590
+ this.activeHdBtn.dom.style.height = (hd.firstChild.offsetHeight-1)+'px';
2591
+ }
2592
+ }
2593
+ }
2594
+ },
2595
+
2596
+ // private
2597
+ handleHdMove : function(e, t){
2598
+ if(this.activeHd && !this.headersDisabled){
2599
+ var hw = this.splitHandleWidth || 5;
2600
+ var r = this.activeHdRegion;
2601
+ var x = e.getPageX();
2602
+ var ss = this.activeHd.style;
2603
+ if(x - r.left <= hw && this.cm.isResizable(this.activeHdIndex-1)){
2604
+ ss.cursor = Ext.isAir ? 'move' : Ext.isWebKit ? 'e-resize' : 'col-resize'; // col-resize not always supported
2605
+ }else if(r.right - x <= (!this.activeHdBtn ? hw : 2) && this.cm.isResizable(this.activeHdIndex)){
2606
+ ss.cursor = Ext.isAir ? 'move' : Ext.isWebKit ? 'w-resize' : 'col-resize';
2607
+ }else{
2608
+ ss.cursor = '';
2609
+ }
2610
+ }
2611
+ },
2612
+
2613
+ // private
2614
+ handleHdOut : function(e, t){
2615
+ var hd = this.findHeaderCell(t);
2616
+ if(hd && (!Ext.isIE || !e.within(hd, true))){
2617
+ this.activeHd = null;
2618
+ this.fly(hd).removeClass("x-grid3-hd-over");
2619
+ hd.style.cursor = '';
2620
+ }
2621
+ },
2622
+
2623
+ // private
2624
+ hasRows : function(){
2625
+ var fc = this.mainBody.dom.firstChild;
2626
+ return fc && fc.nodeType == 1 && fc.className != 'x-grid-empty';
2627
+ },
2628
+
2629
+ // back compat
2630
+ bind : function(d, c){
2631
+ this.initData(d, c);
2632
+ }
2633
+ });
2634
+
2635
+
2636
+ // private
2637
+ // This is a support class used internally by the Grid components
2638
+ Ext.grid.GridView.SplitDragZone = function(grid, hd){
2639
+ this.grid = grid;
2640
+ this.view = grid.getView();
2641
+ this.marker = this.view.resizeMarker;
2642
+ this.proxy = this.view.resizeProxy;
2643
+ Ext.grid.GridView.SplitDragZone.superclass.constructor.call(this, hd,
2644
+ "gridSplitters" + this.grid.getGridEl().id, {
2645
+ dragElId : Ext.id(this.proxy.dom), resizeFrame:false
2646
+ });
2647
+ this.scroll = false;
2648
+ this.hw = this.view.splitHandleWidth || 5;
2649
+ };
2650
+ Ext.extend(Ext.grid.GridView.SplitDragZone, Ext.dd.DDProxy, {
2651
+
2652
+ b4StartDrag : function(x, y){
2653
+ this.view.headersDisabled = true;
2654
+ var h = this.view.mainWrap.getHeight();
2655
+ this.marker.setHeight(h);
2656
+ this.marker.show();
2657
+ this.marker.alignTo(this.view.getHeaderCell(this.cellIndex), 'tl-tl', [-2, 0]);
2658
+ this.proxy.setHeight(h);
2659
+ var w = this.cm.getColumnWidth(this.cellIndex);
2660
+ var minw = Math.max(w-this.grid.minColumnWidth, 0);
2661
+ this.resetConstraints();
2662
+ this.setXConstraint(minw, 1000);
2663
+ this.setYConstraint(0, 0);
2664
+ this.minX = x - minw;
2665
+ this.maxX = x + 1000;
2666
+ this.startPos = x;
2667
+ Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
2668
+ },
2669
+
2670
+
2671
+ handleMouseDown : function(e){
2672
+ var t = this.view.findHeaderCell(e.getTarget());
2673
+ if(t){
2674
+ var xy = this.view.fly(t).getXY(), x = xy[0], y = xy[1];
2675
+ var exy = e.getXY(), ex = exy[0];
2676
+ var w = t.offsetWidth, adjust = false;
2677
+ if((ex - x) <= this.hw){
2678
+ adjust = -1;
2679
+ }else if((x+w) - ex <= this.hw){
2680
+ adjust = 0;
2681
+ }
2682
+ if(adjust !== false){
2683
+ this.cm = this.grid.colModel;
2684
+ var ci = this.view.getCellIndex(t);
2685
+ if(adjust == -1){
2686
+ if (ci + adjust < 0) {
2687
+ return;
2688
+ }
2689
+ while(this.cm.isHidden(ci+adjust)){
2690
+ --adjust;
2691
+ if(ci+adjust < 0){
2692
+ return;
2693
+ }
2694
+ }
2695
+ }
2696
+ this.cellIndex = ci+adjust;
2697
+ this.split = t.dom;
2698
+ if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){
2699
+ Ext.grid.GridView.SplitDragZone.superclass.handleMouseDown.apply(this, arguments);
2700
+ }
2701
+ }else if(this.view.columnDrag){
2702
+ this.view.columnDrag.callHandleMouseDown(e);
2703
+ }
2704
+ }
2705
+ },
2706
+
2707
+ endDrag : function(e){
2708
+ this.marker.hide();
2709
+ var v = this.view;
2710
+ var endX = Math.max(this.minX, e.getPageX());
2711
+ var diff = endX - this.startPos;
2712
+ v.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
2713
+ setTimeout(function(){
2714
+ v.headersDisabled = false;
2715
+ }, 50);
2716
+ },
2717
+
2718
+ autoOffset : function(){
2719
+ this.setDelta(0,0);
2720
+ }
2721
+ });
2722
+ // private
2723
+ // This is a support class used internally by the Grid components
2724
+ Ext.grid.HeaderDragZone = function(grid, hd, hd2){
2725
+ this.grid = grid;
2726
+ this.view = grid.getView();
2727
+ this.ddGroup = "gridHeader" + this.grid.getGridEl().id;
2728
+ Ext.grid.HeaderDragZone.superclass.constructor.call(this, hd);
2729
+ if(hd2){
2730
+ this.setHandleElId(Ext.id(hd));
2731
+ this.setOuterHandleElId(Ext.id(hd2));
2732
+ }
2733
+ this.scroll = false;
2734
+ };
2735
+ Ext.extend(Ext.grid.HeaderDragZone, Ext.dd.DragZone, {
2736
+ maxDragWidth: 120,
2737
+ getDragData : function(e){
2738
+ var t = Ext.lib.Event.getTarget(e);
2739
+ var h = this.view.findHeaderCell(t);
2740
+ if(h){
2741
+ return {ddel: h.firstChild, header:h};
2742
+ }
2743
+ return false;
2744
+ },
2745
+
2746
+ onInitDrag : function(e){
2747
+ this.view.headersDisabled = true;
2748
+ var clone = this.dragData.ddel.cloneNode(true);
2749
+ clone.id = Ext.id();
2750
+ clone.style.width = Math.min(this.dragData.header.offsetWidth,this.maxDragWidth) + "px";
2751
+ this.proxy.update(clone);
2752
+ return true;
2753
+ },
2754
+
2755
+ afterValidDrop : function(){
2756
+ var v = this.view;
2757
+ setTimeout(function(){
2758
+ v.headersDisabled = false;
2759
+ }, 50);
2760
+ },
2761
+
2762
+ afterInvalidDrop : function(){
2763
+ var v = this.view;
2764
+ setTimeout(function(){
2765
+ v.headersDisabled = false;
2766
+ }, 50);
2767
+ }
2768
+ });
2769
+
2770
+ // private
2771
+ // This is a support class used internally by the Grid components
2772
+ Ext.grid.HeaderDropZone = function(grid, hd, hd2){
2773
+ this.grid = grid;
2774
+ this.view = grid.getView();
2775
+ // split the proxies so they don't interfere with mouse events
2776
+ this.proxyTop = Ext.DomHelper.append(document.body, {
2777
+ cls:"col-move-top", html:"&#160;"
2778
+ }, true);
2779
+ this.proxyBottom = Ext.DomHelper.append(document.body, {
2780
+ cls:"col-move-bottom", html:"&#160;"
2781
+ }, true);
2782
+ this.proxyTop.hide = this.proxyBottom.hide = function(){
2783
+ this.setLeftTop(-100,-100);
2784
+ this.setStyle("visibility", "hidden");
2785
+ };
2786
+ this.ddGroup = "gridHeader" + this.grid.getGridEl().id;
2787
+ // temporarily disabled
2788
+ //Ext.dd.ScrollManager.register(this.view.scroller.dom);
2789
+ Ext.grid.HeaderDropZone.superclass.constructor.call(this, grid.getGridEl().dom);
2790
+ };
2791
+ Ext.extend(Ext.grid.HeaderDropZone, Ext.dd.DropZone, {
2792
+ proxyOffsets : [-4, -9],
2793
+ fly: Ext.Element.fly,
2794
+
2795
+ getTargetFromEvent : function(e){
2796
+ var t = Ext.lib.Event.getTarget(e);
2797
+ var cindex = this.view.findCellIndex(t);
2798
+ if(cindex !== false){
2799
+ return this.view.getHeaderCell(cindex);
2800
+ }
2801
+ },
2802
+
2803
+ nextVisible : function(h){
2804
+ var v = this.view, cm = this.grid.colModel;
2805
+ h = h.nextSibling;
2806
+ while(h){
2807
+ if(!cm.isHidden(v.getCellIndex(h))){
2808
+ return h;
2809
+ }
2810
+ h = h.nextSibling;
2811
+ }
2812
+ return null;
2813
+ },
2814
+
2815
+ prevVisible : function(h){
2816
+ var v = this.view, cm = this.grid.colModel;
2817
+ h = h.prevSibling;
2818
+ while(h){
2819
+ if(!cm.isHidden(v.getCellIndex(h))){
2820
+ return h;
2821
+ }
2822
+ h = h.prevSibling;
2823
+ }
2824
+ return null;
2825
+ },
2826
+
2827
+ positionIndicator : function(h, n, e){
2828
+ var x = Ext.lib.Event.getPageX(e);
2829
+ var r = Ext.lib.Dom.getRegion(n.firstChild);
2830
+ var px, pt, py = r.top + this.proxyOffsets[1];
2831
+ if((r.right - x) <= (r.right-r.left)/2){
2832
+ px = r.right+this.view.borderWidth;
2833
+ pt = "after";
2834
+ }else{
2835
+ px = r.left;
2836
+ pt = "before";
2837
+ }
2838
+
2839
+ if(this.grid.colModel.isFixed(this.view.getCellIndex(n))){
2840
+ return false;
2841
+ }
2842
+
2843
+ px += this.proxyOffsets[0];
2844
+ this.proxyTop.setLeftTop(px, py);
2845
+ this.proxyTop.show();
2846
+ if(!this.bottomOffset){
2847
+ this.bottomOffset = this.view.mainHd.getHeight();
2848
+ }
2849
+ this.proxyBottom.setLeftTop(px, py+this.proxyTop.dom.offsetHeight+this.bottomOffset);
2850
+ this.proxyBottom.show();
2851
+ return pt;
2852
+ },
2853
+
2854
+ onNodeEnter : function(n, dd, e, data){
2855
+ if(data.header != n){
2856
+ this.positionIndicator(data.header, n, e);
2857
+ }
2858
+ },
2859
+
2860
+ onNodeOver : function(n, dd, e, data){
2861
+ var result = false;
2862
+ if(data.header != n){
2863
+ result = this.positionIndicator(data.header, n, e);
2864
+ }
2865
+ if(!result){
2866
+ this.proxyTop.hide();
2867
+ this.proxyBottom.hide();
2868
+ }
2869
+ return result ? this.dropAllowed : this.dropNotAllowed;
2870
+ },
2871
+
2872
+ onNodeOut : function(n, dd, e, data){
2873
+ this.proxyTop.hide();
2874
+ this.proxyBottom.hide();
2875
+ },
2876
+
2877
+ onNodeDrop : function(n, dd, e, data){
2878
+ var h = data.header;
2879
+ if(h != n){
2880
+ var cm = this.grid.colModel;
2881
+ var x = Ext.lib.Event.getPageX(e);
2882
+ var r = Ext.lib.Dom.getRegion(n.firstChild);
2883
+ var pt = (r.right - x) <= ((r.right-r.left)/2) ? "after" : "before";
2884
+ var oldIndex = this.view.getCellIndex(h);
2885
+ var newIndex = this.view.getCellIndex(n);
2886
+ if(pt == "after"){
2887
+ newIndex++;
2888
+ }
2889
+ if(oldIndex < newIndex){
2890
+ newIndex--;
2891
+ }
2892
+ cm.moveColumn(oldIndex, newIndex);
2893
+ this.grid.fireEvent("columnmove", oldIndex, newIndex);
2894
+ return true;
2895
+ }
2896
+ return false;
2897
+ }
2898
+ });
2899
+
2900
+
2901
+ Ext.grid.GridView.ColumnDragZone = function(grid, hd){
2902
+ Ext.grid.GridView.ColumnDragZone.superclass.constructor.call(this, grid, hd, null);
2903
+ this.proxy.el.addClass('x-grid3-col-dd');
2904
+ };
2905
+
2906
+ Ext.extend(Ext.grid.GridView.ColumnDragZone, Ext.grid.HeaderDragZone, {
2907
+ handleMouseDown : function(e){
2908
+
2909
+ },
2910
+
2911
+ callHandleMouseDown : function(e){
2912
+ Ext.grid.GridView.ColumnDragZone.superclass.handleMouseDown.call(this, e);
2913
+ }
2914
+ });// private
2915
+ // This is a support class used internally by the Grid components
2916
+ Ext.grid.SplitDragZone = function(grid, hd, hd2){
2917
+ this.grid = grid;
2918
+ this.view = grid.getView();
2919
+ this.proxy = this.view.resizeProxy;
2920
+ Ext.grid.SplitDragZone.superclass.constructor.call(this, hd,
2921
+ "gridSplitters" + this.grid.getGridEl().id, {
2922
+ dragElId : Ext.id(this.proxy.dom), resizeFrame:false
2923
+ });
2924
+ this.setHandleElId(Ext.id(hd));
2925
+ this.setOuterHandleElId(Ext.id(hd2));
2926
+ this.scroll = false;
2927
+ };
2928
+ Ext.extend(Ext.grid.SplitDragZone, Ext.dd.DDProxy, {
2929
+ fly: Ext.Element.fly,
2930
+
2931
+ b4StartDrag : function(x, y){
2932
+ this.view.headersDisabled = true;
2933
+ this.proxy.setHeight(this.view.mainWrap.getHeight());
2934
+ var w = this.cm.getColumnWidth(this.cellIndex);
2935
+ var minw = Math.max(w-this.grid.minColumnWidth, 0);
2936
+ this.resetConstraints();
2937
+ this.setXConstraint(minw, 1000);
2938
+ this.setYConstraint(0, 0);
2939
+ this.minX = x - minw;
2940
+ this.maxX = x + 1000;
2941
+ this.startPos = x;
2942
+ Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
2943
+ },
2944
+
2945
+
2946
+ handleMouseDown : function(e){
2947
+ var ev = Ext.EventObject.setEvent(e);
2948
+ var t = this.fly(ev.getTarget());
2949
+ if(t.hasClass("x-grid-split")){
2950
+ this.cellIndex = this.view.getCellIndex(t.dom);
2951
+ this.split = t.dom;
2952
+ this.cm = this.grid.colModel;
2953
+ if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){
2954
+ Ext.grid.SplitDragZone.superclass.handleMouseDown.apply(this, arguments);
2955
+ }
2956
+ }
2957
+ },
2958
+
2959
+ endDrag : function(e){
2960
+ this.view.headersDisabled = false;
2961
+ var endX = Math.max(this.minX, Ext.lib.Event.getPageX(e));
2962
+ var diff = endX - this.startPos;
2963
+ this.view.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
2964
+ },
2965
+
2966
+ autoOffset : function(){
2967
+ this.setDelta(0,0);
2968
+ }
2969
+ });/**
2970
+ * @class Ext.grid.GridDragZone
2971
+ * @extends Ext.dd.DragZone
2972
+ * <p>A customized implementation of a {@link Ext.dd.DragZone DragZone} which provides default implementations of two of the
2973
+ * template methods of DragZone to enable dragging of the selected rows of a GridPanel.</p>
2974
+ * <p>A cooperating {@link Ext.dd.DropZone DropZone} must be created who's template method implementations of
2975
+ * {@link Ext.dd.DropZone#onNodeEnter onNodeEnter}, {@link Ext.dd.DropZone#onNodeOver onNodeOver},
2976
+ * {@link Ext.dd.DropZone#onNodeOut onNodeOut} and {@link Ext.dd.DropZone#onNodeDrop onNodeDrop}</p> are able
2977
+ * to process the {@link #getDragData data} which is provided.
2978
+ */
2979
+ Ext.grid.GridDragZone = function(grid, config){
2980
+ this.view = grid.getView();
2981
+ Ext.grid.GridDragZone.superclass.constructor.call(this, this.view.mainBody.dom, config);
2982
+ this.scroll = false;
2983
+ this.grid = grid;
2984
+ this.ddel = document.createElement('div');
2985
+ this.ddel.className = 'x-grid-dd-wrap';
2986
+ };
2987
+
2988
+ Ext.extend(Ext.grid.GridDragZone, Ext.dd.DragZone, {
2989
+ ddGroup : "GridDD",
2990
+
2991
+ /**
2992
+ * <p>The provided implementation of the getDragData method which collects the data to be dragged from the GridPanel on mousedown.</p>
2993
+ * <p>This data is available for processing in the {@link Ext.dd.DropZone#onNodeEnter onNodeEnter}, {@link Ext.dd.DropZone#onNodeOver onNodeOver},
2994
+ * {@link Ext.dd.DropZone#onNodeOut onNodeOut} and {@link Ext.dd.DropZone#onNodeDrop onNodeDrop} methods of a cooperating {@link Ext.dd.DropZone DropZone}.</p>
2995
+ * <p>The data object contains the following properties:<ul>
2996
+ * <li><b>grid</b> : Ext.Grid.GridPanel<div class="sub-desc">The GridPanel from which the data is being dragged.</div></li>
2997
+ * <li><b>ddel</b> : htmlElement<div class="sub-desc">An htmlElement which provides the "picture" of the data being dragged.</div></li>
2998
+ * <li><b>rowIndex</b> : Number<div class="sub-desc">The index of the row which receieved the mousedown gesture which triggered the drag.</div></li>
2999
+ * <li><b>selections</b> : Array<div class="sub-desc">An Array of the selected Records which are being dragged from the GridPanel.</div></li>
3000
+ * </ul></p>
3001
+ */
3002
+ getDragData : function(e){
3003
+ var t = Ext.lib.Event.getTarget(e);
3004
+ var rowIndex = this.view.findRowIndex(t);
3005
+ if(rowIndex !== false){
3006
+ var sm = this.grid.selModel;
3007
+ if(!sm.isSelected(rowIndex) || e.hasModifier()){
3008
+ sm.handleMouseDown(this.grid, rowIndex, e);
3009
+ }
3010
+ return {grid: this.grid, ddel: this.ddel, rowIndex: rowIndex, selections:sm.getSelections()};
3011
+ }
3012
+ return false;
3013
+ },
3014
+
3015
+ /**
3016
+ * <p>The provided implementation of the onInitDrag method. Sets the <tt>innerHTML</tt> of the drag proxy which provides the "picture"
3017
+ * of the data being dragged.</p>
3018
+ * <p>The <tt>innerHTML</tt> data is found by calling the owning GridPanel's {@link Ext.grid.GridPanel#getDragDropText getDragDropText}.</p>
3019
+ */
3020
+ onInitDrag : function(e){
3021
+ var data = this.dragData;
3022
+ this.ddel.innerHTML = this.grid.getDragDropText();
3023
+ this.proxy.update(this.ddel);
3024
+ // fire start drag?
3025
+ },
3026
+
3027
+ /**
3028
+ * An empty immplementation. Implement this to provide behaviour after a repair of an invalid drop. An implementation might highlight
3029
+ * the selected rows to show that they have not been dragged.
3030
+ */
3031
+ afterRepair : function(){
3032
+ this.dragging = false;
3033
+ },
3034
+
3035
+ /**
3036
+ * <p>An empty implementation. Implement this to provide coordinates for the drag proxy to slide back to after an invalid drop.</p>
3037
+ * <p>Called before a repair of an invalid drop to get the XY to animate to.</p>
3038
+ * @param {EventObject} e The mouse up event
3039
+ * @return {Array} The xy location (e.g. [100, 200])
3040
+ */
3041
+ getRepairXY : function(e, data){
3042
+ return false;
3043
+ },
3044
+
3045
+ onEndDrag : function(data, e){
3046
+ // fire end drag?
3047
+ },
3048
+
3049
+ onValidDrop : function(dd, e, id){
3050
+ // fire drag drop?
3051
+ this.hideProxy();
3052
+ },
3053
+
3054
+ beforeInvalidDrop : function(e, id){
3055
+
3056
+ }
3057
+ });
3058
+ /**
3059
+ * @class Ext.grid.ColumnModel
3060
+ * @extends Ext.util.Observable
3061
+ * <p>After the data has been read into the client side cache (<b>{@link Ext.data.Store Store}</b>),
3062
+ * the ColumnModel is used to configure how and what parts of that data will be displayed in the
3063
+ * vertical slices (columns) of the grid. The Ext.grid.ColumnModel Class is the default implementation
3064
+ * of a ColumnModel used by implentations of {@link Ext.grid.GridPanel GridPanel}.</p>
3065
+ * <p>Data is mapped into the store's records and then indexed into the ColumnModel using the
3066
+ * <tt>{@link Ext.grid.Column#dataIndex dataIndex}</tt>:</p>
3067
+ * <pre><code>
3068
+ {data source} == mapping ==> {data store} == <b><tt>{@link Ext.grid.Column#dataIndex dataIndex}</tt></b> ==> {ColumnModel}
3069
+ * </code></pre>
3070
+ * <p>Each {@link Ext.grid.Column Column} in the grid's ColumnModel is configured with a
3071
+ * <tt>{@link Ext.grid.Column#dataIndex dataIndex}</tt> to specify how the data within
3072
+ * each record in the store is indexed into the ColumnModel.</p>
3073
+ * <p>There are two ways to initialize the ColumnModel class:</p>
3074
+ * <p><u>Initialization Method 1: an Array</u></p>
3075
+ <pre><code>
3076
+ var colModel = new Ext.grid.ColumnModel([
3077
+ { header: "Ticker", width: 60, sortable: true},
3078
+ { header: "Company Name", width: 150, sortable: true, id: 'company'},
3079
+ { header: "Market Cap.", width: 100, sortable: true},
3080
+ { header: "$ Sales", width: 100, sortable: true, renderer: money},
3081
+ { header: "Employees", width: 100, sortable: true, resizable: false}
3082
+ ]);
3083
+ </code></pre>
3084
+ * <p>The ColumnModel may be initialized with an Array of {@link Ext.grid.Column} column configuration
3085
+ * objects to define the initial layout / display of the columns in the Grid. The order of each
3086
+ * {@link Ext.grid.Column} column configuration object within the specified Array defines the initial
3087
+ * order of the column display. A Column's display may be initially hidden using the
3088
+ * <tt>{@link Ext.grid.Column#hidden hidden}</tt></b> config property (and then shown using the column
3089
+ * header menu). Field's that are not included in the ColumnModel will not be displayable at all.</p>
3090
+ * <p>How each column in the grid correlates (maps) to the {@link Ext.data.Record} field in the
3091
+ * {@link Ext.data.Store Store} the column draws its data from is configured through the
3092
+ * <b><tt>{@link Ext.grid.Column#dataIndex dataIndex}</tt></b>. If the
3093
+ * <b><tt>{@link Ext.grid.Column#dataIndex dataIndex}</tt></b> is not explicitly defined (as shown in the
3094
+ * example above) it will use the column configuration's index in the Array as the index.</p>
3095
+ * <p>See <b><tt>{@link Ext.grid.Column}</tt></b> for additional configuration options for each column.</p>
3096
+ * <p><u>Initialization Method 2: an Object</u></p>
3097
+ * <p>In order to use configuration options from <tt>Ext.grid.ColumnModel</tt>, an Object may be used to
3098
+ * initialize the ColumnModel. The column configuration Array will be specified in the <tt><b>{@link #columns}</b></tt>
3099
+ * config property. The <tt><b>{@link #defaults}</b></tt> config property can be used to apply defaults
3100
+ * for all columns, e.g.:</p><pre><code>
3101
+ var colModel = new Ext.grid.ColumnModel({
3102
+ columns: [
3103
+ { header: "Ticker", width: 60, menuDisabled: false},
3104
+ { header: "Company Name", width: 150, id: 'company'},
3105
+ { header: "Market Cap."},
3106
+ { header: "$ Sales", renderer: money},
3107
+ { header: "Employees", resizable: false}
3108
+ ],
3109
+ defaults: {
3110
+ sortable: true,
3111
+ menuDisabled: true,
3112
+ width: 100
3113
+ },
3114
+ listeners: {
3115
+ {@link #hiddenchange}: function(cm, colIndex, hidden) {
3116
+ saveConfig(colIndex, hidden);
3117
+ }
3118
+ }
3119
+ });
3120
+ </code></pre>
3121
+ * <p>In both examples above, the ability to apply a CSS class to all cells in a column (including the
3122
+ * header) is demonstrated through the use of the <b><tt>{@link Ext.grid.Column#id id}</tt></b> config
3123
+ * option. This column could be styled by including the following css:</p><pre><code>
3124
+ //add this css *after* the core css is loaded
3125
+ .x-grid3-td-company {
3126
+ color: red; // entire column will have red font
3127
+ }
3128
+ // modify the header row only, adding an icon to the column header
3129
+ .x-grid3-hd-company {
3130
+ background: transparent
3131
+ url(../../resources/images/icons/silk/building.png)
3132
+ no-repeat 3px 3px ! important;
3133
+ padding-left:20px;
3134
+ }
3135
+ </code></pre>
3136
+ * Note that the "Company Name" column could be specified as the
3137
+ * <b><tt>{@link Ext.grid.GridPanel}.{@link Ext.grid.GridPanel#autoExpandColumn autoExpandColumn}</tt></b>.
3138
+ * @constructor
3139
+ * @param {Mixed} config Specify either an Array of {@link Ext.grid.Column} configuration objects or specify
3140
+ * a configuration Object (see introductory section discussion utilizing Initialization Method 2 above).
3141
+ */
3142
+ Ext.grid.ColumnModel = function(config){
3143
+ /**
3144
+ * An Array of {@link Ext.grid.Column Column definition} objects representing the configuration
3145
+ * of this ColumnModel. See {@link Ext.grid.Column} for the configuration properties that may
3146
+ * be specified.
3147
+ * @property config
3148
+ * @type Array
3149
+ */
3150
+ if(config.columns){
3151
+ Ext.apply(this, config);
3152
+ this.setConfig(config.columns, true);
3153
+ }else{
3154
+ this.setConfig(config, true);
3155
+ }
3156
+ this.addEvents(
3157
+ /**
3158
+ * @event widthchange
3159
+ * Fires when the width of a column is programmaticially changed using
3160
+ * <code>{@link #setColumnWidth}</code>.
3161
+ * Note internal resizing suppresses the event from firing. See also
3162
+ * {@link Ext.grid.GridPanel}.<code>{@link #columnresize}</code>.
3163
+ * @param {ColumnModel} this
3164
+ * @param {Number} columnIndex The column index
3165
+ * @param {Number} newWidth The new width
3166
+ */
3167
+ "widthchange",
3168
+ /**
3169
+ * @event headerchange
3170
+ * Fires when the text of a header changes.
3171
+ * @param {ColumnModel} this
3172
+ * @param {Number} columnIndex The column index
3173
+ * @param {String} newText The new header text
3174
+ */
3175
+ "headerchange",
3176
+ /**
3177
+ * @event hiddenchange
3178
+ * Fires when a column is hidden or "unhidden".
3179
+ * @param {ColumnModel} this
3180
+ * @param {Number} columnIndex The column index
3181
+ * @param {Boolean} hidden true if hidden, false otherwise
3182
+ */
3183
+ "hiddenchange",
3184
+ /**
3185
+ * @event columnmoved
3186
+ * Fires when a column is moved.
3187
+ * @param {ColumnModel} this
3188
+ * @param {Number} oldIndex
3189
+ * @param {Number} newIndex
3190
+ */
3191
+ "columnmoved",
3192
+ /**
3193
+ * @event configchange
3194
+ * Fires when the configuration is changed
3195
+ * @param {ColumnModel} this
3196
+ */
3197
+ "configchange"
3198
+ );
3199
+ Ext.grid.ColumnModel.superclass.constructor.call(this);
3200
+ };
3201
+ Ext.extend(Ext.grid.ColumnModel, Ext.util.Observable, {
3202
+ /**
3203
+ * @cfg {Number} defaultWidth (optional) The width of columns which have no <tt>{@link #width}</tt>
3204
+ * specified (defaults to <tt>100</tt>). This property shall preferably be configured through the
3205
+ * <tt><b>{@link #defaults}</b></tt> config property.
3206
+ */
3207
+ defaultWidth: 100,
3208
+ /**
3209
+ * @cfg {Boolean} defaultSortable (optional) Default sortable of columns which have no
3210
+ * sortable specified (defaults to <tt>false</tt>). This property shall preferably be configured
3211
+ * through the <tt><b>{@link #defaults}</b></tt> config property.
3212
+ */
3213
+ defaultSortable: false,
3214
+ /**
3215
+ * @cfg {Array} columns An Array of object literals. The config options defined by
3216
+ * <b>{@link Ext.grid.Column}</b> are the options which may appear in the object literal for each
3217
+ * individual column definition.
3218
+ */
3219
+ /**
3220
+ * @cfg {Object} defaults Object literal which will be used to apply {@link Ext.grid.Column}
3221
+ * configuration options to all <tt><b>{@link #columns}</b></tt>. Configuration options specified with
3222
+ * individual {@link Ext.grid.Column column} configs will supersede these <tt><b>{@link #defaults}</b></tt>.
3223
+ */
3224
+
3225
+ /**
3226
+ * Returns the id of the column at the specified index.
3227
+ * @param {Number} index The column index
3228
+ * @return {String} the id
3229
+ */
3230
+ getColumnId : function(index){
3231
+ return this.config[index].id;
3232
+ },
3233
+
3234
+ getColumnAt : function(index){
3235
+ return this.config[index];
3236
+ },
3237
+
3238
+ /**
3239
+ * <p>Reconfigures this column model according to the passed Array of column definition objects.
3240
+ * For a description of the individual properties of a column definition object, see the
3241
+ * <a href="#Ext.grid.ColumnModel-configs">Config Options</a>.</p>
3242
+ * <p>Causes the {@link #configchange} event to be fired. A {@link Ext.grid.GridPanel GridPanel}
3243
+ * using this ColumnModel will listen for this event and refresh its UI automatically.</p>
3244
+ * @param {Array} config Array of Column definition objects.
3245
+ * @param {Boolean} initial Specify <tt>true</tt> to bypass cleanup which deletes the <tt>totalWidth</tt>
3246
+ * and destroys existing editors.
3247
+ */
3248
+ setConfig : function(config, initial){
3249
+ var i, c, len;
3250
+ if(!initial){ // cleanup
3251
+ delete this.totalWidth;
3252
+ for(i = 0, len = this.config.length; i < len; i++){
3253
+ c = this.config[i];
3254
+ if(c.editor){
3255
+ c.editor.destroy();
3256
+ }
3257
+ }
3258
+ }
3259
+
3260
+ // backward compatibility
3261
+ this.defaults = Ext.apply({
3262
+ width: this.defaultWidth,
3263
+ sortable: this.defaultSortable
3264
+ }, this.defaults);
3265
+
3266
+ this.config = config;
3267
+ this.lookup = {};
3268
+ // if no id, create one
3269
+ for(i = 0, len = config.length; i < len; i++){
3270
+ c = Ext.applyIf(config[i], this.defaults);
3271
+ if(!c.isColumn){
3272
+ var cls = Ext.grid.Column.types[c.xtype || 'gridcolumn'];
3273
+ c = new cls(c);
3274
+ config[i] = c;
3275
+ }
3276
+ this.lookup[c.id] = c;
3277
+ }
3278
+ if(!initial){
3279
+ this.fireEvent('configchange', this);
3280
+ }
3281
+ },
3282
+
3283
+ /**
3284
+ * Returns the column for a specified id.
3285
+ * @param {String} id The column id
3286
+ * @return {Object} the column
3287
+ */
3288
+ getColumnById : function(id){
3289
+ return this.lookup[id];
3290
+ },
3291
+
3292
+ /**
3293
+ * Returns the index for a specified column id.
3294
+ * @param {String} id The column id
3295
+ * @return {Number} the index, or -1 if not found
3296
+ */
3297
+ getIndexById : function(id){
3298
+ for(var i = 0, len = this.config.length; i < len; i++){
3299
+ if(this.config[i].id == id){
3300
+ return i;
3301
+ }
3302
+ }
3303
+ return -1;
3304
+ },
3305
+
3306
+ /**
3307
+ * Moves a column from one position to another.
3308
+ * @param {Number} oldIndex The index of the column to move.
3309
+ * @param {Number} newIndex The position at which to reinsert the coolumn.
3310
+ */
3311
+ moveColumn : function(oldIndex, newIndex){
3312
+ var c = this.config[oldIndex];
3313
+ this.config.splice(oldIndex, 1);
3314
+ this.config.splice(newIndex, 0, c);
3315
+ this.dataMap = null;
3316
+ this.fireEvent("columnmoved", this, oldIndex, newIndex);
3317
+ },
3318
+
3319
+ /**
3320
+ * Returns the number of columns.
3321
+ * @param {Boolean} visibleOnly Optional. Pass as true to only include visible columns.
3322
+ * @return {Number}
3323
+ */
3324
+ getColumnCount : function(visibleOnly){
3325
+ if(visibleOnly === true){
3326
+ var c = 0;
3327
+ for(var i = 0, len = this.config.length; i < len; i++){
3328
+ if(!this.isHidden(i)){
3329
+ c++;
3330
+ }
3331
+ }
3332
+ return c;
3333
+ }
3334
+ return this.config.length;
3335
+ },
3336
+
3337
+ /**
3338
+ * Returns the column configs that return true by the passed function that is called
3339
+ * with (columnConfig, index)
3340
+ <pre><code>
3341
+ // returns an array of column config objects for all hidden columns
3342
+ var columns = grid.getColumnModel().getColumnsBy(function(c){
3343
+ return c.hidden;
3344
+ });
3345
+ </code></pre>
3346
+ * @param {Function} fn
3347
+ * @param {Object} scope (optional)
3348
+ * @return {Array} result
3349
+ */
3350
+ getColumnsBy : function(fn, scope){
3351
+ var r = [];
3352
+ for(var i = 0, len = this.config.length; i < len; i++){
3353
+ var c = this.config[i];
3354
+ if(fn.call(scope||this, c, i) === true){
3355
+ r[r.length] = c;
3356
+ }
3357
+ }
3358
+ return r;
3359
+ },
3360
+
3361
+ /**
3362
+ * Returns true if the specified column is sortable.
3363
+ * @param {Number} col The column index
3364
+ * @return {Boolean}
3365
+ */
3366
+ isSortable : function(col){
3367
+ return this.config[col].sortable;
3368
+ },
3369
+
3370
+ /**
3371
+ * Returns true if the specified column menu is disabled.
3372
+ * @param {Number} col The column index
3373
+ * @return {Boolean}
3374
+ */
3375
+ isMenuDisabled : function(col){
3376
+ return !!this.config[col].menuDisabled;
3377
+ },
3378
+
3379
+ /**
3380
+ * Returns the rendering (formatting) function defined for the column.
3381
+ * @param {Number} col The column index.
3382
+ * @return {Function} The function used to render the cell. See {@link #setRenderer}.
3383
+ */
3384
+ getRenderer : function(col){
3385
+ if(!this.config[col].renderer){
3386
+ return Ext.grid.ColumnModel.defaultRenderer;
3387
+ }
3388
+ return this.config[col].renderer;
3389
+ },
3390
+
3391
+ /**
3392
+ * Sets the rendering (formatting) function for a column. See {@link Ext.util.Format} for some
3393
+ * default formatting functions.
3394
+ * @param {Number} col The column index
3395
+ * @param {Function} fn The function to use to process the cell's raw data
3396
+ * to return HTML markup for the grid view. The render function is called with
3397
+ * the following parameters:<ul>
3398
+ * <li><b>value</b> : Object<p class="sub-desc">The data value for the cell.</p></li>
3399
+ * <li><b>metadata</b> : Object<p class="sub-desc">An object in which you may set the following attributes:<ul>
3400
+ * <li><b>css</b> : String<p class="sub-desc">A CSS class name to add to the cell's TD element.</p></li>
3401
+ * <li><b>attr</b> : String<p class="sub-desc">An HTML attribute definition string to apply to the data container element <i>within</i> the table cell
3402
+ * (e.g. 'style="color:red;"').</p></li></ul></p></li>
3403
+ * <li><b>record</b> : Ext.data.record<p class="sub-desc">The {@link Ext.data.Record} from which the data was extracted.</p></li>
3404
+ * <li><b>rowIndex</b> : Number<p class="sub-desc">Row index</p></li>
3405
+ * <li><b>colIndex</b> : Number<p class="sub-desc">Column index</p></li>
3406
+ * <li><b>store</b> : Ext.data.Store<p class="sub-desc">The {@link Ext.data.Store} object from which the Record was extracted.</p></li></ul>
3407
+ */
3408
+ setRenderer : function(col, fn){
3409
+ this.config[col].renderer = fn;
3410
+ },
3411
+
3412
+ /**
3413
+ * Returns the width for the specified column.
3414
+ * @param {Number} col The column index
3415
+ * @return {Number}
3416
+ */
3417
+ getColumnWidth : function(col){
3418
+ return this.config[col].width;
3419
+ },
3420
+
3421
+ /**
3422
+ * Sets the width for a column.
3423
+ * @param {Number} col The column index
3424
+ * @param {Number} width The new width
3425
+ * @param {Boolean} suppressEvent True to suppress firing the <code>{@link #widthchange}</code>
3426
+ * event. Defaults to false.
3427
+ */
3428
+ setColumnWidth : function(col, width, suppressEvent){
3429
+ this.config[col].width = width;
3430
+ this.totalWidth = null;
3431
+ if(!suppressEvent){
3432
+ this.fireEvent("widthchange", this, col, width);
3433
+ }
3434
+ },
3435
+
3436
+ /**
3437
+ * Returns the total width of all columns.
3438
+ * @param {Boolean} includeHidden True to include hidden column widths
3439
+ * @return {Number}
3440
+ */
3441
+ getTotalWidth : function(includeHidden){
3442
+ if(!this.totalWidth){
3443
+ this.totalWidth = 0;
3444
+ for(var i = 0, len = this.config.length; i < len; i++){
3445
+ if(includeHidden || !this.isHidden(i)){
3446
+ this.totalWidth += this.getColumnWidth(i);
3447
+ }
3448
+ }
3449
+ }
3450
+ return this.totalWidth;
3451
+ },
3452
+
3453
+ /**
3454
+ * Returns the header for the specified column.
3455
+ * @param {Number} col The column index
3456
+ * @return {String}
3457
+ */
3458
+ getColumnHeader : function(col){
3459
+ return this.config[col].header;
3460
+ },
3461
+
3462
+ /**
3463
+ * Sets the header for a column.
3464
+ * @param {Number} col The column index
3465
+ * @param {String} header The new header
3466
+ */
3467
+ setColumnHeader : function(col, header){
3468
+ this.config[col].header = header;
3469
+ this.fireEvent("headerchange", this, col, header);
3470
+ },
3471
+
3472
+ /**
3473
+ * Returns the tooltip for the specified column.
3474
+ * @param {Number} col The column index
3475
+ * @return {String}
3476
+ */
3477
+ getColumnTooltip : function(col){
3478
+ return this.config[col].tooltip;
3479
+ },
3480
+ /**
3481
+ * Sets the tooltip for a column.
3482
+ * @param {Number} col The column index
3483
+ * @param {String} tooltip The new tooltip
3484
+ */
3485
+ setColumnTooltip : function(col, tooltip){
3486
+ this.config[col].tooltip = tooltip;
3487
+ },
3488
+
3489
+ /**
3490
+ * Returns the dataIndex for the specified column.
3491
+ <pre><code>
3492
+ // Get field name for the column
3493
+ var fieldName = grid.getColumnModel().getDataIndex(columnIndex);
3494
+ </code></pre>
3495
+ * @param {Number} col The column index
3496
+ * @return {String} The column's dataIndex
3497
+ */
3498
+ getDataIndex : function(col){
3499
+ return this.config[col].dataIndex;
3500
+ },
3501
+
3502
+ /**
3503
+ * Sets the dataIndex for a column.
3504
+ * @param {Number} col The column index
3505
+ * @param {String} dataIndex The new dataIndex
3506
+ */
3507
+ setDataIndex : function(col, dataIndex){
3508
+ this.config[col].dataIndex = dataIndex;
3509
+ },
3510
+
3511
+ /**
3512
+ * Finds the index of the first matching column for the given dataIndex.
3513
+ * @param {String} col The dataIndex to find
3514
+ * @return {Number} The column index, or -1 if no match was found
3515
+ */
3516
+ findColumnIndex : function(dataIndex){
3517
+ var c = this.config;
3518
+ for(var i = 0, len = c.length; i < len; i++){
3519
+ if(c[i].dataIndex == dataIndex){
3520
+ return i;
3521
+ }
3522
+ }
3523
+ return -1;
3524
+ },
3525
+
3526
+ /**
3527
+ * Returns true if the cell is editable.
3528
+ <pre><code>
3529
+ var store = new Ext.data.Store({...});
3530
+ var colModel = new Ext.grid.ColumnModel({
3531
+ columns: [...],
3532
+ isCellEditable: function(col, row) {
3533
+ var record = store.getAt(row);
3534
+ if (record.get('readonly')) { // replace with your condition
3535
+ return false;
3536
+ }
3537
+ return Ext.grid.ColumnModel.prototype.isCellEditable.call(this, col, row);
3538
+ }
3539
+ });
3540
+ var grid = new Ext.grid.GridPanel({
3541
+ store: store,
3542
+ colModel: colModel,
3543
+ ...
3544
+ });
3545
+ </code></pre>
3546
+ * @param {Number} colIndex The column index
3547
+ * @param {Number} rowIndex The row index
3548
+ * @return {Boolean}
3549
+ */
3550
+ isCellEditable : function(colIndex, rowIndex){
3551
+ return (this.config[colIndex].editable || (typeof this.config[colIndex].editable == "undefined" && this.config[colIndex].editor)) ? true : false;
3552
+ },
3553
+
3554
+ /**
3555
+ * Returns the editor defined for the cell/column.
3556
+ * @param {Number} colIndex The column index
3557
+ * @param {Number} rowIndex The row index
3558
+ * @return {Ext.Editor} The {@link Ext.Editor Editor} that was created to wrap
3559
+ * the {@link Ext.form.Field Field} used to edit the cell.
3560
+ */
3561
+ getCellEditor : function(colIndex, rowIndex){
3562
+ return this.config[colIndex].getCellEditor(rowIndex);
3563
+ },
3564
+
3565
+ /**
3566
+ * Sets if a column is editable.
3567
+ * @param {Number} col The column index
3568
+ * @param {Boolean} editable True if the column is editable
3569
+ */
3570
+ setEditable : function(col, editable){
3571
+ this.config[col].editable = editable;
3572
+ },
3573
+
3574
+
3575
+ /**
3576
+ * Returns true if the column is hidden.
3577
+ * @param {Number} colIndex The column index
3578
+ * @return {Boolean}
3579
+ */
3580
+ isHidden : function(colIndex){
3581
+ return this.config[colIndex].hidden;
3582
+ },
3583
+
3584
+
3585
+ /**
3586
+ * Returns true if the column width cannot be changed
3587
+ */
3588
+ isFixed : function(colIndex){
3589
+ return this.config[colIndex].fixed;
3590
+ },
3591
+
3592
+ /**
3593
+ * Returns true if the column can be resized
3594
+ * @return {Boolean}
3595
+ */
3596
+ isResizable : function(colIndex){
3597
+ return colIndex >= 0 && this.config[colIndex].resizable !== false && this.config[colIndex].fixed !== true;
3598
+ },
3599
+ /**
3600
+ * Sets if a column is hidden.
3601
+ <pre><code>
3602
+ myGrid.getColumnModel().setHidden(0, true); // hide column 0 (0 = the first column).
3603
+ </code></pre>
3604
+ * @param {Number} colIndex The column index
3605
+ * @param {Boolean} hidden True if the column is hidden
3606
+ */
3607
+ setHidden : function(colIndex, hidden){
3608
+ var c = this.config[colIndex];
3609
+ if(c.hidden !== hidden){
3610
+ c.hidden = hidden;
3611
+ this.totalWidth = null;
3612
+ this.fireEvent("hiddenchange", this, colIndex, hidden);
3613
+ }
3614
+ },
3615
+
3616
+ /**
3617
+ * Sets the editor for a column and destroys the prior editor.
3618
+ * @param {Number} col The column index
3619
+ * @param {Object} editor The editor object
3620
+ */
3621
+ setEditor : function(col, editor){
3622
+ Ext.destroy(this.config[col].editor);
3623
+ this.config[col].editor = editor;
3624
+ },
3625
+
3626
+ /**
3627
+ * Destroys this column model by purging any event listeners, and removing any editors.
3628
+ */
3629
+ destroy : function(){
3630
+ for(var i = 0, c = this.config, len = c.length; i < len; i++){
3631
+ Ext.destroy(c[i].editor);
3632
+ }
3633
+ this.purgeListeners();
3634
+ }
3635
+ });
3636
+
3637
+ // private
3638
+ Ext.grid.ColumnModel.defaultRenderer = function(value){
3639
+ if(typeof value == "string" && value.length < 1){
3640
+ return "&#160;";
3641
+ }
3642
+ return value;
3643
+ };/**
3644
+ * @class Ext.grid.AbstractSelectionModel
3645
+ * @extends Ext.util.Observable
3646
+ * Abstract base class for grid SelectionModels. It provides the interface that should be
3647
+ * implemented by descendant classes. This class should not be directly instantiated.
3648
+ * @constructor
3649
+ */
3650
+ Ext.grid.AbstractSelectionModel = function(){
3651
+ this.locked = false;
3652
+ Ext.grid.AbstractSelectionModel.superclass.constructor.call(this);
3653
+ };
3654
+
3655
+ Ext.extend(Ext.grid.AbstractSelectionModel, Ext.util.Observable, {
3656
+ /**
3657
+ * The GridPanel for which this SelectionModel is handling selection. Read-only.
3658
+ * @type Object
3659
+ * @property grid
3660
+ */
3661
+
3662
+ /** @ignore Called by the grid automatically. Do not call directly. */
3663
+ init : function(grid){
3664
+ this.grid = grid;
3665
+ this.initEvents();
3666
+ },
3667
+
3668
+ /**
3669
+ * Locks the selections.
3670
+ */
3671
+ lock : function(){
3672
+ this.locked = true;
3673
+ },
3674
+
3675
+ /**
3676
+ * Unlocks the selections.
3677
+ */
3678
+ unlock : function(){
3679
+ this.locked = false;
3680
+ },
3681
+
3682
+ /**
3683
+ * Returns true if the selections are locked.
3684
+ * @return {Boolean}
3685
+ */
3686
+ isLocked : function(){
3687
+ return this.locked;
3688
+ },
3689
+
3690
+ destroy: function(){
3691
+ this.purgeListeners();
3692
+ }
3693
+ });/**
3694
+ * @class Ext.grid.RowSelectionModel
3695
+ * @extends Ext.grid.AbstractSelectionModel
3696
+ * The default SelectionModel used by {@link Ext.grid.GridPanel}.
3697
+ * It supports multiple selections and keyboard selection/navigation. The objects stored
3698
+ * as selections and returned by {@link #getSelected}, and {@link #getSelections} are
3699
+ * the {@link Ext.data.Record Record}s which provide the data for the selected rows.
3700
+ * @constructor
3701
+ * @param {Object} config
3702
+ */
3703
+ Ext.grid.RowSelectionModel = function(config){
3704
+ Ext.apply(this, config);
3705
+ this.selections = new Ext.util.MixedCollection(false, function(o){
3706
+ return o.id;
3707
+ });
3708
+
3709
+ this.last = false;
3710
+ this.lastActive = false;
3711
+
3712
+ this.addEvents(
3713
+ /**
3714
+ * @event selectionchange
3715
+ * Fires when the selection changes
3716
+ * @param {SelectionModel} this
3717
+ */
3718
+ "selectionchange",
3719
+ /**
3720
+ * @event beforerowselect
3721
+ * Fires before a row is selected, return false to cancel the selection.
3722
+ * @param {SelectionModel} this
3723
+ * @param {Number} rowIndex The index to be selected
3724
+ * @param {Boolean} keepExisting False if other selections will be cleared
3725
+ * @param {Record} record The record to be selected
3726
+ */
3727
+ "beforerowselect",
3728
+ /**
3729
+ * @event rowselect
3730
+ * Fires when a row is selected.
3731
+ * @param {SelectionModel} this
3732
+ * @param {Number} rowIndex The selected index
3733
+ * @param {Ext.data.Record} r The selected record
3734
+ */
3735
+ "rowselect",
3736
+ /**
3737
+ * @event rowdeselect
3738
+ * Fires when a row is deselected. To prevent deselection
3739
+ * {@link Ext.grid.AbstractSelectionModel#lock lock the selections}.
3740
+ * @param {SelectionModel} this
3741
+ * @param {Number} rowIndex
3742
+ * @param {Record} record
3743
+ */
3744
+ "rowdeselect"
3745
+ );
3746
+
3747
+ Ext.grid.RowSelectionModel.superclass.constructor.call(this);
3748
+ };
3749
+
3750
+ Ext.extend(Ext.grid.RowSelectionModel, Ext.grid.AbstractSelectionModel, {
3751
+ /**
3752
+ * @cfg {Boolean} singleSelect
3753
+ * <tt>true</tt> to allow selection of only one row at a time (defaults to <tt>false</tt>
3754
+ * allowing multiple selections)
3755
+ */
3756
+ singleSelect : false,
3757
+
3758
+ /**
3759
+ * @cfg {Boolean} moveEditorOnEnter
3760
+ * <tt>false</tt> to turn off moving the editor to the next row down when the enter key is pressed
3761
+ * or the next row up when shift + enter keys are pressed.
3762
+ */
3763
+ // private
3764
+ initEvents : function(){
3765
+
3766
+ if(!this.grid.enableDragDrop && !this.grid.enableDrag){
3767
+ this.grid.on("rowmousedown", this.handleMouseDown, this);
3768
+ }else{ // allow click to work like normal
3769
+ this.grid.on("rowclick", function(grid, rowIndex, e) {
3770
+ if(e.button === 0 && !e.shiftKey && !e.ctrlKey) {
3771
+ this.selectRow(rowIndex, false);
3772
+ grid.view.focusRow(rowIndex);
3773
+ }
3774
+ }, this);
3775
+ }
3776
+
3777
+ this.rowNav = new Ext.KeyNav(this.grid.getGridEl(), {
3778
+ "up" : function(e){
3779
+ if(!e.shiftKey || this.singleSelect){
3780
+ this.selectPrevious(false);
3781
+ }else if(this.last !== false && this.lastActive !== false){
3782
+ var last = this.last;
3783
+ this.selectRange(this.last, this.lastActive-1);
3784
+ this.grid.getView().focusRow(this.lastActive);
3785
+ if(last !== false){
3786
+ this.last = last;
3787
+ }
3788
+ }else{
3789
+ this.selectFirstRow();
3790
+ }
3791
+ },
3792
+ "down" : function(e){
3793
+ if(!e.shiftKey || this.singleSelect){
3794
+ this.selectNext(false);
3795
+ }else if(this.last !== false && this.lastActive !== false){
3796
+ var last = this.last;
3797
+ this.selectRange(this.last, this.lastActive+1);
3798
+ this.grid.getView().focusRow(this.lastActive);
3799
+ if(last !== false){
3800
+ this.last = last;
3801
+ }
3802
+ }else{
3803
+ this.selectFirstRow();
3804
+ }
3805
+ },
3806
+ scope: this
3807
+ });
3808
+
3809
+ var view = this.grid.view;
3810
+ view.on("refresh", this.onRefresh, this);
3811
+ view.on("rowupdated", this.onRowUpdated, this);
3812
+ view.on("rowremoved", this.onRemove, this);
3813
+ },
3814
+
3815
+ // private
3816
+ onRefresh : function(){
3817
+ var ds = this.grid.store, index;
3818
+ var s = this.getSelections();
3819
+ this.clearSelections(true);
3820
+ for(var i = 0, len = s.length; i < len; i++){
3821
+ var r = s[i];
3822
+ if((index = ds.indexOfId(r.id)) != -1){
3823
+ this.selectRow(index, true);
3824
+ }
3825
+ }
3826
+ if(s.length != this.selections.getCount()){
3827
+ this.fireEvent("selectionchange", this);
3828
+ }
3829
+ },
3830
+
3831
+ // private
3832
+ onRemove : function(v, index, r){
3833
+ if(this.selections.remove(r) !== false){
3834
+ this.fireEvent('selectionchange', this);
3835
+ }
3836
+ },
3837
+
3838
+ // private
3839
+ onRowUpdated : function(v, index, r){
3840
+ if(this.isSelected(r)){
3841
+ v.onRowSelect(index);
3842
+ }
3843
+ },
3844
+
3845
+ /**
3846
+ * Select records.
3847
+ * @param {Array} records The records to select
3848
+ * @param {Boolean} keepExisting (optional) <tt>true</tt> to keep existing selections
3849
+ */
3850
+ selectRecords : function(records, keepExisting){
3851
+ if(!keepExisting){
3852
+ this.clearSelections();
3853
+ }
3854
+ var ds = this.grid.store;
3855
+ for(var i = 0, len = records.length; i < len; i++){
3856
+ this.selectRow(ds.indexOf(records[i]), true);
3857
+ }
3858
+ },
3859
+
3860
+ /**
3861
+ * Gets the number of selected rows.
3862
+ * @return {Number}
3863
+ */
3864
+ getCount : function(){
3865
+ return this.selections.length;
3866
+ },
3867
+
3868
+ /**
3869
+ * Selects the first row in the grid.
3870
+ */
3871
+ selectFirstRow : function(){
3872
+ this.selectRow(0);
3873
+ },
3874
+
3875
+ /**
3876
+ * Select the last row.
3877
+ * @param {Boolean} keepExisting (optional) <tt>true</tt> to keep existing selections
3878
+ */
3879
+ selectLastRow : function(keepExisting){
3880
+ this.selectRow(this.grid.store.getCount() - 1, keepExisting);
3881
+ },
3882
+
3883
+ /**
3884
+ * Selects the row immediately following the last selected row.
3885
+ * @param {Boolean} keepExisting (optional) <tt>true</tt> to keep existing selections
3886
+ * @return {Boolean} <tt>true</tt> if there is a next row, else <tt>false</tt>
3887
+ */
3888
+ selectNext : function(keepExisting){
3889
+ if(this.hasNext()){
3890
+ this.selectRow(this.last+1, keepExisting);
3891
+ this.grid.getView().focusRow(this.last);
3892
+ return true;
3893
+ }
3894
+ return false;
3895
+ },
3896
+
3897
+ /**
3898
+ * Selects the row that precedes the last selected row.
3899
+ * @param {Boolean} keepExisting (optional) <tt>true</tt> to keep existing selections
3900
+ * @return {Boolean} <tt>true</tt> if there is a previous row, else <tt>false</tt>
3901
+ */
3902
+ selectPrevious : function(keepExisting){
3903
+ if(this.hasPrevious()){
3904
+ this.selectRow(this.last-1, keepExisting);
3905
+ this.grid.getView().focusRow(this.last);
3906
+ return true;
3907
+ }
3908
+ return false;
3909
+ },
3910
+
3911
+ /**
3912
+ * Returns true if there is a next record to select
3913
+ * @return {Boolean}
3914
+ */
3915
+ hasNext : function(){
3916
+ return this.last !== false && (this.last+1) < this.grid.store.getCount();
3917
+ },
3918
+
3919
+ /**
3920
+ * Returns true if there is a previous record to select
3921
+ * @return {Boolean}
3922
+ */
3923
+ hasPrevious : function(){
3924
+ return !!this.last;
3925
+ },
3926
+
3927
+
3928
+ /**
3929
+ * Returns the selected records
3930
+ * @return {Array} Array of selected records
3931
+ */
3932
+ getSelections : function(){
3933
+ return [].concat(this.selections.items);
3934
+ },
3935
+
3936
+ /**
3937
+ * Returns the first selected record.
3938
+ * @return {Record}
3939
+ */
3940
+ getSelected : function(){
3941
+ return this.selections.itemAt(0);
3942
+ },
3943
+
3944
+ /**
3945
+ * Calls the passed function with each selection. If the function returns
3946
+ * <tt>false</tt>, iteration is stopped and this function returns
3947
+ * <tt>false</tt>. Otherwise it returns <tt>true</tt>.
3948
+ * @param {Function} fn
3949
+ * @param {Object} scope (optional)
3950
+ * @return {Boolean} true if all selections were iterated
3951
+ */
3952
+ each : function(fn, scope){
3953
+ var s = this.getSelections();
3954
+ for(var i = 0, len = s.length; i < len; i++){
3955
+ if(fn.call(scope || this, s[i], i) === false){
3956
+ return false;
3957
+ }
3958
+ }
3959
+ return true;
3960
+ },
3961
+
3962
+ /**
3963
+ * Clears all selections if the selection model
3964
+ * {@link Ext.grid.AbstractSelectionModel#isLocked is not locked}.
3965
+ * @param {Boolean} fast (optional) <tt>true</tt> to bypass the
3966
+ * conditional checks and events described in {@link #deselectRow}.
3967
+ */
3968
+ clearSelections : function(fast){
3969
+ if(this.isLocked()){
3970
+ return;
3971
+ }
3972
+ if(fast !== true){
3973
+ var ds = this.grid.store;
3974
+ var s = this.selections;
3975
+ s.each(function(r){
3976
+ this.deselectRow(ds.indexOfId(r.id));
3977
+ }, this);
3978
+ s.clear();
3979
+ }else{
3980
+ this.selections.clear();
3981
+ }
3982
+ this.last = false;
3983
+ },
3984
+
3985
+
3986
+ /**
3987
+ * Selects all rows if the selection model
3988
+ * {@link Ext.grid.AbstractSelectionModel#isLocked is not locked}.
3989
+ */
3990
+ selectAll : function(){
3991
+ if(this.isLocked()){
3992
+ return;
3993
+ }
3994
+ this.selections.clear();
3995
+ for(var i = 0, len = this.grid.store.getCount(); i < len; i++){
3996
+ this.selectRow(i, true);
3997
+ }
3998
+ },
3999
+
4000
+ /**
4001
+ * Returns <tt>true</tt> if there is a selection.
4002
+ * @return {Boolean}
4003
+ */
4004
+ hasSelection : function(){
4005
+ return this.selections.length > 0;
4006
+ },
4007
+
4008
+ /**
4009
+ * Returns <tt>true</tt> if the specified row is selected.
4010
+ * @param {Number/Record} index The record or index of the record to check
4011
+ * @return {Boolean}
4012
+ */
4013
+ isSelected : function(index){
4014
+ var r = typeof index == "number" ? this.grid.store.getAt(index) : index;
4015
+ return (r && this.selections.key(r.id) ? true : false);
4016
+ },
4017
+
4018
+ /**
4019
+ * Returns <tt>true</tt> if the specified record id is selected.
4020
+ * @param {String} id The id of record to check
4021
+ * @return {Boolean}
4022
+ */
4023
+ isIdSelected : function(id){
4024
+ return (this.selections.key(id) ? true : false);
4025
+ },
4026
+
4027
+ // private
4028
+ handleMouseDown : function(g, rowIndex, e){
4029
+ if(e.button !== 0 || this.isLocked()){
4030
+ return;
4031
+ }
4032
+ var view = this.grid.getView();
4033
+ if(e.shiftKey && !this.singleSelect && this.last !== false){
4034
+ var last = this.last;
4035
+ this.selectRange(last, rowIndex, e.ctrlKey);
4036
+ this.last = last; // reset the last
4037
+ view.focusRow(rowIndex);
4038
+ }else{
4039
+ var isSelected = this.isSelected(rowIndex);
4040
+ if(e.ctrlKey && isSelected){
4041
+ this.deselectRow(rowIndex);
4042
+ }else if(!isSelected || this.getCount() > 1){
4043
+ this.selectRow(rowIndex, e.ctrlKey || e.shiftKey);
4044
+ view.focusRow(rowIndex);
4045
+ }
4046
+ }
4047
+ },
4048
+
4049
+ /**
4050
+ * Selects multiple rows.
4051
+ * @param {Array} rows Array of the indexes of the row to select
4052
+ * @param {Boolean} keepExisting (optional) <tt>true</tt> to keep
4053
+ * existing selections (defaults to <tt>false</tt>)
4054
+ */
4055
+ selectRows : function(rows, keepExisting){
4056
+ if(!keepExisting){
4057
+ this.clearSelections();
4058
+ }
4059
+ for(var i = 0, len = rows.length; i < len; i++){
4060
+ this.selectRow(rows[i], true);
4061
+ }
4062
+ },
4063
+
4064
+ /**
4065
+ * Selects a range of rows if the selection model
4066
+ * {@link Ext.grid.AbstractSelectionModel#isLocked is not locked}.
4067
+ * All rows in between startRow and endRow are also selected.
4068
+ * @param {Number} startRow The index of the first row in the range
4069
+ * @param {Number} endRow The index of the last row in the range
4070
+ * @param {Boolean} keepExisting (optional) True to retain existing selections
4071
+ */
4072
+ selectRange : function(startRow, endRow, keepExisting){
4073
+ var i;
4074
+ if(this.isLocked()){
4075
+ return;
4076
+ }
4077
+ if(!keepExisting){
4078
+ this.clearSelections();
4079
+ }
4080
+ if(startRow <= endRow){
4081
+ for(i = startRow; i <= endRow; i++){
4082
+ this.selectRow(i, true);
4083
+ }
4084
+ }else{
4085
+ for(i = startRow; i >= endRow; i--){
4086
+ this.selectRow(i, true);
4087
+ }
4088
+ }
4089
+ },
4090
+
4091
+ /**
4092
+ * Deselects a range of rows if the selection model
4093
+ * {@link Ext.grid.AbstractSelectionModel#isLocked is not locked}.
4094
+ * All rows in between startRow and endRow are also deselected.
4095
+ * @param {Number} startRow The index of the first row in the range
4096
+ * @param {Number} endRow The index of the last row in the range
4097
+ */
4098
+ deselectRange : function(startRow, endRow, preventViewNotify){
4099
+ if(this.isLocked()){
4100
+ return;
4101
+ }
4102
+ for(var i = startRow; i <= endRow; i++){
4103
+ this.deselectRow(i, preventViewNotify);
4104
+ }
4105
+ },
4106
+
4107
+ /**
4108
+ * Selects a row. Before selecting a row, checks if the selection model
4109
+ * {@link Ext.grid.AbstractSelectionModel#isLocked is locked} and fires the
4110
+ * {@link #beforerowselect} event. If these checks are satisfied the row
4111
+ * will be selected and followed up by firing the {@link #rowselect} and
4112
+ * {@link #selectionchange} events.
4113
+ * @param {Number} row The index of the row to select
4114
+ * @param {Boolean} keepExisting (optional) <tt>true</tt> to keep existing selections
4115
+ * @param {Boolean} preventViewNotify (optional) Specify <tt>true</tt> to
4116
+ * prevent notifying the view (disables updating the selected appearance)
4117
+ */
4118
+ selectRow : function(index, keepExisting, preventViewNotify){
4119
+ if(this.isLocked() || (index < 0 || index >= this.grid.store.getCount()) || (keepExisting && this.isSelected(index))){
4120
+ return;
4121
+ }
4122
+ var r = this.grid.store.getAt(index);
4123
+ if(r && this.fireEvent("beforerowselect", this, index, keepExisting, r) !== false){
4124
+ if(!keepExisting || this.singleSelect){
4125
+ this.clearSelections();
4126
+ }
4127
+ this.selections.add(r);
4128
+ this.last = this.lastActive = index;
4129
+ if(!preventViewNotify){
4130
+ this.grid.getView().onRowSelect(index);
4131
+ }
4132
+ this.fireEvent("rowselect", this, index, r);
4133
+ this.fireEvent("selectionchange", this);
4134
+ }
4135
+ },
4136
+
4137
+ /**
4138
+ * Deselects a row. Before deselecting a row, checks if the selection model
4139
+ * {@link Ext.grid.AbstractSelectionModel#isLocked is locked}.
4140
+ * If this check is satisfied the row will be deselected and followed up by
4141
+ * firing the {@link #rowdeselect} and {@link #selectionchange} events.
4142
+ * @param {Number} row The index of the row to deselect
4143
+ * @param {Boolean} preventViewNotify (optional) Specify <tt>true</tt> to
4144
+ * prevent notifying the view (disables updating the selected appearance)
4145
+ */
4146
+ deselectRow : function(index, preventViewNotify){
4147
+ if(this.isLocked()){
4148
+ return;
4149
+ }
4150
+ if(this.last == index){
4151
+ this.last = false;
4152
+ }
4153
+ if(this.lastActive == index){
4154
+ this.lastActive = false;
4155
+ }
4156
+ var r = this.grid.store.getAt(index);
4157
+ if(r){
4158
+ this.selections.remove(r);
4159
+ if(!preventViewNotify){
4160
+ this.grid.getView().onRowDeselect(index);
4161
+ }
4162
+ this.fireEvent("rowdeselect", this, index, r);
4163
+ this.fireEvent("selectionchange", this);
4164
+ }
4165
+ },
4166
+
4167
+ // private
4168
+ restoreLast : function(){
4169
+ if(this._last){
4170
+ this.last = this._last;
4171
+ }
4172
+ },
4173
+
4174
+ // private
4175
+ acceptsNav : function(row, col, cm){
4176
+ return !cm.isHidden(col) && cm.isCellEditable(col, row);
4177
+ },
4178
+
4179
+ // private
4180
+ onEditorKey : function(field, e){
4181
+ var k = e.getKey(), newCell, g = this.grid, ed = g.activeEditor;
4182
+ var shift = e.shiftKey;
4183
+ if(k == e.TAB){
4184
+ e.stopEvent();
4185
+ ed.completeEdit();
4186
+ if(shift){
4187
+ newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
4188
+ }else{
4189
+ newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
4190
+ }
4191
+ }else if(k == e.ENTER){
4192
+ e.stopEvent();
4193
+ ed.completeEdit();
4194
+ if(this.moveEditorOnEnter !== false){
4195
+ if(shift){
4196
+ newCell = g.walkCells(ed.row - 1, ed.col, -1, this.acceptsNav, this);
4197
+ }else{
4198
+ newCell = g.walkCells(ed.row + 1, ed.col, 1, this.acceptsNav, this);
4199
+ }
4200
+ }
4201
+ }else if(k == e.ESC){
4202
+ ed.cancelEdit();
4203
+ }
4204
+ if(newCell){
4205
+ g.startEditing(newCell[0], newCell[1]);
4206
+ }
4207
+ },
4208
+
4209
+ destroy: function(){
4210
+ if(this.rowNav){
4211
+ this.rowNav.disable();
4212
+ this.rowNav = null;
4213
+ }
4214
+ Ext.grid.RowSelectionModel.superclass.destroy.call(this);
4215
+ }
4216
+ });/**
4217
+ * @class Ext.grid.Column
4218
+ * <p>This class encapsulates column configuration data to be used in the initialization of a
4219
+ * {@link Ext.grid.ColumnModel ColumnModel}.</p>
4220
+ * <p>While subclasses are provided to render data in different ways, this class renders a passed
4221
+ * data field unchanged and is usually used for textual columns.</p>
4222
+ */
4223
+ Ext.grid.Column = function(config){
4224
+ Ext.apply(this, config);
4225
+
4226
+ if(typeof this.renderer == 'string'){
4227
+ this.renderer = Ext.util.Format[this.renderer];
4228
+ } else if(Ext.isObject(this.renderer)){
4229
+ this.scope = this.renderer.scope;
4230
+ this.renderer = this.renderer.fn;
4231
+ }
4232
+ this.renderer = this.renderer.createDelegate(this.scope || config);
4233
+
4234
+ if(this.id === undefined){
4235
+ this.id = ++Ext.grid.Column.AUTO_ID;
4236
+ }
4237
+ if(this.editor){
4238
+ this.editor = Ext.create(this.editor, 'textfield');
4239
+ }
4240
+ };
4241
+
4242
+ Ext.grid.Column.AUTO_ID = 0;
4243
+
4244
+ Ext.grid.Column.prototype = {
4245
+ /**
4246
+ * @cfg {Boolean} editable Optional. Defaults to <tt>true</tt>, enabling the configured
4247
+ * <tt>{@link #editor}</tt>. Set to <tt>false</tt> to initially disable editing on this column.
4248
+ * The initial configuration may be dynamically altered using
4249
+ * {@link Ext.grid.ColumnModel}.{@link Ext.grid.ColumnModel#setEditable setEditable()}.
4250
+ */
4251
+ /**
4252
+ * @cfg {String} id Optional. A name which identifies this column (defaults to the column's initial
4253
+ * ordinal position.) The <tt>id</tt> is used to create a CSS <b>class</b> name which is applied to all
4254
+ * table cells (including headers) in that column (in this context the <tt>id</tt> does not need to be
4255
+ * unique). The class name takes the form of <pre>x-grid3-td-<b>id</b></pre>
4256
+ * Header cells will also receive this class name, but will also have the class <pre>x-grid3-hd</pre>
4257
+ * So, to target header cells, use CSS selectors such as:<pre>.x-grid3-hd-row .x-grid3-td-<b>id</b></pre>
4258
+ * The {@link Ext.grid.GridPanel#autoExpandColumn} grid config option references the column via this
4259
+ * unique identifier.
4260
+ */
4261
+ /**
4262
+ * @cfg {String} header Optional. The header text to be used as innerHTML
4263
+ * (html tags are accepted) to display in the Grid view. <b>Note</b>: to
4264
+ * have a clickable header with no text displayed use <tt>'&#160;'</tt>.
4265
+ */
4266
+ /**
4267
+ * @cfg {Boolean} groupable Optional. If the grid is being rendered by an {@link Ext.grid.GroupingView}, this option
4268
+ * may be used to disable the header menu item to group by the column selected. Defaults to <tt>true</tt>,
4269
+ * which enables the header menu group option. Set to <tt>false</tt> to disable (but still show) the
4270
+ * group option in the header menu for the column. See also <code>{@link #groupName}</code>.
4271
+ */
4272
+ /**
4273
+ * @cfg {String} groupName Optional. If the grid is being rendered by an {@link Ext.grid.GroupingView}, this option
4274
+ * may be used to specify the text with which to prefix the group field value in the group header line.
4275
+ * See also {@link #groupRenderer} and
4276
+ * {@link Ext.grid.GroupingView}.{@link Ext.grid.GroupingView#showGroupName showGroupName}.
4277
+ */
4278
+ /**
4279
+ * @cfg {Function} groupRenderer <p>Optional. If the grid is being rendered by an {@link Ext.grid.GroupingView}, this option
4280
+ * may be used to specify the function used to format the grouping field value for display in the group
4281
+ * {@link #groupName header}. If a <tt><b>groupRenderer</b></tt> is not specified, the configured
4282
+ * <tt><b>{@link #renderer}</b></tt> will be called; if a <tt><b>{@link #renderer}</b></tt> is also not specified
4283
+ * the new value of the group field will be used.</p>
4284
+ * <p>The called function (either the <tt><b>groupRenderer</b></tt> or <tt><b>{@link #renderer}</b></tt>) will be
4285
+ * passed the following parameters:
4286
+ * <div class="mdetail-params"><ul>
4287
+ * <li><b>v</b> : Object<p class="sub-desc">The new value of the group field.</p></li>
4288
+ * <li><b>unused</b> : undefined<p class="sub-desc">Unused parameter.</p></li>
4289
+ * <li><b>r</b> : Ext.data.Record<p class="sub-desc">The Record providing the data
4290
+ * for the row which caused group change.</p></li>
4291
+ * <li><b>rowIndex</b> : Number<p class="sub-desc">The row index of the Record which caused group change.</p></li>
4292
+ * <li><b>colIndex</b> : Number<p class="sub-desc">The column index of the group field.</p></li>
4293
+ * <li><b>ds</b> : Ext.data.Store<p class="sub-desc">The Store which is providing the data Model.</p></li>
4294
+ * </ul></div></p>
4295
+ * <p>The function should return a string value.</p>
4296
+ */
4297
+ /**
4298
+ * @cfg {String} emptyGroupText Optional. If the grid is being rendered by an {@link Ext.grid.GroupingView}, this option
4299
+ * may be used to specify the text to display when there is an empty group value. Defaults to the
4300
+ * {@link Ext.grid.GroupingView}.{@link Ext.grid.GroupingView#emptyGroupText emptyGroupText}.
4301
+ */
4302
+ /**
4303
+ * @cfg {String} dataIndex <p><b>Required</b>. The name of the field in the
4304
+ * grid's {@link Ext.data.Store}'s {@link Ext.data.Record} definition from
4305
+ * which to draw the column's value.</p>
4306
+ */
4307
+ /**
4308
+ * @cfg {Number} width
4309
+ * Optional. The initial width in pixels of the column.
4310
+ * The width of each column can also be affected if any of the following are configured:
4311
+ * <div class="mdetail-params"><ul>
4312
+ * <li>{@link Ext.grid.GridPanel}.<tt>{@link Ext.grid.GridPanel#autoExpandColumn autoExpandColumn}</tt></li>
4313
+ * <li>{@link Ext.grid.GridView}.<tt>{@link Ext.grid.GridView#forceFit forceFit}</tt>
4314
+ * <div class="sub-desc">
4315
+ * <p>By specifying <tt>forceFit:true</tt>, {@link #fixed non-fixed width} columns will be
4316
+ * re-proportioned (based on the relative initial widths) to fill the width of the grid so
4317
+ * that no horizontal scrollbar is shown.</p>
4318
+ * </div></li>
4319
+ * <li>{@link Ext.grid.GridView}.<tt>{@link Ext.grid.GridView#autoFill autoFill}</tt></li>
4320
+ * <li>{@link Ext.grid.GridPanel}.<tt>{@link Ext.grid.GridPanel#minColumnWidth minColumnWidth}</tt></li>
4321
+ * <br><p><b>Note</b>: when the width of each column is determined, a space on the right side
4322
+ * is reserved for the vertical scrollbar. The
4323
+ * {@link Ext.grid.GridView}.<tt>{@link Ext.grid.GridView#scrollOffset scrollOffset}</tt>
4324
+ * can be modified to reduce or eliminate the reserved offset.</p>
4325
+ */
4326
+ /**
4327
+ * @cfg {Boolean} sortable Optional. <tt>true</tt> if sorting is to be allowed on this column.
4328
+ * Defaults to the value of the {@link #defaultSortable} property.
4329
+ * Whether local/remote sorting is used is specified in {@link Ext.data.Store#remoteSort}.
4330
+ */
4331
+ /**
4332
+ * @cfg {Boolean} fixed Optional. <tt>true</tt> if the column width cannot be changed. Defaults to <tt>false</tt>.
4333
+ */
4334
+ /**
4335
+ * @cfg {Boolean} resizable Optional. <tt>false</tt> to disable column resizing. Defaults to <tt>true</tt>.
4336
+ */
4337
+ /**
4338
+ * @cfg {Boolean} menuDisabled Optional. <tt>true</tt> to disable the column menu. Defaults to <tt>false</tt>.
4339
+ */
4340
+ /**
4341
+ * @cfg {Boolean} hidden Optional. <tt>true</tt> to hide the column. Defaults to <tt>false</tt>.
4342
+ */
4343
+ /**
4344
+ * @cfg {String} tooltip Optional. A text string to use as the column header's tooltip. If Quicktips
4345
+ * are enabled, this value will be used as the text of the quick tip, otherwise it will be set as the
4346
+ * header's HTML title attribute. Defaults to ''.
4347
+ */
4348
+ /**
4349
+ * @cfg {Mixed} renderer
4350
+ * <p>For an alternative to specifying a renderer see <code>{@link #xtype}</code></p>
4351
+ * <p>Optional. A renderer is an 'interceptor' method which can be used transform data (value,
4352
+ * appearance, etc.) before it is rendered). This may be specified in either of three ways:
4353
+ * <div class="mdetail-params"><ul>
4354
+ * <li>A renderer function used to return HTML markup for a cell given the cell's data value.</li>
4355
+ * <li>A string which references a property name of the {@link Ext.util.Format} class which
4356
+ * provides a renderer function.</li>
4357
+ * <li>An object specifying both the renderer function, and its execution scope (<tt><b>this</b></tt>
4358
+ * reference) e.g.:<pre style="margin-left:1.2em"><code>
4359
+ {
4360
+ fn: this.gridRenderer,
4361
+ scope: this
4362
+ }
4363
+ </code></pre></li></ul></div>
4364
+ * If not specified, the default renderer uses the raw data value.</p>
4365
+ * <p>For information about the renderer function (passed parameters, etc.), see
4366
+ * {@link Ext.grid.ColumnModel#setRenderer}. An example of specifying renderer function inline:</p><pre><code>
4367
+ var companyColumn = {
4368
+ header: 'Company Name',
4369
+ dataIndex: 'company',
4370
+ renderer: function(value, metaData, record, rowIndex, colIndex, store) {
4371
+ // provide the logic depending on business rules
4372
+ // name of your own choosing to manipulate the cell depending upon
4373
+ // the data in the underlying Record object.
4374
+ if (value == 'whatever') {
4375
+ //metaData.css : String : A CSS class name to add to the TD element of the cell.
4376
+ //metaData.attr : String : An html attribute definition string to apply to
4377
+ // the data container element within the table
4378
+ // cell (e.g. 'style="color:red;"').
4379
+ metaData.css = 'name-of-css-class-you-will-define';
4380
+ }
4381
+ return value;
4382
+ }
4383
+ }
4384
+ * </code></pre>
4385
+ * See also {@link #scope}.
4386
+ */
4387
+ /**
4388
+ * @cfg {String} xtype Optional. A String which references a predefined {@link Ext.grid.Column} subclass
4389
+ * type which is preconfigured with an appropriate <code>{@link #renderer}</code> to be easily
4390
+ * configured into a ColumnModel. The predefined {@link Ext.grid.Column} subclass types are:
4391
+ * <div class="mdetail-params"><ul>
4392
+ * <li><b><tt>gridcolumn</tt></b> : {@link Ext.grid.Column} (<b>Default</b>)<p class="sub-desc"></p></li>
4393
+ * <li><b><tt>booleancolumn</tt></b> : {@link Ext.grid.BooleanColumn}<p class="sub-desc"></p></li>
4394
+ * <li><b><tt>numbercolumn</tt></b> : {@link Ext.grid.NumberColumn}<p class="sub-desc"></p></li>
4395
+ * <li><b><tt>datecolumn</tt></b> : {@link Ext.grid.DateColumn}<p class="sub-desc"></p></li>
4396
+ * <li><b><tt>templatecolumn</tt></b> : {@link Ext.grid.TemplateColumn}<p class="sub-desc"></p></li>
4397
+ * </ul></div>
4398
+ * <p>Configuration properties for the specified <code>xtype</code> may be specified with
4399
+ * the Column configuration properties, for example:</p>
4400
+ * <pre><code>
4401
+ var grid = new Ext.grid.GridPanel({
4402
+ ...
4403
+ columns: [{
4404
+ header: 'Last Updated',
4405
+ dataIndex: 'lastChange',
4406
+ width: 85,
4407
+ sortable: true,
4408
+ //renderer: Ext.util.Format.dateRenderer('m/d/Y'),
4409
+ xtype: 'datecolumn', // use xtype instead of renderer
4410
+ format: 'M/d/Y' // configuration property for {@link Ext.grid.DateColumn}
4411
+ }, {
4412
+ ...
4413
+ }]
4414
+ });
4415
+ * </code></pre>
4416
+ */
4417
+ /**
4418
+ * @cfg {Object} scope Optional. The scope (<tt><b>this</b></tt> reference) in which to execute the
4419
+ * renderer. Defaults to the Column configuration object.
4420
+ */
4421
+ /**
4422
+ * @cfg {String} align Optional. Set the CSS text-align property of the column. Defaults to undefined.
4423
+ */
4424
+ /**
4425
+ * @cfg {String} css Optional. An inline style definition string which is applied to all table cells in the column
4426
+ * (excluding headers). Defaults to undefined.
4427
+ */
4428
+ /**
4429
+ * @cfg {Boolean} hideable Optional. Specify as <tt>false</tt> to prevent the user from hiding this column
4430
+ * (defaults to true). To disallow column hiding globally for all columns in the grid, use
4431
+ * {@link Ext.grid.GridPanel#enableColumnHide} instead.
4432
+ */
4433
+ /**
4434
+ * @cfg {Ext.form.Field} editor Optional. The {@link Ext.form.Field} to use when editing values in this column
4435
+ * if editing is supported by the grid. See <tt>{@link #editable}</tt> also.
4436
+ */
4437
+
4438
+ // private. Used by ColumnModel to avoid reprocessing
4439
+ isColumn : true,
4440
+ /**
4441
+ * Optional. A function which returns displayable data when passed the following parameters:
4442
+ * <div class="mdetail-params"><ul>
4443
+ * <li><b>value</b> : Object<p class="sub-desc">The data value for the cell.</p></li>
4444
+ * <li><b>metadata</b> : Object<p class="sub-desc">An object in which you may set the following attributes:<ul>
4445
+ * <li><b>css</b> : String<p class="sub-desc">A CSS class name to add to the cell's TD element.</p></li>
4446
+ * <li><b>attr</b> : String<p class="sub-desc">An HTML attribute definition string to apply to the data container
4447
+ * element <i>within</i> the table cell (e.g. 'style="color:red;"').</p></li></ul></p></li>
4448
+ * <li><b>record</b> : Ext.data.record<p class="sub-desc">The {@link Ext.data.Record} from which the data was
4449
+ * extracted.</p></li>
4450
+ * <li><b>rowIndex</b> : Number<p class="sub-desc">Row index</p></li>
4451
+ * <li><b>colIndex</b> : Number<p class="sub-desc">Column index</p></li>
4452
+ * <li><b>store</b> : Ext.data.Store<p class="sub-desc">The {@link Ext.data.Store} object from which the Record
4453
+ * was extracted.</p></li>
4454
+ * </ul></div>
4455
+ * @property renderer
4456
+ * @type Function
4457
+ */
4458
+ renderer : function(value){
4459
+ if(typeof value == 'string' && value.length < 1){
4460
+ return '&#160;';
4461
+ }
4462
+ return value;
4463
+ },
4464
+
4465
+ // private
4466
+ getEditor: function(rowIndex){
4467
+ return this.editable !== false ? this.editor : null;
4468
+ },
4469
+
4470
+ /**
4471
+ * Returns the {@link Ext.Editor editor} defined for this column that was created to wrap the {@link Ext.form.Field Field}
4472
+ * used to edit the cell.
4473
+ * @param {Number} rowIndex The row index
4474
+ * @return {Ext.Editor}
4475
+ */
4476
+ getCellEditor: function(rowIndex){
4477
+ var editor = this.getEditor(rowIndex);
4478
+ if(editor){
4479
+ if(!editor.startEdit){
4480
+ if(!editor.gridEditor){
4481
+ editor.gridEditor = new Ext.grid.GridEditor(editor);
4482
+ }
4483
+ return editor.gridEditor;
4484
+ }else if(editor.startEdit){
4485
+ return editor;
4486
+ }
4487
+ }
4488
+ return null;
4489
+ }
4490
+ };
4491
+
4492
+ /**
4493
+ * @class Ext.grid.BooleanColumn
4494
+ * @extends Ext.grid.Column
4495
+ * <p>A Column definition class which renders boolean data fields. See the {@link Ext.grid.ColumnModel#xtype xtype}
4496
+ * config option of {@link Ext.grid.ColumnModel} for more details.</p>
4497
+ */
4498
+ Ext.grid.BooleanColumn = Ext.extend(Ext.grid.Column, {
4499
+ /**
4500
+ * @cfg {String} trueText
4501
+ * The string returned by the renderer when the column value is not falsey (defaults to <tt>'true'</tt>).
4502
+ */
4503
+ trueText: 'true',
4504
+ /**
4505
+ * @cfg {String} falseText
4506
+ * The string returned by the renderer when the column value is falsey (but not undefined) (defaults to
4507
+ * <tt>'false'</tt>).
4508
+ */
4509
+ falseText: 'false',
4510
+ /**
4511
+ * @cfg {String} undefinedText
4512
+ * The string returned by the renderer when the column value is undefined (defaults to <tt>'&#160;'</tt>).
4513
+ */
4514
+ undefinedText: '&#160;',
4515
+
4516
+ constructor: function(cfg){
4517
+ Ext.grid.BooleanColumn.superclass.constructor.call(this, cfg);
4518
+ var t = this.trueText, f = this.falseText, u = this.undefinedText;
4519
+ this.renderer = function(v){
4520
+ if(v === undefined){
4521
+ return u;
4522
+ }
4523
+ if(!v || v === 'false'){
4524
+ return f;
4525
+ }
4526
+ return t;
4527
+ };
4528
+ }
4529
+ });
4530
+
4531
+ /**
4532
+ * @class Ext.grid.NumberColumn
4533
+ * @extends Ext.grid.Column
4534
+ * <p>A Column definition class which renders a numeric data field according to a {@link #format} string. See the
4535
+ * {@link Ext.grid.ColumnModel#xtype xtype} config option of {@link Ext.grid.ColumnModel} for more details.</p>
4536
+ */
4537
+ Ext.grid.NumberColumn = Ext.extend(Ext.grid.Column, {
4538
+ /**
4539
+ * @cfg {String} format
4540
+ * A formatting string as used by {@link Ext.util.Format#number} to format a numeric value for this Column
4541
+ * (defaults to <tt>'0,000.00'</tt>).
4542
+ */
4543
+ format : '0,000.00',
4544
+ constructor: function(cfg){
4545
+ Ext.grid.NumberColumn.superclass.constructor.call(this, cfg);
4546
+ this.renderer = Ext.util.Format.numberRenderer(this.format);
4547
+ }
4548
+ });
4549
+
4550
+ /**
4551
+ * @class Ext.grid.DateColumn
4552
+ * @extends Ext.grid.Column
4553
+ * <p>A Column definition class which renders a passed date according to the default locale, or a configured
4554
+ * {@link #format}. See the {@link Ext.grid.ColumnModel#xtype xtype} config option of {@link Ext.grid.ColumnModel}
4555
+ * for more details.</p>
4556
+ */
4557
+ Ext.grid.DateColumn = Ext.extend(Ext.grid.Column, {
4558
+ /**
4559
+ * @cfg {String} format
4560
+ * A formatting string as used by {@link Date#format} to format a Date for this Column
4561
+ * (defaults to <tt>'m/d/Y'</tt>).
4562
+ */
4563
+ format : 'm/d/Y',
4564
+ constructor: function(cfg){
4565
+ Ext.grid.DateColumn.superclass.constructor.call(this, cfg);
4566
+ this.renderer = Ext.util.Format.dateRenderer(this.format);
4567
+ }
4568
+ });
4569
+
4570
+ /**
4571
+ * @class Ext.grid.TemplateColumn
4572
+ * @extends Ext.grid.Column
4573
+ * <p>A Column definition class which renders a value by processing a {@link Ext.data.Record Record}'s
4574
+ * {@link Ext.data.Record#data data} using a {@link #tpl configured} {@link Ext.XTemplate XTemplate}.
4575
+ * See the {@link Ext.grid.ColumnModel#xtype xtype} config option of {@link Ext.grid.ColumnModel} for more
4576
+ * details.</p>
4577
+ */
4578
+ Ext.grid.TemplateColumn = Ext.extend(Ext.grid.Column, {
4579
+ /**
4580
+ * @cfg {String/XTemplate} tpl
4581
+ * An {@link Ext.XTemplate XTemplate}, or an XTemplate <i>definition string</i> to use to process a
4582
+ * {@link Ext.data.Record Record}'s {@link Ext.data.Record#data data} to produce a column's rendered value.
4583
+ */
4584
+ constructor: function(cfg){
4585
+ Ext.grid.TemplateColumn.superclass.constructor.call(this, cfg);
4586
+ var tpl = typeof Ext.isObject(this.tpl) ? this.tpl : new Ext.XTemplate(this.tpl);
4587
+ this.renderer = function(value, p, r){
4588
+ return tpl.apply(r.data);
4589
+ };
4590
+ this.tpl = tpl;
4591
+ }
4592
+ });
4593
+
4594
+ /*
4595
+ * @property types
4596
+ * @type Object
4597
+ * @member Ext.grid.Column
4598
+ * @static
4599
+ * <p>An object containing predefined Column classes keyed by a mnemonic code which may be referenced
4600
+ * by the {@link Ext.grid.ColumnModel#xtype xtype} config option of ColumnModel.</p>
4601
+ * <p>This contains the following properties</p><div class="mdesc-details"><ul>
4602
+ * <li>gridcolumn : <b>{@link Ext.grid.Column Column constructor}</b></li>
4603
+ * <li>booleancolumn : <b>{@link Ext.grid.BooleanColumn BooleanColumn constructor}</b></li>
4604
+ * <li>numbercolumn : <b>{@link Ext.grid.NumberColumn NumberColumn constructor}</b></li>
4605
+ * <li>datecolumn : <b>{@link Ext.grid.DateColumn DateColumn constructor}</b></li>
4606
+ * <li>templatecolumn : <b>{@link Ext.grid.TemplateColumn TemplateColumn constructor}</b></li>
4607
+ * </ul></div>
4608
+ */
4609
+ Ext.grid.Column.types = {
4610
+ gridcolumn : Ext.grid.Column,
4611
+ booleancolumn: Ext.grid.BooleanColumn,
4612
+ numbercolumn: Ext.grid.NumberColumn,
4613
+ datecolumn: Ext.grid.DateColumn,
4614
+ templatecolumn: Ext.grid.TemplateColumn
4615
+ };/**
4616
+ * @class Ext.grid.RowNumberer
4617
+ * This is a utility class that can be passed into a {@link Ext.grid.ColumnModel} as a column config that provides
4618
+ * an automatic row numbering column.
4619
+ * <br>Usage:<br>
4620
+ <pre><code>
4621
+ // This is a typical column config with the first column providing row numbers
4622
+ var colModel = new Ext.grid.ColumnModel([
4623
+ new Ext.grid.RowNumberer(),
4624
+ {header: "Name", width: 80, sortable: true},
4625
+ {header: "Code", width: 50, sortable: true},
4626
+ {header: "Description", width: 200, sortable: true}
4627
+ ]);
4628
+ </code></pre>
4629
+ * @constructor
4630
+ * @param {Object} config The configuration options
4631
+ */
4632
+ Ext.grid.RowNumberer = function(config){
4633
+ Ext.apply(this, config);
4634
+ if(this.rowspan){
4635
+ this.renderer = this.renderer.createDelegate(this);
4636
+ }
4637
+ };
4638
+
4639
+ Ext.grid.RowNumberer.prototype = {
4640
+ /**
4641
+ * @cfg {String} header Any valid text or HTML fragment to display in the header cell for the row
4642
+ * number column (defaults to '').
4643
+ */
4644
+ header: "",
4645
+ /**
4646
+ * @cfg {Number} width The default width in pixels of the row number column (defaults to 23).
4647
+ */
4648
+ width: 23,
4649
+ /**
4650
+ * @cfg {Boolean} sortable True if the row number column is sortable (defaults to false).
4651
+ * @hide
4652
+ */
4653
+ sortable: false,
4654
+
4655
+ // private
4656
+ fixed:true,
4657
+ menuDisabled:true,
4658
+ dataIndex: '',
4659
+ id: 'numberer',
4660
+ rowspan: undefined,
4661
+
4662
+ // private
4663
+ renderer : function(v, p, record, rowIndex){
4664
+ if(this.rowspan){
4665
+ p.cellAttr = 'rowspan="'+this.rowspan+'"';
4666
+ }
4667
+ return rowIndex+1;
4668
+ }
4669
+ };/**
4670
+ * @class Ext.grid.CheckboxSelectionModel
4671
+ * @extends Ext.grid.RowSelectionModel
4672
+ * A custom selection model that renders a column of checkboxes that can be toggled to select or deselect rows.
4673
+ * @constructor
4674
+ * @param {Object} config The configuration options
4675
+ */
4676
+ Ext.grid.CheckboxSelectionModel = Ext.extend(Ext.grid.RowSelectionModel, {
4677
+
4678
+ /**
4679
+ * @cfg {Boolean} checkOnly <tt>true</tt> if rows can only be selected by clicking on the
4680
+ * checkbox column (defaults to <tt>false</tt>).
4681
+ */
4682
+ /**
4683
+ * @cfg {String} header Any valid text or HTML fragment to display in the header cell for the
4684
+ * checkbox column. Defaults to:<pre><code>
4685
+ * '&lt;div class="x-grid3-hd-checker">&#38;#160;&lt;/div>'</tt>
4686
+ * </code></pre>
4687
+ * The default CSS class of <tt>'x-grid3-hd-checker'</tt> displays a checkbox in the header
4688
+ * and provides support for automatic check all/none behavior on header click. This string
4689
+ * can be replaced by any valid HTML fragment, including a simple text string (e.g.,
4690
+ * <tt>'Select Rows'</tt>), but the automatic check all/none behavior will only work if the
4691
+ * <tt>'x-grid3-hd-checker'</tt> class is supplied.
4692
+ */
4693
+ header: '<div class="x-grid3-hd-checker">&#160;</div>',
4694
+ /**
4695
+ * @cfg {Number} width The default width in pixels of the checkbox column (defaults to <tt>20</tt>).
4696
+ */
4697
+ width: 20,
4698
+ /**
4699
+ * @cfg {Boolean} sortable <tt>true</tt> if the checkbox column is sortable (defaults to
4700
+ * <tt>false</tt>).
4701
+ */
4702
+ sortable: false,
4703
+
4704
+ // private
4705
+ menuDisabled:true,
4706
+ fixed:true,
4707
+ dataIndex: '',
4708
+ id: 'checker',
4709
+
4710
+ constructor: function(){
4711
+ Ext.grid.CheckboxSelectionModel.superclass.constructor.apply(this, arguments);
4712
+
4713
+ if(this.checkOnly){
4714
+ this.handleMouseDown = Ext.emptyFn;
4715
+ }
4716
+ },
4717
+
4718
+ // private
4719
+ initEvents : function(){
4720
+ Ext.grid.CheckboxSelectionModel.superclass.initEvents.call(this);
4721
+ this.grid.on('render', function(){
4722
+ var view = this.grid.getView();
4723
+ view.mainBody.on('mousedown', this.onMouseDown, this);
4724
+ Ext.fly(view.innerHd).on('mousedown', this.onHdMouseDown, this);
4725
+
4726
+ }, this);
4727
+ },
4728
+
4729
+ // private
4730
+ onMouseDown : function(e, t){
4731
+ if(e.button === 0 && t.className == 'x-grid3-row-checker'){ // Only fire if left-click
4732
+ e.stopEvent();
4733
+ var row = e.getTarget('.x-grid3-row');
4734
+ if(row){
4735
+ var index = row.rowIndex;
4736
+ if(this.isSelected(index)){
4737
+ this.deselectRow(index);
4738
+ }else{
4739
+ this.selectRow(index, true);
4740
+ }
4741
+ }
4742
+ }
4743
+ },
4744
+
4745
+ // private
4746
+ onHdMouseDown : function(e, t){
4747
+ if(t.className == 'x-grid3-hd-checker'){
4748
+ e.stopEvent();
4749
+ var hd = Ext.fly(t.parentNode);
4750
+ var isChecked = hd.hasClass('x-grid3-hd-checker-on');
4751
+ if(isChecked){
4752
+ hd.removeClass('x-grid3-hd-checker-on');
4753
+ this.clearSelections();
4754
+ }else{
4755
+ hd.addClass('x-grid3-hd-checker-on');
4756
+ this.selectAll();
4757
+ }
4758
+ }
4759
+ },
4760
+
4761
+ // private
4762
+ renderer : function(v, p, record){
4763
+ return '<div class="x-grid3-row-checker">&#160;</div>';
4764
+ }
4765
+ });