Changeset 6

Show
Ignore:
Timestamp:
08/25/08 01:42:48 (4 years ago)
Author:
tsuckowhomberg
Message:
  • enhancement: CHANGELOG updated
  • fixed: (BufferedGridView?.js) grid would not be repainted correctly if a column was moved: method "onColumnMove()" with appropriate implementation added (fixes google issue 9)
  • fixed: (BufferedGridView?.js) "onRemove()" would not work properly if the end of the data was reached in the visible rect and rows from within that rect are removed. Adjusted "lastRowIndex" to be equal to "rowIndex", and skipped implicit "processRows()" call in "replaceLiveRows()" via passing a new third argument "processRows", which will only call "processRows()" if the argument was not set to false; removed call to "selections.add()" in "processRows()" since selections are already in the "bufferedSelections" property of the selection model, and previously selected records are still part of the "selections"-property of the selection model
  • enhancement: (BufferedGridView?.js) added "options" parameter to be passed to "buffer"-event
  • enhancement: (BufferedGridView?.js) Added functionality for listening to erroneous responses from

buffer-requests. Event "bufferfailure" will now be fired if the store indicated that the proxy's response was erroneous.

  • enhancement: (BufferedGridToolbar?.js) Toolbar is now listening to "bufferfailure"-event and resets the reload-button to "enabled" if necessary.
