summaryrefslogtreecommitdiff
path: root/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/table/RemoteTableModel.js
diff options
context:
space:
mode:
Diffstat (limited to 'webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/table/RemoteTableModel.js')
-rw-r--r--webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/table/RemoteTableModel.js435
1 files changed, 0 insertions, 435 deletions
diff --git a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/table/RemoteTableModel.js b/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/table/RemoteTableModel.js
deleted file mode 100644
index ebd1be8f53..0000000000
--- a/webapps/qooxdoo-0.6.3-sdk/frontend/framework/source/class/qx/ui/table/RemoteTableModel.js
+++ /dev/null
@@ -1,435 +0,0 @@
-/* ************************************************************************
-
- qooxdoo - the new era of web development
-
- http://qooxdoo.org
-
- Copyright:
- 2006 by STZ-IDA, Germany, http://www.stz-ida.de
-
- License:
- LGPL 2.1: http://www.gnu.org/licenses/lgpl.html
-
- Authors:
- * Til Schneider (til132)
-
-************************************************************************ */
-
-/* ************************************************************************
-
-#module(ui_table)
-
-************************************************************************ */
-
-/**
- * A table model that loads its data from a backend.
- * <p>
- * Only those rows are loaded that are near the area the user is currently
- * viewing. If the user scrolls, the rows he will see soon are loaded
- * asynchroniously in the background. All loaded data is managed in a cache that
- * automatically removes the last resently used rows when it gets full.
- * <p>
- * This class is abstract: The actual loading of row data must be done by
- * subclasses.
- */
-qx.OO.defineClass("qx.ui.table.RemoteTableModel", qx.ui.table.AbstractTableModel,
-function() {
- qx.ui.table.AbstractTableModel.call(this);
-
- this._sortColumnIndex = -1;
- this._sortAscending = true;
- this._rowCount = -1;
-
- this._lruCounter = 0;
- this._firstLoadingBlock = -1;
- this._firstRowToLoad = -1;
- this._lastRowToLoad = -1;
- this._ignoreCurrentRequest = false;
-
- this._rowBlockCache = {};
- this._rowBlockCount = 0;
-});
-
-
-/** The number of rows that are stored in one cache block. */
-qx.OO.addProperty({ name:"blockSize", type:"number", defaultValue:50, allowNull:false });
-
-/** The maximum number of row blocks kept in the cache. */
-qx.OO.addProperty({ name:"maxCachedBlockCount", type:"number", defaultValue:15, allowNull:false });
-
-/**
- * Whether to clear the cache when some rows are removed.
- * If false the rows are removed locally in the cache.
- */
-qx.OO.addProperty({ name:"clearCacheOnRemove", type:"boolean", defaultValue:false, allowNull:false });
-
-
-// overridden
-qx.Proto.getRowCount = function() {
- if (this._rowCount == -1) {
- this._loadRowCount();
-
- // NOTE: _loadRowCount may set this._rowCount
- return (this._rowCount == -1) ? 0 : this._rowCount;
- } else {
- return this._rowCount;
- }
-}
-
-
-/**
- * Loads the row count from the server.
- * <p>
- * Implementing classes have to call {@link _onRowDataLoaded()} when the server
- * response arrived. That method has to be called! Even when there was an error.
- */
-qx.Proto._loadRowCount = function() {
- throw new Error("_loadRowCount is abstract");
-};
-
-
-/**
- * Sets the row count.
- * <p>
- * Has to be called by {@link _loadRowCount()}.
- *
- * @param rowCount {int} the number of rows in this model or null if loading.
- */
-qx.Proto._onRowCountLoaded = function(rowCount) {
- this.debug("row count loaded: " + rowCount);
- if (rowCount == null) {
- rowCount = 0;
- }
- this._rowCount = rowCount;
-
- // Inform the listeners
- var data = { firstRow:0, lastRow:rowCount - 1, firstColumn:0, lastColumn:this.getColumnCount() - 1 };
- this.dispatchEvent(new qx.event.type.DataEvent(qx.ui.table.TableModel.EVENT_TYPE_DATA_CHANGED, data), true);
-};
-
-
-/**
- * Reloads the model and clears the local cache.
- */
-qx.Proto.reloadData = function() {
- this.clearCache();
-
- // If there is currently a request on its way, then this request will bring
- // obsolete data -> Ignore it
- if (this._firstLoadingBlock != -1) {
- this._ignoreCurrentRequest = true;
- }
-
- // NOTE: This will inform the listeners as soon as the new row count is known
- this._loadRowCount();
-};
-
-
-/**
- * Clears the cache.
- */
-qx.Proto.clearCache = function() {
- this._rowBlockCache = {};
- this._rowBlockCount = 0;
-};
-
-
-// overridden
-qx.Proto.prefetchRows = function(firstRowIndex, lastRowIndex) {
- // this.debug("Prefetch wanted: " + firstRowIndex + ".." + lastRowIndex);
- if (this._firstLoadingBlock == -1) {
- var blockSize = this.getBlockSize();
- var totalBlockCount = Math.ceil(this._rowCount / blockSize);
-
- // There is currently no request running -> Start a new one
- // NOTE: We load one more block above and below to have a smooth
- // scrolling into the next block without blank cells
- var firstBlock = parseInt(firstRowIndex / blockSize) - 1;
- if (firstBlock < 0) {
- firstBlock = 0;
- }
- var lastBlock = parseInt(lastRowIndex / blockSize) + 1;
- if (lastBlock >= totalBlockCount) {
- lastBlock = totalBlockCount - 1;
- }
-
- // Check which blocks we have to load
- var firstBlockToLoad = -1;
- var lastBlockToLoad = -1;
- for (var block = firstBlock; block <= lastBlock; block++) {
- if (this._rowBlockCache[block] == null || this._rowBlockCache[block].isDirty) {
- // We don't have this block
- if (firstBlockToLoad == -1) {
- firstBlockToLoad = block;
- }
- lastBlockToLoad = block;
- }
- }
-
- // Load the blocks
- if (firstBlockToLoad != -1) {
- this._firstRowToLoad = -1;
- this._lastRowToLoad = -1;
-
- this._firstLoadingBlock = firstBlockToLoad;
-
- this.debug("Starting server request. rows: " + firstRowIndex + ".." + lastRowIndex + ", blocks: " + firstBlockToLoad + ".." + lastBlockToLoad);
- this._loadRowData(firstBlockToLoad * blockSize, (lastBlockToLoad + 1) * blockSize - 1);
- }
- } else {
- // There is already a request running -> Remember this request
- // so it can be executed after the current one is finished.
- this._firstRowToLoad = firstRowIndex;
- this._lastRowToLoad = lastRowIndex;
- }
-};
-
-
-/**
- * Loads some row data from the server.
- * <p>
- * Implementing classes have to call {@link _onRowDataLoaded()} when the server
- * response arrived. That method has to be called! Even when there was an error.
- *
- * @param firstRow {int} The index of the first row to load.
- * @param lastRow {int} The index of the last row to load.
- */
-qx.Proto._loadRowData = function(firstRow, lastRow) {
- throw new Error("_loadRowCount is abstract");
-};
-
-
-/**
- * Sets row data.
- * <p>
- * Has to be called by {@link _loadRowData()}.
- *
- * @param rowDataArr {Map[]} the loaded row data or null if there was an error.
- */
-qx.Proto._onRowDataLoaded = function(rowDataArr) {
- if (rowDataArr != null && ! this._ignoreCurrentRequest) {
- var blockSize = this.getBlockSize();
- var blockCount = Math.ceil(rowDataArr.length / blockSize);
- if (blockCount == 1) {
- // We got one block -> Use the rowData directly
- this._setRowBlockData(this._firstLoadingBlock, rowDataArr);
- } else {
- // We got more than one block -> We've to split the rowData
- for (var i = 0; i < blockCount; i++) {
- var rowOffset = i * blockSize;
- var blockRowData = [];
- var mailCount = Math.min(blockSize, rowDataArr.length - rowOffset);
- for (var row = 0; row < mailCount; row++) {
- blockRowData.push(rowDataArr[rowOffset + row]);
- }
-
- this._setRowBlockData(this._firstLoadingBlock + i, blockRowData);
- }
- }
- this.debug("Got server answer. blocks: " + this._firstLoadingBlock + ".." + (this._firstLoadingBlock + blockCount - 1) + ". mail count: " + rowDataArr.length + " block count:" + blockCount);
-
- // Inform the listeners
- var data = {
- firstRow:this._firstLoadingBlock * blockSize,
- lastRow:(this._firstLoadingBlock + blockCount + 1) * blockSize - 1,
- firstColumn:0,
- lastColumn:this.getColumnCount() - 1
- };
- this.dispatchEvent(new qx.event.type.DataEvent(qx.ui.table.TableModel.EVENT_TYPE_DATA_CHANGED, data), true);
- }
-
- // We're not loading any blocks any more
- this._firstLoadingBlock = -1;
- this._ignoreCurrentRequest = false;
-
- // Check whether we have to start a new request
- if (this._firstRowToLoad != -1) {
- this.prefetchRows(this._firstRowToLoad, this._lastRowToLoad);
- }
-};
-
-
-/**
- * Sets the data of one block.
- *
- * @param block {int} the index of the block.
- * @param rowDataArr {var[][]} the data to set.
- */
-qx.Proto._setRowBlockData = function(block, rowDataArr) {
- if (this._rowBlockCache[block] == null) {
- // This is a new block -> Check whether we have to remove another block first
- this._rowBlockCount++;
-
- while (this._rowBlockCount > this.getMaxCachedBlockCount()) {
- // Find the last recently used block
- // NOTE: We never remove block 0 and 1
- var lruBlock;
- var minLru = this._lruCounter;
- for (var currBlock in this._rowBlockCache) {
- var currLru = this._rowBlockCache[currBlock].lru;
- if (currLru < minLru && currBlock > 1) {
- minLru = currLru;
- lruBlock = currBlock;
- }
- }
-
- // Remove that block
- this.debug("Removing block: " + lruBlock + ". current LRU: " + this._lruCounter);
- delete this._rowBlockCache[lruBlock];
- this._rowBlockCount--;
- }
- }
-
- this._rowBlockCache[block] = { lru:++this._lruCounter, rowDataArr:rowDataArr };
-};
-
-
-/**
- * Removes a rows from the model.
- *
- * @param rowIndex {int} the index of the row to remove.
- */
-qx.Proto.removeRow = function(rowIndex) {
- if (this.getClearCacheOnRemove()) {
- this.clearCache();
-
- // Inform the listeners
- var data = { firstRow:0, lastRow:rowCount - 1, firstColumn:0, lastColumn:this.getColumnCount() - 1 };
- this.dispatchEvent(new qx.event.type.DataEvent(qx.ui.table.TableModel.EVENT_TYPE_DATA_CHANGED, data), true);
- } else {
- var blockSize = this.getBlockSize();
- var blockCount = Math.ceil(this.getRowCount() / blockSize);
- var startBlock = parseInt(rowIndex / blockSize);
-
- // Remove the row and move the rows of all following blocks
- for (var block = startBlock; block <= blockCount; block++) {
- var blockData = this._rowBlockCache[block];
- if (blockData != null) {
- // Remove the row in the start block
- // NOTE: In the other blocks the first row is removed
- // (This is the row that was)
- var removeIndex = 0;
- if (block == startBlock) {
- removeIndex = rowIndex - block * blockSize;
- }
- blockData.rowDataArr.splice(removeIndex, 1);
-
- if (block == blockCount - 1) {
- // This is the last block
- if (blockData.rowDataArr.length == 0) {
- // It is empty now -> Remove it
- delete this._rowBlockCache[block];
- }
- } else {
- // Try to copy the first row of the next block to the end of this block
- // so this block can stays clean
- var nextBlockData = this._rowBlockCache[block + 1];
- if (nextBlockData != null) {
- blockData.rowDataArr.push(nextBlockData.rowDataArr[0]);
- } else {
- // There is no row to move -> Mark this block as dirty
- blockData.isDirty = true;
- }
- }
- }
- }
-
- if (this._rowCount != -1) {
- this._rowCount--;
- }
-
- // Inform the listeners
- if (this.hasEventListeners(qx.ui.table.TableModel.EVENT_TYPE_DATA_CHANGED)) {
- var data = { firstRow:rowIndex, lastRow:this.getRowCount() - 1, firstColumn:0, lastColumn:this.getColumnCount() - 1 };
- this.dispatchEvent(new qx.event.type.DataEvent(qx.ui.table.TableModel.EVENT_TYPE_DATA_CHANGED, data), true);
- }
- }
-};
-
-
-/**
- * <p>See overridden method for details.</p>
- *
- * @param rowIndex {int} the model index of the row.
- * @return {Object} Map containing a value for each column.
- */
-qx.Proto.getRowData = function(rowIndex) {
- var blockSize = this.getBlockSize();
- var block = parseInt(rowIndex / blockSize);
- var blockData = this._rowBlockCache[block];
- if (blockData == null) {
- // This block is not (yet) loaded
- return null;
- } else {
- var rowData = blockData.rowDataArr[rowIndex - (block * blockSize)];
-
- // Update the last recently used counter
- if (blockData.lru != this._lruCounter) {
- blockData.lru = ++this._lruCounter;
- }
-
- return rowData;
- }
-};
-
-
-// overridden
-qx.Proto.getValue = function(columnIndex, rowIndex) {
- var rowData = this.getRowData(rowIndex);
- if (rowData == null) {
- return null;
- } else {
- var columnId = this.getColumnId(columnIndex);
- return rowData[columnId];
- }
-};
-
-
-/**
- * Sets whether a column is sortable.
- *
- * @param columnIndex {int} the column of which to set the sortable state.
- * @param sortable {boolean} whether the column should be sortable.
- */
-qx.Proto.setColumnSortable = function(columnIndex, sortable) {
- if (sortable != this.isColumnSortable(columnIndex)) {
- if (this._sortableColArr == null) {
- this._sortableColArr = [];
- }
- this._sortableColArr[columnIndex] = sortable;
-
- this.createDispatchEvent(qx.ui.table.TableModel.EVENT_TYPE_META_DATA_CHANGED);
- }
-}
-
-
-// overridden
-qx.Proto.isColumnSortable = function(columnIndex) {
- return this._sortableColArr ? (this._sortableColArr[columnIndex] == true) : false;
-}
-
-
-// overridden
-qx.Proto.sortByColumn = function(columnIndex, ascending) {
- if (this._sortColumnIndex != columnIndex || this._sortAscending != ascending) {
- this._sortColumnIndex = columnIndex;
- this._sortAscending = ascending;
-
- this.clearCache();
-
- // Inform the listeners
- this.createDispatchEvent(qx.ui.table.TableModel.EVENT_TYPE_META_DATA_CHANGED);
- }
-};
-
-
-// overridden
-qx.Proto.getSortColumnIndex = function() {
- return this._sortColumnIndex;
-}
-
-
-// overridden
-qx.Proto.isSortAscending = function() {
- return this._sortAscending;
-}