Ext.grid.ColumnModel.override({
// defaultPROPERTY removed in favor of standard
// defaults provided by Ext.container.Container.
/**
* @cfg {Number} defaultWidth (optional) The width of columns which have no {@link #width}
* specified (defaults to 100). This property shall preferably be configured through the
* {@link #defaults} config property.
*/
defaultWidth: 100,
/**
* @cfg {Boolean} defaultSortable (optional) Default sortable of columns which have no
* sortable specified (defaults to false). This property shall preferably be configured
* through the {@link #defaults} config property.
*/
defaultSortable: false,
/**
* Reconfigures this column model according to the passed Array of column definition objects.
* For a description of the individual properties of a column definition object, see the
* Config Options.
* Causes the {@link #configchange} event to be fired. A {@link Ext.grid.GridPanel GridPanel}
* using this ColumnModel will listen for this event and refresh its UI automatically.
* @param {Array} config Array of Column definition objects.
* @param {Boolean} initial Specify true to bypass cleanup which deletes the totalWidth
* and destroys existing editors.
*/
setConfig : function(config, initial) {
this.config = config;
//var i, c, len;
//
//if (!initial) { // cleanup
// delete this.totalWidth;
//
// for (i = 0, len = this.config.length; i < len; i++) {
// c = this.config[i];
//
// if (c.setEditor) {
// //check here, in case we have a special column like a CheckboxSelectionModel
// c.setEditor(null);
// }
// }
//}
//
//// backward compatibility
//this.defaults = Ext.apply({
// width: this.defaultWidth,
// sortable: this.defaultSortable
//}, this.defaults);
//
//this.config = config;
//this.lookup = {};
//
//for (i = 0, len = config.length; i < len; i++) {
// c = Ext.applyIf(config[i], this.defaults);
//
// // if no id, create one using column's ordinal position
// if (Ext.isEmpty(c.id)) {
// c.id = Ext.id();
// }
//
// if (!c.isColumn) {
// var Cls = Ext.grid.Column.types[c.xtype || 'gridcolumn'];
// c = new Cls(c);
// config[i] = c;
// }
//
// this.lookup[c.id] = c;
//}
//
//if (!initial) {
// this.fireEvent('configchange', this);
//}
},
/**
* @private
* Called by the SplitDragZone when a drag has been completed. Resizes the columns
*/
onColumnSplitterMoved : function(cellIndex, width) {
this.userResized = true;
this.setColumnWidth(cellIndex, width, true);
if (this.forceFit) {
this.fitColumns(true, false, cellIndex);
this.updateAllColumnWidths();
} else {
this.updateColumnWidth(cellIndex, width);
this.syncHeaderScroll();
}
this.grid.fireEvent('columnresize', cellIndex, width);
},
/**
* @private
* Click handler for the shared column dropdown menu, called on beforeshow. Builds the menu
* which displays the list of columns for the user to show or hide.
*/
beforeColMenuShow : function() {
var colModel = this.cm,
colCount = colModel.getColumnCount(),
colMenu = this.colMenu,
i;
colMenu.removeAll();
for (i = 0; i < colCount; i++) {
if (colModel.config[i].hideable !== false) {
colMenu.add(new Ext.menu.CheckItem({
text : colModel.getColumnHeader(i),
itemId : 'col-' + colModel.getColumnId(i),
checked : !colModel.isHidden(i),
disabled : colModel.config[i].hideable === false,
hideOnClick: false
}));
}
}
},
/**
* @private
* Attached as the 'itemclick' handler to the header menu and the column show/hide submenu (if available).
* Performs sorting if the sorter buttons were clicked, otherwise hides/shows the column that was clicked.
*/
handleHdMenuClick : function(item) {
var store = this.ds,
dataIndex = this.cm.getDataIndex(this.hdCtxIndex);
switch (item.getItemId()) {
case 'asc':
store.sort(dataIndex, 'ASC');
break;
case 'desc':
store.sort(dataIndex, 'DESC');
break;
default:
this.handleHdMenuClickDefault(item);
}
return true;
},
/**
* Called by handleHdMenuClick if any button except a sort ASC/DESC button was clicked. The default implementation provides
* the column hide/show functionality based on the check state of the menu item. A different implementation can be provided
* if needed.
* @param {Ext.menu.BaseItem} item The menu item that was clicked
*/
handleHdMenuClickDefault: function(item) {
var colModel = this.cm,
itemId = item.getItemId(),
index = colModel.getIndexById(itemId.substr(4));
if (index != -1) {
// this has been changed to a MC so we'd use getCount if we port it...
if (item.checked && colModel.getColumnsBy(this.isHideableColumn, this).length <= 1) {
this.onDenyColumnHide();
return false;
}
colModel.setHidden(index, item.checked);
}
},
/**
* @private
* Called when a header cell is clicked - shows the menu if the click happened over a trigger button
*/
handleHdDown : function(e, target) {
if (Ext.fly(target).hasCls(Ext.baseCSSPrefix + 'grid3-hd-btn')) {
e.stopEvent();
var colModel = this.cm,
header = this.findHeaderCell(target),
index = this.getCellIndex(header),
sortable = colModel.isSortable(index),
menu = this.hmenu,
menuItems = menu.items,
menuCls = this.headerMenuOpenCls;
this.hdCtxIndex = index;
Ext.fly(header).addCls(menuCls);
menuItems.get('asc').setDisabled(!sortable);
menuItems.get('desc').setDisabled(!sortable);
menu.on('hide', function() {
Ext.fly(header).removeCls(menuCls);
}, this, {single:true});
menu.show(target, 'tl-bl?');
}
},
/**
* @private
* Attached to the headers' mousemove event. This figures out the CSS cursor to use based on where the mouse is currently
* pointed. If the mouse is currently hovered over the extreme left or extreme right of any header cell and the cell next
* to it is resizable it is given the resize cursor, otherwise the cursor is set to an empty string.
*/
handleHdMove : function(e) {
var header = this.findHeaderCell(this.activeHdRef);
if (header && !this.headersDisabled) {
var handleWidth = this.splitHandleWidth || 5,
activeRegion = this.activeHdRegion,
headerStyle = header.style,
colModel = this.cm,
cursor = '',
pageX = e.getPageX();
if (this.grid.enableColumnResize !== false) {
var activeHeaderIndex = this.activeHdIndex,
currentResizable = colModel.isResizable(activeHeaderIndex),
previousResizable = colModel.isResizable(activeHeaderIndex - 1),
inLeftResizer = pageX - activeRegion.left <= handleWidth,
inRightResizer = activeRegion.right - pageX <= (!this.activeHdBtn ? handleWidth : 2);
if (inLeftResizer && previousResizable) {
cursor = Ext.isAir ? 'move' : Ext.isWebKit ? 'e-resize' : 'col-resize'; // col-resize not always supported
} else if (inRightResizer && currentResizable) {
cursor = Ext.isAir ? 'move' : Ext.isWebKit ? 'w-resize' : 'col-resize';
}
}
headerStyle.cursor = cursor;
}
},
/**
* @private
* Tied to the header element's mouseover event - adds the over class to the header cell if the menu is not disabled
* for that cell
*/
handleHdOver : function(e, target) {
var header = this.findHeaderCell(target);
if (header && !this.headersDisabled) {
var fly = this.fly(header);
this.activeHdRef = target;
this.activeHdIndex = this.getCellIndex(header);
this.activeHdRegion = fly.getRegion();
if (!this.isMenuDisabled(this.activeHdIndex, fly)) {
fly.addCls(Ext.baseCSSPrefix + 'grid3-hd-over');
this.activeHdBtn = fly.down('.' + Ext.baseCSSPrefix + 'grid3-hd-btn');
if (this.activeHdBtn) {
this.activeHdBtn.dom.style.height = (header.firstChild.offsetHeight - 1) + 'px';
}
}
}
},
/**
* @private
* Tied to the header element's mouseout event. Removes the hover class from the header cell
*/
handleHdOut : function(e, target) {
var header = this.findHeaderCell(target);
if (header && (!Ext.isIE || !e.within(header, true))) {
this.activeHdRef = null;
this.fly(header).removeCls(Ext.baseCSSPrefix + 'grid3-hd-over');
header.style.cursor = '';
}
},
/**
* @private
* Used by {@link #handleHdOver} to determine whether or not to show the header menu class on cell hover
* @param {Number} cellIndex The header cell index
* @param {Ext.core.Element} el The cell element currently being hovered over
*/
isMenuDisabled: function(cellIndex, el) {
return this.cm.isMenuDisabled(cellIndex);
}
});