Location:
trunk
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • trunk/CHANGELOG

    r4 r6  
    1  
     1Version 0.1.1 
     225-August-2008 
     3 
     4- fixes: 
     5 - BufferedGridView: grid would not be repainted correctly if a column was moved: 
     6method "onColumnMove()" with appropriate implementation added (fixes google issue 9); 
     7"onRemove()" would not work properly if the end of the data was reached in the visible 
     8rect and rows from within that rect are removed. Adjusted "lastRowIndex" to be equal to 
     9"rowIndex", and skipped implicit "processRows()" call in "replaceLiveRows()" via passing 
     10a new third argument "processRows", which will only call "processRows()" if the argument 
     11was not set to false; removed call to "selections.add()" in "processRows()" since selections 
     12are already in the "bufferedSelections" property of the selection model, and previously 
     13selected records are still part of the "selections"-property of the selection model. 
     14 
     15 
     16- enhancements: 
     17 - BufferedGridView: Added functionality for listening to erroneous responses from 
     18buffer-requests. Event "bufferfailure" will now be fired if the store indicated that 
     19the proxy's response was erroneous; added "options" parameter to be passed to 
     20"buffer"-event 
     21 
     22 - BufferedGridToolbar: Toolbar is now listening to "bufferfailure"-event and resets 
     23the reload-button to "enabled" if necessary. 
     24 
    225Version 0.1 
    32616-June-2008 
     
    730the passed argument to the appropriate index in the model; updated sources to take 
    831overriden method into account 
    9  - added cfg option "scrollDelay" in BufferedGridView for buffering calls to onLiveScroll  
     32 - added cfg option "scrollDelay" in BufferedGridView for buffering calls to onLiveScroll 
    1033when scroll-event gets fired (thanks to Rich Waters) 
    1134 - BufferedStore: removed custom applySort() implementation due to changes in findInsertIndex 
    12  - BufferedStore: changed findInsertIndex to use parent implementation first, then check  
     35 - BufferedStore: changed findInsertIndex to use parent implementation first, then check 
    1336return value and adjust the index if needed 
    1437 - BufferedStore/BufferedGridView: moved bufferRange-member to BufferedStore 
    1538 - BufferedStore: optimized insert() method in BufferedStore 
    1639 - allowed to add records at position "0" in grid (existing records get shifted down) 
    17   
     40 
    1841- fixes: 
    19  - wrong calculation in BufferedGridView.onLiveScroll (based on lastScrollPosition and actual  
     42 - wrong calculation in BufferedGridView.onLiveScroll (based on lastScrollPosition and actual 
    2043scrollPosition) caused the view sometimes to not re-render some rows 
    2144 - provided bug fix for "ensureVisible: returned x-coordinate does not take the x-position 
  • trunk/src/BufferedGridToolbar.js

    r2 r6  
    22 * Ext.ux.BufferedGridToolbar V1.0 
    33 * Copyright(c) 2007, http://www.siteartwork.de 
    4  *  
     4 * 
    55 * Licensed under the terms of the Open Source LGPL 3.0 
    66 * http://www.gnu.org/licenses/lgpl.html 
     
    1313 * @class Ext.ux.BufferedGridToolbar 
    1414 * @extends Ext.Toolbar 
    15  * A specialized toolbar that is bound to a {@link Ext.ux.grid.BufferedGridView}  
    16  * and provides information about the indexes of the requested data and the buffer  
     15 * A specialized toolbar that is bound to a {@link Ext.ux.grid.BufferedGridView} 
     16 * and provides information about the indexes of the requested data and the buffer 
    1717 * state. 
    1818 * @constructor 
     
    2626     * True to display the displayMsg (defaults to false) 
    2727     */ 
    28      
     28 
    2929    /** 
    3030     * @cfg {String} displayMsg 
     
    3232     */ 
    3333    displayMsg : 'Displaying {0} - {1} of {2}', 
    34      
     34 
    3535    /** 
    3636     * @cfg {String} emptyMsg 
     
    4444     * @param {String} 
    4545     */ 
    46     refreshText : "Refresh",     
    47      
     46    refreshText : "Refresh", 
     47 
    4848    initComponent : function() 
    4949    { 
     
    5858            var msg = totalCount == 0 ? 
    5959                this.emptyMsg : 
    60                 String.format(this.displayMsg, rowIndex+1,  
     60                String.format(this.displayMsg, rowIndex+1, 
    6161                              rowIndex+visibleRows, totalCount); 
    6262            this.displayEl.update(msg); 
    63         }    
     63        } 
    6464    }, 
    6565 
     
    7070    unbind : function(view) 
    7171    { 
    72         view.un('rowremoved',   this.onRowRemoved, this); 
    73         view.un('rowsinserted', this.onRowsInserted, this); 
    74         view.un('beforebuffer', this.beforeBuffer,   this); 
    75         view.un('cursormove',   this.onCursorMove,   this); 
    76         view.un('buffer',       this.onBuffer,       this); 
     72        view.un('rowremoved',    this.onRowRemoved,    this); 
     73        view.un('rowsinserted',  this.onRowsInserted,  this); 
     74        view.un('beforebuffer',  this.beforeBuffer,    this); 
     75        view.un('cursormove',    this.onCursorMove,    this); 
     76        view.un('buffer',        this.onBuffer,        this); 
     77        view.un('bufferfailure', this.onBufferFailure, this); 
    7778        this.view = undefined; 
    7879    }, 
     
    8485    bind : function(view) 
    8586    { 
    86         view.on('rowremoved',   this.onRowRemoved, this); 
    87         view.on('rowsinserted', this.onRowsInserted, this); 
    88         view.on('beforebuffer', this.beforeBuffer,   this); 
    89         view.on('cursormove',   this.onCursorMove,   this); 
    90         view.on('buffer',       this.onBuffer,       this); 
     87        view.on('rowremoved',    this.onRowRemoved,    this); 
     88        view.on('rowsinserted',  this.onRowsInserted,  this); 
     89        view.on('beforebuffer',  this.beforeBuffer,    this); 
     90        view.on('cursormove',    this.onCursorMove,    this); 
     91        view.on('buffer',        this.onBuffer,        this); 
     92        view.on('bufferfailure', this.onBufferFailure, this); 
    9193        this.view = view; 
    92     },     
    93      
    94 // ----------------------------------- Listeners -------------------------------     
     94    }, 
     95 
     96// ----------------------------------- Listeners ------------------------------- 
    9597    onCursorMove : function(view, rowIndex, visibleRows, totalCount) 
    9698    { 
     
    98100    }, 
    99101 
    100     // private     
     102    // private 
    101103    onRowsInserted : function(view, start, end) 
    102104    { 
    103         this.updateInfo(view.rowIndex, Math.min(view.ds.totalLength, view.visibleRows),  
     105        this.updateInfo(view.rowIndex, Math.min(view.ds.totalLength, view.visibleRows), 
    104106                        view.ds.totalLength); 
    105     },     
     107    }, 
    106108 
    107     // private     
     109    // private 
    108110    onRowRemoved : function(view, index, record) 
    109111    { 
    110         this.updateInfo(view.rowIndex, Math.min(view.ds.totalLength, view.visibleRows),  
     112        this.updateInfo(view.rowIndex, Math.min(view.ds.totalLength, view.visibleRows), 
    111113                        view.ds.totalLength); 
    112     },       
     114    }, 
    113115 
    114116    // private 
     
    118120        this.updateInfo(rowIndex, visibleRows, totalCount); 
    119121    }, 
    120      
     122 
     123    // priate 
     124    onBufferFailure : function(view, store, options) 
     125    { 
     126        this.loading.enable(); 
     127    }, 
     128 
    121129    // private 
    122130    onBuffer : function(view, store, rowIndex, visibleRows, totalCount) 
     
    124132        this.loading.enable(); 
    125133        this.updateInfo(rowIndex, visibleRows, totalCount); 
    126     },     
     134    }, 
    127135 
    128     // private     
     136    // private 
    129137    onClick : function(type) 
    130138    { 
     
    147155            handler : this.onClick.createDelegate(this, ["refresh"]) 
    148156        }); 
    149          
     157 
    150158        this.addSeparator(); 
    151          
     159 
    152160        if(this.displayInfo){ 
    153161            this.displayEl = Ext.fly(this.el.dom).createChild({cls:'x-paging-info'}); 
  • trunk/src/BufferedGridView.js

    r4 r6  
    22 * Ext.ux.grid.BufferedGridView V0.1 
    33 * Copyright(c) 2007, http://www.siteartwork.de 
    4  *  
     4 * 
    55 * Licensed under the terms of the Open Source LGPL 3.0 
    66 * http://www.gnu.org/licenses/lgpl.html 
     
    1919Ext.namespace('Ext.ux.grid'); 
    2020Ext.ux.grid.BufferedGridView = function(config) { 
    21      
     21 
    2222    this.addEvents({ 
    2323        /** 
     
    3939         * @param {Number} visibleRows 
    4040         * @param {Number} totalCount 
     41         * @param {Object} options 
    4142         */ 
    4243        'buffer' : true, 
     44        /** 
     45         * @event bufferfailure 
     46         * Fires when buffering failed. 
     47         * @param {Ext.ux.BufferedGridView} this 
     48         * @param {Ext.data.Store} store The store 
     49         * @param {Object} options The options the buffer-request was initiated with 
     50         */ 
     51        'bufferfailure' : true, 
    4352        /** 
    4453         * @event cursormove 
     
    4857         *                          grid absolute to it's position in the model. 
    4958         * @param {Number} visibleRows The number of rows visible in the grid. 
    50          * @param {Number} totalCount              
     59         * @param {Number} totalCount 
    5160         */ 
    5261        'cursormove' : true 
    53          
    54     });    
    55      
    56     /** 
    57      * @cfg {Number} scrollDelay The number of microseconds a call to the  
     62 
     63    }); 
     64 
     65    /** 
     66     * @cfg {Number} scrollDelay The number of microseconds a call to the 
    5867     * onLiveScroll-lisener should be delayed when the scroll event fires 
    5968     */ 
    60      
    61     /** 
    62      * @cfg {Number} bufferSize The number of records that will at least always  
     69 
     70    /** 
     71     * @cfg {Number} bufferSize The number of records that will at least always 
    6372     * be available in the store for rendering. This value will be send to the 
    6473     * server as the <tt>limit</tt> parameter and should not change during the 
    65      * lifetime of a grid component. Note: In a paging grid, this number would  
     74     * lifetime of a grid component. Note: In a paging grid, this number would 
    6675     * indicate the page size. 
    67      * The value should be set high enough to make a userfirendly scrolling  
    68      * possible and should be greater than the sum of {nearLimit} and  
     76     * The value should be set high enough to make a userfirendly scrolling 
     77     * possible and should be greater than the sum of {nearLimit} and 
    6978     * {visibleRows}. Usually, a value in between 150 and 200 is good enough. 
    7079     * A lesser value will more often make the store re-request new data, while 
    7180     * a larger number will make loading times higher. 
    7281     */ 
    73      
     82 
    7483    /** 
    7584     * @cfg {Number} nearLimit This value represents a near value that is responsible 
    76      * for deciding if a request for new data is needed. The lesser the number, the  
     85     * for deciding if a request for new data is needed. The lesser the number, the 
    7786     * more often new data will be requested. The number should be set to a value 
    7887     * that lies in between 1/4 to 1/2 of the {bufferSize}. 
    7988     */ 
    80      
    81     /** 
    82      * @cfg {Number} horizontalScrollOffset The height of a horizontal aligned  
    83      * scrollbar.  The scrollbar is shown if the total width of all visible  
    84      * columns exceeds the width of the grid component.  
     89 
     90    /** 
     91     * @cfg {Number} horizontalScrollOffset The height of a horizontal aligned 
     92     * scrollbar.  The scrollbar is shown if the total width of all visible 
     93     * columns exceeds the width of the grid component. 
    8594     * On Windows XP (IE7, FF2), this value defaults to 16. 
    8695     */ 
    87     this.horizontalScrollOffset = 16;  
    88      
     96    this.horizontalScrollOffset = 16; 
     97 
    8998    /** 
    9099     * @cfg {Object} loadMaskConfig The config of the load mask that will be shown 
     
    92101     */ 
    93102    this.loadMask = false; 
    94      
     103 
    95104    Ext.apply(this, config); 
    96105 
     
    109118            '<div class="x-grid3-resize-proxy">&#160;</div>', 
    110119        "</div>" 
    111     );     
    112      
     120    ); 
     121 
    113122    Ext.ux.grid.BufferedGridView.superclass.constructor.call(this); 
    114123}; 
     
    117126Ext.extend(Ext.ux.grid.BufferedGridView, Ext.grid.GridView, { 
    118127 
    119 // {{{ --------------------------properties-------------------------------------   
     128// {{{ --------------------------properties------------------------------------- 
    120129    /** 
    121130     * This is the actual y-scroller that does control sending request to the server 
     
    124133     */ 
    125134    liveScroller : null, 
    126      
     135 
    127136    /** 
    128137     * This is the panel that represents the amount of data in a given repository. 
     
    132141     */ 
    133142    liveScrollerInset : null, 
    134      
    135     /** 
    136      * The <b>fixed</b> row height for <b>every</b> row in the grid. The value is  
     143 
     144    /** 
     145     * The <b>fixed</b> row height for <b>every</b> row in the grid. The value is 
    137146     * computed once the store has been loaded for the first time and used for 
    138147     * various calculations during the lifetime of the grid component, such as 
     
    141150     */ 
    142151    rowHeight : -1, 
    143      
     152 
    144153    /** 
    145154     * Stores the number of visible rows that have to be rendered. 
     
    147156     */ 
    148157    visibleRows : 1, 
    149      
    150     /** 
    151      * Stores the last offset relative to a previously scroll action. This is  
     158 
     159    /** 
     160     * Stores the last offset relative to a previously scroll action. This is 
    152161     * needed for deciding wether the user scrolls up or down. 
    153162     * @param {Number} 
    154163     */ 
    155164    lastIndex : -1, 
    156       
     165 
    157166    /** 
    158167     * Stores the last visible row at position "0" in the table view before 
     
    161170     */ 
    162171    lastRowIndex : 0, 
    163      
    164     /** 
    165      * Stores the value of the <tt>liveScroller</tt>'s <tt>scrollTop</tt> DOM  
     172 
     173    /** 
     174     * Stores the value of the <tt>liveScroller</tt>'s <tt>scrollTop</tt> DOM 
    166175     * property. 
    167176     * @param {Number} 
    168177     */ 
    169178    lastScrollPos : 0, 
    170      
    171     /** 
    172      * The current index of the row in the model that is displayed as the first  
     179 
     180    /** 
     181     * The current index of the row in the model that is displayed as the first 
    173182     * visible row in the view. 
    174183     * @param {Number} 
    175184     */ 
    176     rowIndex : 0,     
    177      
     185    rowIndex : 0, 
     186 
    178187    /** 
    179188    * Set to <tt>true</tt> if the store is busy with loading new data. 
     
    181190    */ 
    182191    isBuffering : false, 
    183      
     192 
    184193        /** 
    185194         * If a request for new data was made and the user scrolls to a new position 
    186          * that lays not within the requested range of the new data, the queue will  
     195         * that lays not within the requested range of the new data, the queue will 
    187196         * hold the latest requested position. If the buffering succeeds and the value 
    188197         * of requestQueue is not within the range of the current buffer, data may be 
     
    192201         */ 
    193202    requestQueue : -1, 
    194      
     203 
    195204    /** 
    196205     * The view's own load mask that will be shown when a request to data was made 
     
    200209     */ 
    201210    loadMask : null, 
    202      
     211 
    203212    /** 
    204213     * Set to <tt>true</tt> if a request for new data has been made while there 
     
    213222 
    214223    /** 
    215      * Resets the view to display the first row in the data model. This will  
     224     * Resets the view to display the first row in the data model. This will 
    216225     * change the scrollTop property of the scroller and may trigger a request 
    217226     * to buffer new data, if the row index "0" is not within the buffer range and 
     
    234243            this.refresh(true); 
    235244            //this.replaceLiveRows(0, true); 
    236             this.fireEvent('cursormove', this, 0,  
    237                            Math.min(this.ds.totalLength, this.visibleRows),  
     245            this.fireEvent('cursormove', this, 0, 
     246                           Math.min(this.ds.totalLength, this.visibleRows), 
    238247                           this.ds.totalLength); 
    239248        } else { 
    240              
     249 
    241250            var params = { 
    242                     start : 0,  
     251                    start : 0, 
    243252                    limit : this.ds.bufferSize 
    244253            }; 
    245              
     254 
    246255            var sInfo = this.ds.sortInfo; 
    247              
     256 
    248257            if (sInfo) { 
    249258                params.dir  = sInfo.direction; 
    250259                params.sort = sInfo.field; 
    251260            } 
    252              
     261 
    253262            this.ds.load({ 
    254263                callback : function(){this.reset(false);}, 
    255                 scope    : this,  
     264                scope    : this, 
    256265                params   : params 
    257266            }); 
    258267        } 
    259          
     268 
    260269    }, 
    261270 
     
    266275     * 
    267276     * Since detaching a previously created DragZone from a grid panel seems to 
    268      * be impossible, a little workaround will tell the parent implementation  
     277     * be impossible, a little workaround will tell the parent implementation 
    269278     * that drad/drop is not enabled for this view's grid, and right after that 
    270279     * the custom DragZone will be created, if neccessary. 
     
    274283        var g = this.grid; 
    275284        var dEnabled = g.enableDragDrop || g.enableDrag; 
    276          
     285 
    277286        g.enableDragDrop = false; 
    278287        g.enableDrag     = false; 
    279          
     288 
    280289        Ext.ux.grid.BufferedGridView.superclass.renderUI.call(this); 
    281          
     290 
    282291        var g = this.grid; 
    283          
     292 
    284293        g.enableDragDrop = dEnabled; 
    285294        g.enableDrag     = dEnabled; 
    286          
     295 
    287296        if(dEnabled){ 
    288297            var dd = new Ext.ux.grid.BufferedGridDragZone(g, { 
     
    290299            }); 
    291300        } 
    292          
    293          
     301 
     302 
    294303            if (this.loadMask) { 
    295304            this.loadMask = new Ext.LoadMask( 
    296                                 this.mainBody.dom.parentNode.parentNode,  
     305                                this.mainBody.dom.parentNode.parentNode, 
    297306                                this.loadMask 
    298                             );   
     307                            ); 
    299308        } 
    300309    }, 
     
    312321    { 
    313322        Ext.ux.grid.BufferedGridView.superclass.init.call(this, grid); 
    314          
     323 
    315324        this.ds.on('beforeload', this.onBeforeLoad, this); 
    316         },     
    317          
    318          
     325        }, 
     326 
     327 
    319328    /** 
    320329     * Only render the viewable rect of the table. The number of rows visible to 
     
    328337        return this.templates.body.apply({rows: markup}); 
    329338    }, 
    330      
    331     /** 
    332      * Inits the DOM native elements for this component.  
     339 
     340    /** 
     341     * Inits the DOM native elements for this component. 
    333342     * The properties <tt>liveScroller</tt> and <tt>liveScrollerInset</tt> will 
    334343     * be respected as provided by the master template. 
    335      * The <tt>scroll</tt> listener for the <tt>liverScroller</tt> will also be  
     344     * The <tt>scroll</tt> listener for the <tt>liverScroller</tt> will also be 
    336345     * added here as the <tt>mousewheel</tt> listener. 
    337346     * This method overwrites the parents implementation. 
     
    348357 
    349358        this.mainWrap = new E(cs[1]); 
    350          
     359 
    351360        // liveScroller and liveScrollerInset 
    352361        this.liveScroller       = new E(cs[0]); 
    353362        this.liveScrollerInset  = this.liveScroller.dom.firstChild; 
    354363        this.liveScroller.on('scroll', this.onLiveScroll,  this, {buffer : this.scrollDelay}); 
    355          
     364 
    356365            this.mainHd = new E(this.mainWrap.dom.firstChild); 
    357366            this.innerHd = this.mainHd.dom.firstChild; 
     
    364373        // addd the mousewheel event to the table's body 
    365374        this.mainBody.on('mousewheel', this.handleWheel,  this); 
    366          
     375 
    367376            this.focusEl = new E(this.scroller.dom.childNodes[1]); 
    368377        this.focusEl.swallowEvent("click", true); 
     
    371380        this.resizeProxy = new E(cs[3]); 
    372381 
    373     },     
    374      
     382    }, 
     383 
    375384        /** 
    376385         * Layouts the grid's view taking the scroller into account. The height 
     
    378387         * The width of the grid view will be adjusted so the header and the rows do 
    379388         * not overlap the scroller. 
    380          * This method will also compute the row-height based on the first row this  
    381          * grid displays and will adjust the number of visible rows if a resize  
     389         * This method will also compute the row-height based on the first row this 
     390         * grid displays and will adjust the number of visible rows if a resize 
    382391         * of the grid component happened. 
    383392         * This method overwrites the parents implementation. 
    384393         */ 
    385         //private     
     394        //private 
    386395    layout : function() 
    387396    { 
     
    395404 
    396405        var csize = c.getSize(true); 
    397          
     406 
    398407        // set vw to 19 to take scrollbar width into account! 
    399408        var vw = csize.width-this.scrollOffset; 
    400      
     409 
    401410        if(vw < 20 || csize.height < 20){ // display: none? 
    402411            return; 
     
    416425            } 
    417426        } 
    418          
     427 
    419428        if(this.forceFit){ 
    420429            if(this.lastViewWidth != vw){ 
     
    425434            this.autoExpand(); 
    426435        } 
    427          
    428          
     436 
     437 
    429438        // adjust the number of visible rows and the height of the scroller. 
    430439        this.adjustVisibleRows(); 
    431440        this.adjustBufferInset(); 
    432          
    433                                              
     441 
     442 
    434443        this.onLayout(vw, vh); 
    435     },    
     444    }, 
    436445 
    437446// {{{ ----------------------dom/mouse listeners-------------------------------- 
     447 
     448    // private 
     449    onColumnMove : function(cm, oldIndex, newIndex) 
     450    { 
     451        this.indexMap = null; 
     452        this.replaceLiveRows(this.rowIndex, true); 
     453        this.updateHeaders(); 
     454        this.updateHeaderSortState(); 
     455        this.afterMove(newIndex); 
     456    }, 
     457 
     458 
    438459    /** 
    439460     * Called when a column width has been updated. Adjusts the scroller height 
     
    444465    { 
    445466        this.adjustVisibleRows(); 
    446         this.adjustBufferInset();    
    447     }, 
    448      
    449     /** 
    450      * Called when the width of all columns has been updated. Adjusts the scroller  
     467        this.adjustBufferInset(); 
     468    }, 
     469 
     470    /** 
     471     * Called when the width of all columns has been updated. Adjusts the scroller 
    451472     * height and the number of visible rows wether the horizontal scrollbar is shown 
    452473     * or not. 
     
    456477        this.adjustVisibleRows(); 
    457478        this.adjustBufferInset(); 
    458     },   
    459  
    460     /** 
    461      * Callback for selecting a row. The index of the row is the absolute index  
     479    }, 
     480 
     481    /** 
     482     * Callback for selecting a row. The index of the row is the absolute index 
    462483     * in the datamodel and gets translated to the index in the view. 
    463484     * Overwrites the parent's implementation. 
    464      */         
     485     */ 
    465486    // private 
    466487    onRowSelect : function(row) 
     
    469490            return; 
    470491        } 
    471          
     492 
    472493        var viewIndex = row-this.rowIndex; 
    473          
     494 
    474495        this.addRowClass(viewIndex, "x-grid3-row-selected"); 
    475496    }, 
    476497 
    477498    /** 
    478      * Callback for deselecting a row. The index of the row is the absolute index  
     499     * Callback for deselecting a row. The index of the row is the absolute index 
    479500     * in the datamodel and gets translated to the index in the view. 
    480501     * Overwrites the parent's implementation. 
    481      */         
     502     */ 
    482503    // private 
    483504    onRowDeselect : function(row) 
     
    486507            return; 
    487508        } 
    488          
     509 
    489510        var viewIndex = row-this.rowIndex; 
    490          
     511 
    491512        this.removeRowClass(viewIndex, "x-grid3-row-selected"); 
    492513    }, 
    493514 
    494515    /** 
    495      * Callback for selecting a cell. The index of the row is the absolute index  
     516     * Callback for selecting a cell. The index of the row is the absolute index 
    496517     * in the datamodel and gets translated to the index in the view. 
    497518     * Overwrites the parent's implementation. 
    498      */         
     519     */ 
    499520    // private 
    500521    onCellSelect : function(row, col) 
     
    503524            return; 
    504525        } 
    505          
     526 
    506527        var viewIndex = row-this.rowIndex; 
    507          
     528 
    508529        var cell = this.getCell(viewIndex, col); 
    509530        if(cell){ 
     
    513534 
    514535    /** 
    515      * Callback for deselecting a cell. The index of the row is the absolute index  
     536     * Callback for deselecting a cell. The index of the row is the absolute index 
    516537     * in the datamodel and gets translated to the index in the view. 
    517538     * Overwrites the parent's implementation. 
    518      */     
     539     */ 
    519540    // private 
    520541    onCellDeselect : function(row, col) 
     
    523544            return; 
    524545        } 
    525          
     546 
    526547        var viewIndex = row-this.rowIndex; 
    527          
     548 
    528549        var cell = this.getCell(viewIndex, col); 
    529550        if(cell){ 
     
    537558     * view. 
    538559     * Overwrites the parent's implementation. 
    539      */     
     560     */ 
    540561    // private 
    541562    onRowOver : function(e, t) 
     
    562583            this.removeRowClass(viewIndex, "x-grid3-row-over"); 
    563584        } 
    564     },     
     585    }, 
    565586 
    566587 
     
    577598    }, 
    578599 
    579      
    580     /** 
    581      * Callback for the underlying store's remove method. The current  
    582      * implementation does only remove the selected row which record is in the  
     600 
     601    /** 
     602     * Callback for the underlying store's remove method. The current 
     603     * implementation does only remove the selected row which record is in the 
    583604     * current store. 
    584605     * 
     
    587608    onRemove : function(ds, record, index, isUpdate) 
    588609    { 
     610 
    589611        if (index == Number.MIN_VALUE || index == Number.MAX_VALUE) { 
    590612            this.fireEvent("beforerowremoved", this, index, record); 
     
    597619            this.fireEvent("beforerowremoved", this, viewIndex, record); 
    598620        } 
    599          
     621 
    600622        var domLength = this.getRows().length; 
    601          
     623 
    602624        if (viewIndex < this.rowIndex) { 
    603             // if the according row is not displayed within the visible rect of  
     625            // if the according row is not displayed within the visible rect of 
    604626            // the grid, just adjust the row index and the liveScroller 
    605627            this.rowIndex--; 
    606628            this.lastRowIndex = this.rowIndex; 
    607629            this.adjustScrollerPos(-this.rowHeight, true); 
    608             this.fireEvent('cursormove', this, this.rowIndex,  
    609                            Math.min(this.ds.totalLength, this.visibleRows),  
     630            this.fireEvent('cursormove', this, this.rowIndex, 
     631                           Math.min(this.ds.totalLength, this.visibleRows), 
    610632                           this.ds.totalLength); 
    611                             
     633 
    612634        } else if (viewIndex >= this.rowIndex && viewIndex < this.rowIndex+domLength) { 
    613              
     635 
    614636            var lastPossibleRIndex = ((this.rowIndex-this.ds.bufferRange[0])+this.visibleRows)-1; 
    615              
     637 
    616638            var cInd = viewIndex-this.rowIndex; 
    617639            var rec  = this.ds.getAt(this.rowIndex+this.visibleRows-1); 
    618              
     640 
    619641            // did we reach the end of the buffer range? 
    620642            if (rec == null) { 
     
    625647                    } 
    626648                    this.updateLiveRows(this.rowIndex, true, true); 
    627                      
     649 
    628650                    return; 
    629651                } else { 
     
    631653                    // nor in the data store 
    632654                    if (this.rowIndex == 0) { 
    633                         // simply remove the row from the dom 
     655                        // simply remove the row from the end of the dom dom 
    634656                        this.removeRows(cInd, cInd); 
    635                         
     657 
    636658                    } else { 
    637                         // scroll a new row in the rect so the whole rect is filled  
     659                        // scroll a new row in the rect so the whole rect is filled 
    638660                        // with rows 
    639661                        this.rowIndex--; 
     662                        this.lastRowIndex = this.rowIndex; 
    640663                        if (this.rowIndex < this.ds.bufferRange[0]) { 
    641664                            // buffer range is invalid! request new data 
     
    644667                            } 
    645668                            this.updateLiveRows(this.rowIndex); 
    646                             
     669 
    647670                            return; 
    648671                        } else { 
    649                             // still records in the store, simply update the dom 
    650                             this.replaceLiveRows(this.rowIndex); 
    651                              
     672                            // still records in the store, simply update the dom, 
     673                            //but leave processing to this method after the event rowremoved 
     674                            // was fired so the selection store can update properly 
     675                            this.replaceLiveRows(this.rowIndex, true, false); 
    652676                        } 
    653677                    } 
    654678                } 
    655679            } else { 
    656                  
     680 
    657681                // the record is right within the visible rect of the grid. 
    658682                // remove the row that represents the record and append another 
     
    662686                Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html); 
    663687            } 
    664         }     
    665          
     688        } 
     689 
    666690        // a record within the bufferrange was removed, so adjust the buffer 
    667691        // range 
     
    671695            this.fireEvent("rowremoved", this, viewIndex, record); 
    672696        } 
    673          
     697 
    674698        this.processRows(0, undefined, true); 
    675699    }, 
    676700 
    677701    /** 
    678      * The callback for the underlying data store when new data was added.  
    679      * If <tt>index</tt> equals to <tt>Number.MIN_VALUE</tt> or <tt>Number.MAX_VALUE</tt>, the  
     702     * The callback for the underlying data store when new data was added. 
     703     * If <tt>index</tt> equals to <tt>Number.MIN_VALUE</tt> or <tt>Number.MAX_VALUE</tt>, the 
    680704     * method can't tell at which position in the underlying data model the 
    681      * records where added. However, if <tt>index</tt> equals to <tt>Number.MIN_VALUE</tt>,  
     705     * records where added. However, if <tt>index</tt> equals to <tt>Number.MIN_VALUE</tt>, 
    682706     * the <tt>rowIndex</tt> property will be adjusted to <tt>rowIndex+records.length</tt>, 
    683707     * and the <tt>liveScroller</tt>'s properties get adjusted so it matches the 
     
    685709     * The same will happen to any records that get added at the store index which 
    686710     * is currently represented by the first visible row in the view. 
    687      * Any other value will cause the method to compute the number of rows that  
     711     * Any other value will cause the method to compute the number of rows that 
    688712     * have to be (re-)painted and calling the <tt>insertRows</tt> method, if 
    689713     * neccessary. 
    690714     * 
    691715     * This method triggers the <tt>beforerowsinserted</tt> and <tt>rowsinserted</tt> 
    692      * event, passing the indexes of the records as they may default to the  
    693      * positions in the underlying data model. However, due to the fact that  
     716     * event, passing the indexes of the records as they may default to the 
     717     * positions in the underlying data model. However, due to the fact that 
    694718     * any sort algorithm may have computed the indexes of the records, it is 
    695      * not guaranteed that the computed indexes equal to the indexes of the  
     719     * not guaranteed that the computed indexes equal to the indexes of the 
    696720     * underlying data model. 
    697721     * 
    698722     * @param {Ext.ux.grid.BufferedStore} ds The datastore that buffers records 
    699723     *                                       from the underlying data model 
    700      * @param {Array} records An array containing the newly added  
    701      *                        {@link Ext.data.Record}s  
     724     * @param {Array} records An array containing the newly added 
     725     *                        {@link Ext.data.Record}s 
    702726     * @param {Number} index The index of the position in the underlying 
    703727     *                       {@link Ext.ux.grid.BufferedStore} where the rows 
     
    708732    { 
    709733        var recordLen = records.length; 
    710          
    711         // values of index which equal to Number.MIN_VALUE or Number.MAX_VALUE  
    712         // indicate that the records were not added to the store. The component  
     734 
     735        // values of index which equal to Number.MIN_VALUE or Number.MAX_VALUE 
     736        // indicate that the records were not added to the store. The component 
    713737        // does not know which index those records do have in the underlying 
    714738        // data model 
    715739        if (index == Number.MAX_VALUE || index == Number.MIN_VALUE) { 
    716740            this.fireEvent("beforerowsinserted", this, index, index); 
    717              
     741 
    718742            // if index equals to Number.MIN_VALUE, shift rows! 
    719743            if (index == Number.MIN_VALUE) { 
    720                  
     744 
    721745                this.rowIndex     = this.rowIndex + recordLen; 
    722746                this.lastRowIndex = this.rowIndex; 
    723                  
    724                 this.adjustBufferInset();                
     747 
     748                this.adjustBufferInset(); 
    725749                this.adjustScrollerPos(this.rowHeight*recordLen, true); 
    726                  
     750 
    727751                this.fireEvent("rowsinserted", this, index, index); 
    728752                this.processRows(); 
    729753                // the cursor did virtually move 
    730                 this.fireEvent('cursormove', this, this.rowIndex,  
    731                                Math.min(this.ds.totalLength, this.visibleRows),  
     754                this.fireEvent('cursormove', this, this.rowIndex, 
     755                               Math.min(this.ds.totalLength, this.visibleRows), 
    732756                               this.ds.totalLength); 
    733                  
     757 
    734758                return; 
    735759            } 
    736              
     760 
    737761            this.adjustBufferInset(); 
    738762            this.fireEvent("rowsinserted", this, index, index); 
    739             return;             
    740         } 
    741          
     763            return; 
     764        } 
     765 
    742766        // only insert the rows which affect the current view. 
    743767        var start = index+this.ds.bufferRange[0]; 
    744768        var end   = start + (recordLen-1); 
    745769        var len   = this.getRows().length; 
    746          
     770 
    747771        var firstRow = 0; 
    748772        var lastRow  = 0; 
    749          
    750         // rows would be added at the end of the rows which are currently  
     773 
     774        // rows would be added at the end of the rows which are currently 
    751775        // displayed, so fire the evnt and return 
    752776        if (index >= (this.rowIndex-this.ds.bufferRange[0])+len && len == this.visibleRows) { 
    753             this.fireEvent("beforerowsinserted", this, start, end);     
    754             this.fireEvent("rowsinserted", this, start, end);     
    755              
     777            this.fireEvent("beforerowsinserted", this, start, end); 
     778            this.fireEvent("rowsinserted", this, start, end); 
     779 
    756780            this.adjustVisibleRows(); 
    757781            this.adjustBufferInset(); 
    758              
    759         }  
    760          
     782 
     783        } 
     784 
    761785        // we are all up in the grid, first row is first record, 
    762786        // prepend! 
     
    767791            this.rowIndex      = 0; 
    768792            this.insertRows(ds, firstRow, lastRow); 
    769             
     793 
    770794            this.adjustVisibleRows(); 
    771795            this.adjustBufferInset(); 
    772796        } 
    773          
     797 
    774798        // rows get added before the first row in the view 
    775799        else if (len == this.visibleRows && index <= this.rowIndex-this.ds.bufferRange[0]) { 
    776              
    777             this.fireEvent("beforerowsinserted", this, start, end);     
     800 
     801            this.fireEvent("beforerowsinserted", this, start, end); 
    778802            this.liveScroller.un('scroll', this.onLiveScroll, this); 
    779803            this.rowIndex     = this.rowIndex+recordLen; 
    780804            this.lastRowIndex = this.rowIndex; 
    781              
     805 
    782806            this.adjustVisibleRows(); 
    783807            this.adjustBufferInset(); 
    784              
     808 
    785809            this.adjustScrollerPos(this.rowHeight*recordLen, true); 
    786              
    787             this.fireEvent("rowsinserted", this, start, end);  
     810 
     811            this.fireEvent("rowsinserted", this, start, end); 
    788812            this.processRows(); 
    789             this.fireEvent('cursormove', this, this.rowIndex,  
    790                            Math.min(this.ds.totalLength, this.visibleRows),  
    791                            this.ds.totalLength);   
    792         } 
    793          
     813            this.fireEvent('cursormove', this, this.rowIndex, 
     814                           Math.min(this.ds.totalLength, this.visibleRows), 
     815                           this.ds.totalLength); 
     816        } 
     817 
    794818        // rows get added somewhere IN the current view 
    795819        else if ((len < this.visibleRows ) || index > this.rowIndex-this.ds.bufferRange[0]) { 
    796820            firstRow = index; 
    797821            lastRow  = Math.min(end, this.rowIndex+this.visibleRows-1) - this.ds.bufferRange[0]; 
    798             this.insertRows(ds, firstRow, lastRow);  
    799              
     822            this.insertRows(ds, firstRow, lastRow); 
     823 
    800824            this.adjustVisibleRows(); 
    801825            this.adjustBufferInset(); 
    802              
    803         } 
    804          
    805          
    806          
    807          
    808     }, 
    809  
    810 // {{{ ----------------------store listeners------------------------------------     
     826 
     827        } 
     828 
     829 
     830 
     831 
     832    }, 
     833 
     834// {{{ ----------------------store listeners------------------------------------ 
    811835    /** 
    812836     * This callback for the store's "beforeload" event will adjust the start 
    813837     * position and the limit of the data in the model to fetch. It is guaranteed 
    814      * that this method will only be called when the store initially loads,  
     838     * that this method will only be called when the store initially loads, 
    815839     * remeote-sorts or reloads. 
    816840     * All other load events will be suspended when the view requests buffer data. 
     
    824848    { 
    825849        if (!options.params) { 
    826             options.params = {start : 0, limit : this.ds.bufferSize};     
     850            options.params = {start : 0, limit : this.ds.bufferSize}; 
    827851        } else { 
    828852            options.params.start = 0; 
    829853            options.params.limit = this.ds.bufferSize; 
    830854        } 
    831          
     855 
    832856        options.scope    = this; 
    833857        options.callback = function(){this.reset(false);}; 
    834          
     858 
    835859        return true; 
    836860    }, 
    837      
     861 
    838862    /** 
    839863     * Method is used as a callback for the load-event of the attached data store. 
    840      * Adjusts the buffer inset based upon the <tt>totalCount</tt> property  
     864     * Adjusts the buffer inset based upon the <tt>totalCount</tt> property 
    841865     * returned by the response. 
    842866     * Overwrites the parent's implementation. 
     
    846870        this.adjustBufferInset(); 
    847871    }, 
    848      
    849     /** 
    850      * This will be called when the data in the store has changed, i.e. a  
    851      * re-buffer has occured. If the table was not rendered yet, a call to  
    852      * <tt>refresh</tt> will initially render the table, which DOM elements will  
     872 
     873    /** 
     874     * This will be called when the data in the store has changed, i.e. a 
     875     * re-buffer has occured. If the table was not rendered yet, a call to 
     876     * <tt>refresh</tt> will initially render the table, which DOM elements will 
    853877     * then be used to re-render the table upon scrolling. 
    854878     * 
     
    858882    { 
    859883        this.updateHeaderSortState(); 
    860     },    
    861      
     884    }, 
     885 
    862886    /** 
    863887     * A callback for the store when new data has been buffered successfully. 
    864      * If the current row index is not within the range of the newly created  
    865      * data buffer or another request to new data has been made while the store  
     888     * If the current row index is not within the range of the newly created 
     889     * data buffer or another request to new data has been made while the store 
    866890     * was loading, new data will be re-requested. 
    867891     * 
     
    869893     * in the data store, the method will request the pending selections from 
    870894     * the grid's selection model and add them to the selections if available. 
    871      * This is because the component assumes that a user who scrolls through the  
    872      * rows and updates the view's buffer during scrolling, can check the selected  
    873      * rows which come into the view for integrity. It is up to the user to  
     895     * This is because the component assumes that a user who scrolls through the 
     896     * rows and updates the view's buffer during scrolling, can check the selected 
     897     * rows which come into the view for integrity. It is up to the user to 
    874898     * deselect those rows not matchuing the selection. 
    875899     * Additionally, if the version of the store changes during various requests 
    876      * and selections are still pending, the versionchange event of the store  
    877      * can delete the pending selections after a re-bufer happened and before this  
     900     * and selections are still pending, the versionchange event of the store 
     901     * can delete the pending selections after a re-bufer happened and before this 
    878902     * method was called. 
    879903     * 
    880904     */ 
    881905    // private 
    882     liveBufferUpdate : function(o1, options, o2) 
    883     { 
    884         this.fireEvent('buffer', this, this.ds, this.rowIndex,  
    885                        Math.max(this.visibleRows, this.getRows().length),  
    886                        this.ds.getTotalCount()); 
     906    liveBufferUpdate : function(records, options, success) 
     907    { 
     908        if (success === true) { 
     909            this.fireEvent('buffer', this, this.ds, this.rowIndex, 
     910                Math.max(this.visibleRows, this.getRows().length), 
     911                this.ds.getTotalCount(), 
     912                options 
     913            ); 
     914 
     915            this.isBuffering    = false; 
     916            this.isPrebuffering = false; 
     917            this.showLoadMask(false); 
     918 
     919            var pendingSelections = this.grid.selModel.getPendingSelections(false); 
     920 
     921            for (var i = 0, max_i = pendingSelections.length; i < max_i; i++) { 
     922                this.grid.selModel.clearPendingSelection(pendingSelections[i]); 
     923            } 
     924 
     925            if (this.isInRange(this.rowIndex)) { 
     926                this.replaceLiveRows(this.rowIndex); 
     927            } else { 
     928                this.updateLiveRows(this.rowIndex); 
     929            } 
     930 
     931            if (this.requestQueue >= 0) { 
     932                var offset = this.requestQueue; 
     933                this.requestQueue = -1; 
     934                this.updateLiveRows(offset); 
     935            } 
     936 
     937            return; 
     938        } else { 
     939            this.fireEvent('bufferfailure', this, this.ds, options); 
     940        } 
     941 
     942        this.requestQueue   = -1; 
    887943        this.isBuffering    = false; 
    888944        this.isPrebuffering = false; 
    889945        this.showLoadMask(false); 
    890          
    891         var pendingSelections = this.grid.selModel.getPendingSelections(false); 
    892          
    893         for (var i = 0, max_i = pendingSelections.length; i < max_i; i++) { 
    894             this.grid.selModel.clearPendingSelection(pendingSelections[i]);     
    895         } 
    896          
    897         if (this.isInRange(this.rowIndex)) { 
    898             this.replaceLiveRows(this.rowIndex); 
    899         } else { 
    900             this.updateLiveRows(this.rowIndex); 
    901         } 
    902          
    903         if (this.requestQueue >= 0) { 
    904             var offset = this.requestQueue; 
    905             this.requestQueue = -1; 
    906             this.updateLiveRows(offset); 
    907         } 
    908     }, 
    909          
    910      
    911 // {{{ ----------------------scroll listeners------------------------------------        
     946    }, 
     947 
     948 
     949// {{{ ----------------------scroll listeners------------------------------------ 
    912950    /** 
    913951     * Handles mousewheel event on the table's body. This is neccessary since the 
     
    919957    { 
    920958        if (this.rowHeight == -1) { 
    921             e.stopEvent();           
     959            e.stopEvent(); 
    922960            return; 
    923961        } 
    924962        var d = e.getWheelDelta(); 
    925          
     963 
    926964        this.adjustScrollerPos(-(d*this.rowHeight)); 
    927                
    928         e.stopEvent();           
    929     }, 
    930      
     965 
     966        e.stopEvent(); 
     967    }, 
     968 
    931969    /** 
    932970     * Handles scrolling through the grid. Since the grid is fixed and rows get 
     
    938976    onLiveScroll : function() 
    939977    { 
    940         var scrollTop     = this.liveScroller.dom.scrollTop;  
    941          
     978        var scrollTop     = this.liveScroller.dom.scrollTop; 
     979 
    942980        var cursor = Math.floor((scrollTop)/this.rowHeight); 
    943981        this.rowIndex = cursor; 
     
    946984            return; 
    947985        } 
    948          
     986 
    949987        this.updateLiveRows(cursor); 
    950         this.lastScrollPos = this.liveScroller.dom.scrollTop;  
    951     },     
    952      
    953     
    954      
     988        this.lastScrollPos = this.liveScroller.dom.scrollTop; 
     989    }, 
     990 
     991 
     992 
    955993// {{{ --------------------------helpers---------------------------------------- 
    956994 
     
    9651003            index = ds.indexOf(record); 
    9661004        } 
    967          
     1005 
    9681006        var viewIndex = index + this.ds.bufferRange[0]; 
    969          
     1007 
    9701008        if (viewIndex < this.rowIndex || viewIndex >= this.rowIndex + this.visibleRows) { 
    9711009            this.fireEvent("rowupdated", this, viewIndex, record); 
    9721010            return; 
    9731011        } 
    974          
     1012 
    9751013        this.insertRows(ds, index, index, true); 
    9761014        //this.getRow(index).rowIndex = index; 
     
    9941032        var cls = ' x-grid3-row-alt '; 
    9951033        var cursor = this.rowIndex; 
    996          
     1034 
    9971035        var index      = 0; 
    9981036        var selections = this.grid.selModel.selections; 
     
    10031041            // changed! 
    10041042            row.rowIndex = index; 
    1005              
     1043 
    10061044            if (paintSelections == true) { 
    10071045                if (this.grid.selModel.bufferedSelections[index] === true) { 
    10081046                    this.addRowClass(i, "x-grid3-row-selected"); 
    1009                     selections.add(ds.getAt(index));      
    10101047                } 
    10111048                this.fly(row).removeClass("x-grid3-row-over"); 
    10121049            } 
    1013              
     1050 
    10141051            if(!skipStripe){ 
    10151052                var isAlt = ((i+1) % 2 == 0); 
     
    10291066    /** 
    10301067     * API only, since the passed arguments are the indexes in the buffer store. 
    1031      * However, the method will try to compute the indexes so they might match  
     1068     * However, the method will try to compute the indexes so they might match 
    10321069     * the indexes of the records in the underlying data model. 
    10331070     * 
     
    10381075        var viewIndexFirst = firstRow + this.ds.bufferRange[0]; 
    10391076        var viewIndexLast  = lastRow  + this.ds.bufferRange[0]; 
    1040          
     1077 
    10411078        if (!isUpdate) { 
    10421079            this.fireEvent("beforerowsinserted", this, viewIndexFirst, viewIndexLast); 
    10431080        } 
    1044          
    1045         // first off, remove the rows at the bottom of the view to match the  
     1081 
     1082        // first off, remove the rows at the bottom of the view to match the 
    10461083        // visibleRows value and to not cause any spill in the DOM 
    10471084        if (isUpdate !== true && this.getRows().length == this.visibleRows) { 
    10481085            this.removeRows((this.visibleRows-1)-(lastRow-firstRow), this.visibleRows-1); 
    10491086        } 
    1050          
     1087 
    10511088        if (isUpdate) { 
    10521089            this.removeRows(viewIndexFirst-this.rowIndex, viewIndexLast-this.rowIndex); 
    10531090        } 
    1054          
     1091 
    10551092        var html   = this.renderRows(firstRow, lastRow); 
    1056      
     1093 
    10571094        var before = this.getRow(firstRow-(this.rowIndex-this.ds.bufferRange[0])); 
    1058          
     1095 
    10591096        if (before) { 
    10601097            Ext.DomHelper.insertHtml('beforeBegin', before, html); 
     
    10621099            Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html); 
    10631100        } 
    1064          
    1065          
    1066          
     1101 
     1102 
     1103 
    10671104        if (isUpdate === true) { 
    10681105            var rows   = this.getRows(); 
    10691106            var cursor = this.rowIndex; 
    10701107            for (var i = 0, max_i = rows.length; i < max_i; i++) { 
    1071                 rows[i].rowIndex = cursor+i;     
    1072             } 
    1073         } 
    1074          
     1108                rows[i].rowIndex = cursor+i; 
     1109            } 
     1110        } 
     1111 
    10751112        if (!isUpdate) { 
    10761113            this.fireEvent("rowsinserted", this, viewIndexFirst, viewIndexLast); 
     
    10781115        } 
    10791116    }, 
    1080     
     1117 
    10811118    /** 
    10821119     * Focuses the specified cell. 
     
    10911128                } 
    10921129                this.focusEl.setXY(xy); 
    1093          
     1130 
    10941131        if(Ext.isGecko){ 
    10951132            this.focusEl.focus(); 
     
    10971134            this.focusEl.focus.defer(1, this.focusEl); 
    10981135        } 
    1099          
     1136 
    11001137    }, 
    11011138 
     
    11121149            row = row.rowIndex; 
    11131150        } 
    1114          
     1151 
    11151152        if(row < 0 || row >= this.ds.totalLength){ 
    11161153            return; 
    11171154        } 
    1118          
     1155 
    11191156        col = (col !== undefined ? col : 0); 
    1120          
     1157 
    11211158        var rowInd = row-this.rowIndex; 
    11221159        if (row >= this.rowIndex+this.visibleRows) { 
     
    11241161        } else if (row <= this.rowIndex) { 
    11251162            this.adjustScrollerPos((rowInd)*this.rowHeight); 
    1126         }  
     1163        } 
    11271164        var rowInd = rowInd < 0 ? row : rowInd; 
    11281165        var rowEl = this.getRow(rowInd), cellEl; 
    1129          
     1166 
    11301167        if(!(hscroll === false && col === 0)){ 
    11311168            while(this.cm.isHidden(col)){ 
     
    11371174            return; 
    11381175        } 
    1139          
     1176 
    11401177        var c = this.scroller.dom; 
    1141          
    1142         return cellEl ?  
    1143             Ext.fly(cellEl).getXY() :  
     1178 
     1179        return cellEl ? 
     1180            Ext.fly(cellEl).getXY() : 
    11441181            [c.scrollLeft+this.el.getX(), Ext.fly(rowEl).getY()]; 
    1145     },    
    1146  
    1147     
    1148     /** 
    1149      * Checks if the passed argument <tt>cursor</tt> lays within a renderable  
    1150      * area. The area is renderable, if the sum of cursor and the visibleRows  
     1182    }, 
     1183 
     1184 
     1185    /** 
     1186     * Checks if the passed argument <tt>cursor</tt> lays within a renderable 
     1187     * area. The area is renderable, if the sum of cursor and the visibleRows 
    11511188     * property does not exceed the current upper buffer limit. 
    11521189     * 
     
    11631200    isInRange : function(rowIndex) 
    11641201    { 
    1165         var lastRowIndex = Math.min(this.ds.totalLength-1,  
     1202        var lastRowIndex = Math.min(this.ds.totalLength-1, 
    11661203                                    rowIndex + this.visibleRows); 
    1167         return (rowIndex     >= this.ds.bufferRange[0]) &&  
    1168                (lastRowIndex <= this.ds.bufferRange[1]);  
    1169     }, 
    1170  
    1171     /** 
    1172      * Calculates the bufferRange start index for a buffer request  
     1204        return (rowIndex     >= this.ds.bufferRange[0]) && 
     1205               (lastRowIndex <= this.ds.bufferRange[1]); 
     1206    }, 
     1207 
     1208    /** 
     1209     * Calculates the bufferRange start index for a buffer request 
    11731210     * 
    11741211     * @param {Boolean} inRange If the index is within the current buffer range 
     
    11841221            return Math.max(0, (index-this.ds.bufferSize)+this.visibleRows); 
    11851222        } 
    1186          
     1223 
    11871224        if (down) { 
    11881225            return Math.max(0, Math.min(index, this.ds.totalLength-this.ds.bufferSize)); 
    11891226        } 
    11901227    }, 
    1191      
    1192      
    1193     /** 
    1194      * Updates the table view. Removes/appends rows as needed and fetches the  
     1228 
     1229 
     1230    /** 
     1231     * Updates the table view. Removes/appends rows as needed and fetches the 
    11951232     * cells content out of the available store. If the needed rows are not within 
    11961233     * the buffer, the method will advise the store to update it's contents. 
     
    12001237     * 
    12011238     * @param {Number} cursor The row's position, absolute to it's position in the 
    1202      *                        data model  
    1203      * 
    1204      */ 
    1205     updateLiveRows: function(index, forceRepaint, forceReload)  
    1206     { 
    1207         this.fireEvent('cursormove', this, index,  
    1208                        Math.min(this.ds.totalLength, this.visibleRows),  
     1239     *                        data model 
     1240     * 
     1241     */ 
     1242    updateLiveRows: function(index, forceRepaint, forceReload) 
     1243    { 
     1244        this.fireEvent('cursormove', this, index, 
     1245                       Math.min(this.ds.totalLength, this.visibleRows), 
    12091246                       this.ds.totalLength); 
    1210          
     1247 
    12111248        var inRange = this.isInRange(index); 
    1212          
     1249 
    12131250        if (this.isBuffering && this.isPrebuffering) { 
    12141251            if (inRange) { 
    1215                 this.replaceLiveRows(index);    
     1252                this.replaceLiveRows(index); 
    12161253            } else { 
    12171254                this.showLoadMask(true); 
     
    12221259            return; 
    12231260        } 
    1224          
     1261 
    12251262        var lastIndex  = this.lastIndex; 
    12261263        this.lastIndex = index; 
    12271264        var inRange    = this.isInRange(index); 
    1228          
     1265 
    12291266        var down = false; 
    1230          
     1267 
    12311268        if (inRange && forceReload !== true) { 
    1232              
    1233             // repaint the table's view  
     1269 
     1270            // repaint the table's view 
    12341271            this.replaceLiveRows(index, forceRepaint); 
    1235              
    1236             // lets decide if we can void this method or stay in here for  
     1272 
     1273            // lets decide if we can void this method or stay in here for 
    12371274            // requesting a buffer update 
    12381275            if (index > lastIndex) { // scrolling down 
    1239                  
     1276 
    12401277                down = true; 
    12411278                var totalCount = this.ds.totalLength; 
    1242                  
     1279 
    12431280                // while scrolling, we have not yet reached the row index 
    12441281                // that would trigger a re-buffer 
     
    12461283                    return; 
    12471284                } 
    1248                 
     1285 
    12491286                // If we have already buffered the last range we can ever get 
    12501287                // by the queried data repository, we don't need to buffer again. 
     
    12551292                } 
    12561293            } else if (index < lastIndex) { // scrolling up 
    1257                  
     1294 
    12581295                down = false; 
    12591296                // We are scrolling up in the first buffer range we can ever get 
     
    12621299                    return; 
    12631300                } 
    1264                  
    1265                 // if we are scrolling up and we are moving in an acceptable  
    1266                 // buffer range, lets return.  
     1301 
     1302                // if we are scrolling up and we are moving in an acceptable 
     1303                // buffer range, lets return. 
    12671304                if (index - this.nearLimit > this.ds.bufferRange[0]) { 
    12681305                    return; 
     
    12711308                return; 
    12721309            } 
    1273              
     1310 
    12741311            this.isPrebuffering = true; 
    12751312        } 
    1276      
     1313 
    12771314        // prepare for rebuffering 
    12781315        this.isBuffering = true 
    1279      
     1316 
    12801317        var bufferOffset = this.getPredictedBufferIndex(index, inRange, down); 
    12811318        var fetchSize    = this.ds.bufferSize; 
    1282          
     1319 
    12831320        if (!inRange) { 
    12841321            this.showLoadMask(true); 
    12851322        } 
    1286          
    1287         this.fireEvent('beforebuffer', this, this.ds, index,  
     1323 
     1324        this.fireEvent('beforebuffer', this, this.ds, index, 
    12881325                       this.visibleRows, this.ds.totalLength); 
    1289          
     1326 
    12901327        this.ds.suspendEvents(); 
    12911328        var sInfo  = this.ds.sortInfo; 
    1292          
     1329 
    12931330        var params = {}; 
    12941331        if (this.ds.lastOptions) { 
     
    12971334        params.start = bufferOffset; 
    12981335        params.limit = this.ds.bufferSize; 
    1299          
     1336 
    13001337        if (sInfo) { 
    13011338            params.dir  = sInfo.direction; 
     
    13081345        }); 
    13091346        this.ds.resumeEvents(); 
    1310     },     
    1311      
     1347    }, 
     1348 
    13121349    /** 
    13131350     * Shows this' view own load mask to indicate that a large amount of buffer 
     
    13201357        if (this.loadMask == null) { 
    13211358            if (show) { 
    1322                 this.loadMask = new Ext.LoadMask(this.mainBody.dom.parentNode.parentNode,  
    1323                                 this.loadMaskConfig);     
     1359                this.loadMask = new Ext.LoadMask(this.mainBody.dom.parentNode.parentNode, 
     1360                                this.loadMaskConfig); 
    13241361            } else { 
    13251362                return; 
    13261363            } 
    1327         }  
    1328          
     1364        } 
     1365 
    13291366        if (show) { 
    13301367            this.loadMask.show(); 
     
    13331370        } 
    13341371    }, 
    1335   
    1336     /** 
    1337      * Renders the table body with the contents of the model. The method will  
     1372 
     1373    /** 
     1374     * Renders the table body with the contents of the model. The method will 
    13381375     * prepend/ append rows after removing from either the end or the beginning 
    13391376     * of the table DOM to reduce expensive DOM calls. 
     
    13431380     * Instead of calling this method directly, the <tt>updateLiveRows</tt> method 
    13441381     * should be called which takes care of rebuffering if needed, since this method 
    1345      * will behave erroneous if data of the buffer is requested which may not be  
     1382     * will behave erroneous if data of the buffer is requested which may not be 
    13461383     * available. 
    1347      *  
    1348      * @param {Number} cursor The position of the data in the model to start  
     1384     * 
     1385     * @param {Number} cursor The position of the data in the model to start 
    13491386     *                        rendering. 
    13501387     * 
     
    13531390     */ 
    13541391    // private 
    1355     replaceLiveRows : function(cursor, forceReplace) 
    1356     {    
     1392    replaceLiveRows : function(cursor, forceReplace, processRows) 
     1393    { 
    13571394        var spill = cursor-this.lastRowIndex; 
    1358          
     1395 
    13591396        if (spill == 0 && forceReplace !== true) { 
    13601397            return; 
    1361         }         
    1362          
     1398        } 
     1399 
    13631400        // decide wether to prepend or append rows 
    1364         // if spill is negative, we are scrolling up. Thus we have to prepend  
    1365         // rows. If spill is positive, we have to append the buffers data.         
     1401        // if spill is negative, we are scrolling up. Thus we have to prepend 
     1402        // rows. If spill is positive, we have to append the buffers data. 
    13661403        var append = spill > 0; 
    1367          
     1404 
    13681405        // abs spill for simplyfiying append/prepend calculations 
    13691406        spill = Math.abs(spill); 
    1370          
     1407 
    13711408        // adjust cursor to the buffered model index 
    13721409        var cursorBuffer = cursor-this.ds.bufferRange[0]; 
    1373           
     1410 
    13741411        // we can skip checking for append or prepend if the spill is larger than 
    13751412        // visibleRows. We can paint the whole rows new then- 
    13761413        if (spill >= this.visibleRows || spill == 0) { 
    13771414            this.mainBody.update(this.renderRows( 
    1378                 cursorBuffer,  
     1415                cursorBuffer, 
    13791416                cursorBuffer+this.visibleRows-1 
    1380             ));     
     1417            )); 
    13811418        } else { 
    13821419            if (append) { 
    13831420                this.removeRows(0, spill-1); 
    1384                 var html = this.renderRows(cursorBuffer+this.visibleRows-spill,  
     1421                var html = this.renderRows(cursorBuffer+this.visibleRows-spill, 
    13851422                           cursorBuffer+this.visibleRows-1); 
    13861423                Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html); 
    13871424            } else { 
    1388                 this.removeRows(this.visibleRows-spill, this.visibleRows-1);     
     1425                this.removeRows(this.visibleRows-spill, this.visibleRows-1); 
    13891426                var html = this.renderRows(cursorBuffer, cursorBuffer+spill-1); 
    13901427                Ext.DomHelper.insertHtml('beforeBegin', this.mainBody.dom.firstChild, html); 
    13911428            } 
    13921429        } 
    1393          
    1394         this.processRows(0, undefined, true); 
     1430 
     1431        if (processRows !== false) { 
     1432            this.processRows(0, undefined, true); 
     1433        } 
    13951434        this.lastRowIndex = cursor; 
    13961435    }, 
    1397      
    1398  
    1399      
    1400     /** 
    1401     * Adjusts the scroller height to make sure each row in the dataset will be  
    1402     * can be displayed, no matter which value the current height of the grid  
     1436 
     1437 
     1438 
     1439    /** 
     1440    * Adjusts the scroller height to make sure each row in the dataset will be 
     1441    * can be displayed, no matter which value the current height of the grid 
    14031442    * component equals to. 
    14041443    */ 
     
    14071446    { 
    14081447        var g = this.grid, ds = g.store; 
    1409          
     1448 
    14101449        var c  = g.getGridEl(); 
    14111450 
    14121451        var scrollbar = this.cm.getTotalWidth()+this.scrollOffset > c.getSize().width; 
    1413          
     1452 
    14141453        // adjust the height of the scrollbar 
    1415         this.liveScroller.dom.style.height = this.liveScroller.dom.parentNode.offsetHeight +  
    1416                                              (Ext.isGecko  
     1454        this.liveScroller.dom.style.height = this.liveScroller.dom.parentNode.offsetHeight + 
     1455                                             (Ext.isGecko 
    14171456                                             ? ((ds.totalLength > 0 && scrollbar) 
    14181457                                                ? - this.horizontalScrollOffset 
    14191458                                                : 0) 
    14201459                                             : (((ds.totalLength > 0 && scrollbar) 
    1421                                                 ? 0 : this.horizontalScrollOffset)))+"px";                 
     1460                                                ? 0 : this.horizontalScrollOffset)))+"px"; 
    14221461        if (this.rowHeight == -1) { 
    14231462            return; 
    14241463        } 
    1425                 
     1464 
    14261465        if (ds.totalLength <= this.visibleRows) { 
    14271466            this.liveScrollerInset.style.height = "0px"; 
    14281467            return; 
    1429         }  
    1430          
     1468        } 
     1469 
    14311470        var height = this.rowHeight*ds.totalLength; 
    1432          
     1471 
    14331472        height += (c.getSize().height-(this.visibleRows*this.rowHeight)); 
    1434          
     1473 
    14351474        if (scrollbar) { 
    14361475            height -= this.horizontalScrollOffset; 
    14371476        } 
    1438          
     1477 
    14391478        this.liveScrollerInset.style.height = (height)+"px"; 
    14401479    }, 
    1441      
     1480 
    14421481    /** 
    14431482     * Recomputes the number of visible rows in the table based upon the height 
    1444      * of the component. The method adjusts the <tt>rowIndex</tt> property as  
    1445      * needed, if the sum of visible rows and the current row index exceeds the  
     1483     * of the component. The method adjusts the <tt>rowIndex</tt> property as 
     1484     * needed, if the sum of visible rows and the current row index exceeds the 
    14461485     * number of total data available. 
    14471486     */ 
     
    14511490        if (this.rowHeight == -1) { 
    14521491            if (this.getRows()[0]) { 
    1453                 this.rowHeight = this.getRows()[0].offsetHeight;  
     1492                this.rowHeight = this.getRows()[0].offsetHeight; 
    14541493            } else { 
    14551494                return; 
    14561495            } 
    1457         }  
    1458          
    1459          
     1496        } 
     1497 
     1498 
    14601499        var g = this.grid, ds = g.store; 
    1461          
     1500 
    14621501        var c    = g.getGridEl(); 
    14631502        var cm   = this.cm; 
    14641503        var size = c.getSize(true); 
    1465         var vh   = size.height;     
    1466          
    1467         var vw = size.width-this.scrollOffset;         
     1504        var vh   = size.height; 
     1505 
     1506        var vw = size.width-this.scrollOffset; 
    14681507        // horizontal scrollbar shown? 
    14691508        if (cm.getTotalWidth() > vw) { 
    14701509            // yes! 
    14711510            vh -= this.horizontalScrollOffset; 
    1472         }         
    1473          
     1511        } 
     1512 
    14741513        vh -= this.mainHd.getHeight(); 
    1475          
     1514 
    14761515        var visibleRows = Math.max(1, Math.floor(vh/this.rowHeight)); 
    1477          
     1516 
    14781517        var totalLength = ds.getTotalCount(); 
    1479          
     1518 
    14801519        if (totalLength < this.visibleRows || this.visibleRows == visibleRows) { 
    14811520            return; 
    14821521        } 
    1483          
     1522 
    14841523        this.visibleRows = visibleRows; 
    1485          
     1524 
    14861525        if (this.rowIndex + visibleRows > totalLength) { 
    14871526            this.rowIndex     = Math.max(0, ds.totalLength-this.visibleRows); 
     
    14901529        } else { 
    14911530            this.updateLiveRows(this.rowIndex, true); 
    1492         }  
    1493     }, 
    1494      
    1495      
     1531        } 
     1532    }, 
     1533 
     1534 
    14961535    adjustScrollerPos : function(pixels, suspendEvent) 
    14971536    { 
     
    15011540        var liveScroller = this.liveScroller; 
    15021541        var scrollDom    = liveScroller.dom; 
    1503          
     1542 
    15041543        if (suspendEvent === true) { 
    15051544            liveScroller.un('scroll', this.onLiveScroll, this); 
    15061545        } 
    1507         this.lastScrollPos   = scrollDom.scrollTop;  
     1546        this.lastScrollPos   = scrollDom.scrollTop; 
    15081547        scrollDom.scrollTop += pixels; 
    1509          
     1548 
    15101549        if (suspendEvent === true) { 
    15111550            scrollDom.scrollTop = scrollDom.scrollTop; 
    15121551            liveScroller.on('scroll', this.onLiveScroll, this, {buffer : this.scrollDelay}); 
    15131552        } 
    1514          
     1553 
    15151554    } 
    1516      
    1517    
    1518      
     1555 
     1556 
     1557 
    15191558});