lpmp 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ });