if(typeof(sortArray)=="undefined") var sortArray = null; if(typeof(sortOrder)=="undefined") var sortOrder = -1; function TableManager(dataSource, headerMessage, titleBg, borderColour, rowBgs, viewProps, mode) { this.mode = mode?mode:0; this.dataSource = dataSource?dataSource:new Array(); this.selectedItems = null; this.dataPointers = new Array(); this.rawHeader = headerMessage?headerMessage:""; this.titleBg = titleBg?titleBg:"#999999"; this.bColour = borderColour?borderColour:this.titleBg; this.rowBgs = (rowBgs && rowBgs.length)?rowBgs:new Array("#FFFFFF","#CCCCCC"); this.view = viewProps?viewProps:new ViewProperties(); this.outWin = null; this.expand = !this.view.collpaseAll; this.groupCol = 0; this.sortCol = 0; this.sortOrder = this.view.sortOrder; this.pageSize = this.view.pageSize; this.lockThreads = this.view.lockThreads; this.firstItem = 0; this.lastItem = 0; this.currPage = 0; this.maxPages = 0; this.groups = new Array(); this.groupPointers = new Array(); this.rowPointers = new Array(); this.header = ""; this.titles = ""; this.rows = new Array(); this.line = ""; this.bar = ""; this.titleHeight = 20; this.columns = new Array(); this.columns[0] = new RowNumberColumn(this); this.resizeTargets = new Array(); } new TableManager("initialize"); TableManager.prototype.addSelectColumn = function(width) { var colID = this.columns.length; this.columns[colID] = new SelectColumn(this, width, colID); }; TableManager.prototype.checkSortAndGroupCols = function(index,column) { if(index == this.view.sortOn) { this.sortCol = column; } if(index == this.view.groupOn) this.groupCol = column; }; TableManager.prototype.addColumn = function(dataIndex, type, title, icon, width, attr) { this.checkSortAndGroupCols(dataIndex,this.columns.length); var colID = this.columns.length; if(dataIndex==8200) // freakin' VG enabled column.... type = 1; switch(parseInt(type)) { case -3: break; case 1: this.columns[colID] = new IconColumn(this,dataIndex,title,icon,width,attr&1,decodeAttrAlign(attr)); break; /* Pict Columns (client coltype=4) not yet supported case 4: this.columns[colID] = new PictColumn(this,dataIndex,title,icon,width,attr&1,decodeAttrAlign(attr)); break; */ case 8: this.columns[colID] = new NumberColumn(this,dataIndex,title,icon,width,attr&1,decodeAttrAlign(attr)); break; case 16: this.columns[colID] = new DateColumn(this,dataIndex,title,icon,width,attr&1,decodeAttrAlign(attr)); break; default: this.columns[colID] = new TextColumn(this,dataIndex,title,icon,width,attr&1,decodeAttrAlign(attr)); break; } }; TableManager.prototype.sort = function(groupCol,sortCol) { window.status = "Please wait, table manager sorting...."; if(groupCol==-1) { this.expand = !this.expand; for(var group=0; group < this.groups.length; group++) this.groups[group][0] = this.expand; this.build(); } else { if(sortCol==-1) { this.sortOrder *= -1; sortCol = this.sortCol; } if(isNaN(parseInt(sortCol)) || parseInt(sortCol) < 0 || parseInt(sortCol) >= this.columns.length) sortCol = this.sortCol; if(isNaN(parseInt(groupCol)) || parseInt(groupCol) < 0 || parseInt(groupCol) >= this.columns.length) groupCol = this.groupCol; if(sortCol != this.sortCol || this.sortOrder==0) this.sortOrder = this.columns[sortCol].sortOrder; var currentValue; var currentIndex = 0; sortArray = new Array(); this.groupCol = groupCol; this.sortCol = sortCol; sortOrder = this.sortOrder; var sortParams = new Array(); sortParams[0] = this.columns[this.sortCol]; if(sortCol != 0) sortParams[sortParams.length] = this.columns[0]; for(var index=0; index < this.dataSource.length; index++) { sortArray[index] = new Array(); if(groupCol != 0) sortArray[index][0] = this.columns[groupCol].getGroupData(index); for(var param=0; param < sortParams.length; param++) sortArray[index][sortArray[index].length] = sortParams[param].getSortData(index); } this.dataPointers = new Array(); for(var index=0; index 0) { for(var index=0; index < sortArray.length; index++) { var dataIndex = sortArray[index]; sortArray[index] = new Array(); for(var param=0; param < sortParams.length; param++) sortArray[index][sortArray[index].length] = sortParams[param].getSortData(dataIndex); } qSort(this.groupPointers,sortComparison); } this.build(); } }; TableManager.prototype.build = function() { window.status = "Done sorting, table manager building display...."; this.titles = this.makeTitles(); var nodeBg = (this.view.vLine||this.view.hLine?" bgcolor=\"" + this.bColour + "\"":""); this.line =""; for(var col = (this.view.rNum?0:1);col < this.columns.length; col++) this.line += ""; this.line += ""; this.bar = ""; this.rowPointers = new Array(); for(var group = 0; group < this.groupPointers.length; group++) { this.rowPointers[this.rowPointers.length] = new Array(group,0); if(this.groups[this.groupPointers[group]][1].length > 1 && this.groups[this.groupPointers[group]][0]) for(var groupMember = 1; groupMember this.pageSize && this.pageSize > 0) { var firstItem; var lastItem; if(isFinite(direction)){ firstItem = this.firstItem + this.pageSize * direction; lastItem = firstItem + this.pageSize; } if(direction == Number.POSITIVE_INFINITY || lastItem > this.rowPointers.length) { lastItem = this.rowPointers.length; firstItem = lastItem - this.pageSize; } else if(!isFinite(direction) || firstItem < 0) { firstItem = 0; lastItem = this.pageSize; } if(this.lockThreads) { while(firstItem>0 && this.rowPointers[firstItem][0] == this.rowPointers[firstItem-1][0]) firstItem --; while(lastItem < this.rowPointers.length && this.rowPointers[lastItem - 1][0] == this.rowPointers[lastItem][0]) lastItem ++; } this.firstItem = firstItem; this.lastItem = lastItem; this.currPage = Math.ceil(this.firstItem/this.pageSize) + 1; this.maxPages = Math.ceil(this.rowPointers.length/this.pageSize); } else { this.currPage = 0; this.maxPages = 0; this.firstItem = 0; this.lastItem = this.rowPointers.length; } this.buildRows(); this.makeHeader(); }; TableManager.prototype.buildRows = function() { this.rows = new Array(); for(var item=this.firstItem; item < this.lastItem; item++) { var group = this.groupPointers[this.rowPointers[item][0]]; var dataIndex = this.groups[group][1][this.rowPointers[item][1]]; var collapseState = (this.rowPointers[item][1]>0?2:(this.groups[group][1].length==1?0:(this.groups[group][0]?1:-1))); this.rows[item] = this.makeRow(dataIndex,item,collapseState,group); } }; TableManager.prototype.makeTitles = function() { var outString = ""; for(var column=(this.view.rNum?0:1); column" + this.makeTitle(column,(column==this.sortCol&&column>0),(column==this.groupCol&&column>0)) + ""; outString += ""; return outString; }; TableManager.prototype.makeRow = function(dataIndex,rowNum,expandState,groupNum) { var lineBg = (this.view.vLine?this.bColour:this.rowBgs[rowNum%this.rowBgs.length]); var outString = "" + (this.view.rNum?this.column[0].makeCell(rowNum) + "":""); for(var column=(this.view.rNum?0:1); column"; if(column==this.groupCol && (expandState==1 || expandState==-1)) outString += ""; else if(column==this.groupCol) outString += ""; outString += this.columns[column].makeCell(dataIndex,(column==this.groupCol && expandState==2)) + "
\"Expand\"":"2\"
" } outString += ""; return outString; }; TableManager.prototype.makeTitle = function(colNum,isSortCol,isGroupCol) { var column = this.columns[colNum]; return ("
" + (isGroupCol?"":"") + "
\"Collapse" + (isSortCol?this.makePaddings(-1,column.width,column.align):"") + "" + (isSortCol?this.makePaddings(1,column.width,column.align):"") + "
" + column.title + "
"); }; TableManager.prototype.makePaddings = function(side,width,align,sortOrder) { var icons = new Array("/Icons/8001","/Icons/8000"); var alts = new Array("Sorted in Descending Order","Sorted in Ascending Order"); var sortDirection = (this.sortOrder + 1) / 2; if(side==-1 && align.toUpperCase() == "RIGHT" && width >= 25) return "\"""; else if (side==-1 && align.toUpperCase() == "CENTER" && width >= 40) return ""; else if (side==1 && align.toUpperCase() != "RIGHT" && width >= 25) return "\"""; else return ""; }; TableManager.prototype.makeHeader = function() { var outString = new String(this.rawHeader); var startIndex, elseIndex, endIndex; outString = decodeIf(outString,"","",(this.maxPages > 0)); outString = decodeIf(outString,"","",(this.maxPages == 0)); outString = decodeIf(outString,"","",(this.currPage < 2)); outString = decodeIf(outString,"","",(this.currPage > 1)); outString = decodeIf(outString,"","",(this.currPage == this.maxPages)); outString = decodeIf(outString,"","",(this.currPage != this.maxPages)); while((startIndex = outString.toUpperCase().indexOf("")) > -1) outString = outString.substring(0,startIndex) + (this.currPage!=0?this.currPage:1) + outString.substring(startIndex + 10,outString.length); while((startIndex = outString.toUpperCase().indexOf("")) > -1) outString = outString.substring(0,startIndex) + (this.maxPages!=0?this.maxPages:1) + outString.substring(startIndex + 10,outString.length); this.header = outString; }; TableManager.prototype.getSelectedItems = function() { var selectedArray = new Array(); if(this.selectedItems != null) { for(var item=0; item < this.selectedItems.length; item++) if(this.selectedItems[item]) selectedArray[selectedArray.length] = item; } return selectedArray; }; TableManager.prototype.getRow = function(item) { var retVal = -1; var location = this.getGroupMember(item[13]); if(location != 0 && (location[1] == 0 || this.groups[location[0]][0]!=0)) { for(var row = 0; row < this.rowPointers.length && this.groupPointers[this.rowPointers[row][0]] != location[0]; row++); if(row < this.rowPointers.length) retVal = row + location[1]; } return retVal; } TableManager.prototype.getGroupMember = function(sysID) { var found = false; var member = 0; var group = 0; while(group < this.groups.length && !found) { member = 0; while(member < this.groups[group][1].length && !found) if(this.dataSource[this.groups[group][1][member]][13] == sysID) found = true; else member++; if(!found) group++; } if(found) return new Array(group,member); else return 0; } TableManager.prototype.getItemFromSysID = function(sysID) { var location = this.getGroupMember(sysID); if(location != 0) return this.dataSource[this.groups[location[0]][1][location[1]]]; else return 0; } TableManager.prototype.getAdjacentInThread = function(sysID, offset) { var adjacentInThread = -1; var location = this.getGroupMember(sysID); if(location != 0 && this.groups[location[0]][1].length > Math.abs(offset)) { location[1] -= offset; if(location[1] >= 0 && location[1] < this.groups[location[0]][1].length) adjacentInThread = this.groups[location[0]][1][location[1]]; } return adjacentInThread; } TableManager.prototype.getAdjacentUnread = function(sysID, direction) { var adjacentUnread = -1; var found = false; var wrap = false; var location = this.getGroupMember(sysID); if(location != 0) { var member = location[1]; for(var group=0; group < this.groupPointers.length && this.groupPointers[group] != location[0]; group++); do { member -= direction; if(member < 0) { group--; if(group < 0) group = this.groupPointers.length - 1; member = this.groups[this.groupPointers[group]][1].length-1; } else if(member >= this.groups[this.groupPointers[group]][1].length) { group++; if(group >= this.groupPointers.length) group = 0; member = 0; } } while(this.dataSource[this.groups[this.groupPointers[group]][1][member]][9] != 7016 && !(this.groupPointers[group]==location[0] && member==location[1])); if(this.dataSource[this.groups[this.groupPointers[group]][1][member]][9]==7016) { adjacentUnread = this.groups[this.groupPointers[group]][1][member]; } } return adjacentUnread; } TableManager.prototype.select = function(index) { this.selectedItems[index] = 1 - (1*this.selectedItems[index]); } function RowNumberColumn(parent) { this.parent = parent; this.align = "right"; this.width = 25; this.title = "   "; this.sortOrder = 1; } new RowNumberColumn(null); RowNumberColumn.prototype.makeCell = function(rowIndex) { return ("" + rowIndex + ""); }; RowNumberColumn.prototype.getSortData = function(index) { return index; }; RowNumberColumn.prototype.getGroupData = function(index) { return index; }; function SelectColumn(parent, width, colIndex) { this.parent = parent; this.title = "\"Select\""; this.width = width?width:20; this.align = "center"; this.colIndex = colIndex; this.sortOrder = 1; if(this.parent != null && this.parent.selectedItems==null) { this.parent.selectedItems = new Array(); for(var item=0; item < this.parent.dataSource.length; item++) this.parent.selectedItems[item] = 0; } } new SelectColumn(null); SelectColumn.prototype.makeCell = function(rowIndex,indent) { return ("" + makeIndent(indent,this.width) + "
"); }; SelectColumn.prototype.getSortData = function(index) { return (this.parent.selectedItems!=null && this.parent.selectedItems[index]); }; SelectColumn.prototype.getGroupData = function(index) { return (this.parent.selectedItems!=null && this.parent.selectedItems[index]); }; function IconColumn(parent, dataIndex, title, icon, width, sortOrder, align) { this.parent = parent; this.dataIndex = dataIndex?dataIndex:5; this.title = makeTitle(title, (dataIndex==5?"s" + icon:dataIndex==10&&icon==11128?9292:icon)); this.width = width?width:20; this.sortOrder = sortOrder?-1:1; this.align = align?align:"center"; } new IconColumn(null); IconColumn.prototype.makeCell = function(rowIndex,indent) { var URL = getBaseURL( this.parent.dataSource[rowIndex][19]); var alt = this.parent.dataSource[rowIndex][-14]; var commandID = 0; var icon = (this.dataIndex==5?"s":0) + (this.parent.dataSource[rowIndex][this.dataIndex] + (this.dataIndex==8200?2025:0)); if(this.dataIndex==5) { /* disabled pending the activation of getInfo if(decodeBitField(srcwin.permissions,0x80000)) { alt="Click to Get Info" commandID=143; } else*/ alt=this.parent.dataSource[rowIndex][-1]; } else if(this.dataIndex==9) {/* if(decodeBitField(this.parent.dataSource[rowIndex][3],0x1000)) { alt="Undelete"; commandID=366; } else if(decodeBitField(this.parent.dataSource[rowIndex][3],0x1800)==0x800) { alt="Send"; commandID=152; } else if(decodeBitField(srcwin.privs,0x20000)) { alt="Mark as Read"; commandID=167; } else*/ alt=""; } else if (this.dataIndex==10) {/* if(decodeBitField(srcwin.permissions,0x80)) { alt="Approve"; commandID=175; }*/ if(decodeBitField(this.parent.dataSource[rowIndex][3],0x1)) alt="Voice Attachment"; else if(decodeBitField(this.parent.dataSource[rowIndex][3],0x20)) alt="Attachment"; else alt=""; } if(commandID) { URL += "?" + (commandID==366?"Undelete":"Command=" + commandID); var action = "srcwin.fileOp(activeManager.dataSource[" + rowIndex + "]," + commandID + ");return false;"; } else var action = "srcwin.URLClick(activeManager.dataSource[" + rowIndex + "]," + rowIndex + ");return false;"; return "" + makeIndent(indent,this.width) + "
\""
"; }; IconColumn.prototype.getSortData = function(index) { return this.parent.dataSource[index][this.dataIndex]; }; IconColumn.prototype.getGroupData = function(index) { return this.parent.dataSource[index][this.dataIndex]; }; function TextColumn(parent, dataIndex, title, icon, width, sortOrder, align) { this.parent = parent; this.dataIndex = dataIndex; this.title = makeTitle(title, icon); this.width = width?width:40; this.sortOrder = sortOrder?-1:1; this.align = align?align:"left"; } new TextColumn(null); TextColumn.prototype.makeCell = function(rowIndex,indent) { var style = 0; var URL = getBaseURL( this.parent.dataSource[rowIndex][19]); var action = "srcwin.URLClick(activeManager.dataSource[" + rowIndex + "]," + rowIndex + ");return false;"; var wrapIndex = parseInt(this.dataIndex); if(this.dataIndex==0) var text = this.parent.dataSource[rowIndex][-1]; else if(this.dataIndex==4) var text = "(" + this.parent.dataSource[rowIndex][4][0] + "," + this.parent.dataSource[rowIndex][4][1] + ")"; else if(this.dataIndex==6) var text = numToMetricString(this.parent.dataSource[rowIndex][6]); else if(this.dataIndex==14) { wrapIndex = this.parent.dataSource[rowIndex][14]; var text = this.parent.dataSource[rowIndex][wrapIndex]; } else var text = this.parent.dataSource[rowIndex][this.dataIndex]; var URLString = "href=\"" + URL + "\" onClick=\"" + action + "\">"; if(wrapIndex==7) { var status = this.parent.dataSource[rowIndex][3]; style = ((decodeBitField(permissions,0x0004) && !decodeBitField(status,0x0410) && this.parent.dataSource[rowIndex][0]==1)?4:0) + (decodeBitField(status,0x0200)?2:0); var outString = ""; if(decodeBitField(status,0x0800)) outString = "" + outString; } else if(wrapIndex==8) { var msgOptions = this.parent.dataSource[rowIndex][17]; var outString = ""; if(decodeBitField(msgOptions,0x1C00)) { outString = ">10)][0] + ": " + outString; } if(decodeBitField(msgOptions,0xE000)) outString = ">13)][0] + ": " + outString; if(decodeBitField(msgOptions,0x0100)) outString = "" + outString; } else var outString = ""; return "" + makeIndent(indent,this.width) + "
" + outString + "
"; }; TextColumn.prototype.getSortData = function(index) { var sortIndex = parseInt(this.dataIndex); if(sortIndex==14) sortIndex=-14; switch(sortIndex) { case 0: var retVal = this.parent.dataSource[index][0]; break; case 4: var retVal = ((this.parent.dataSource[index][4][1]<<16) + this.parent.dataSource[index][4][0]); break; case 6: var retVal = this.parent.dataSource[index][6]; break; case 8: var retVal = (new String(this.parent.dataSource[index][8])).toUpperCase(); var reStr = (new String("Re")).toUpperCase(); var fwdStr = (new String("Fwd")).toUpperCase(); while((retVal.indexOf(reStr)==0 && retVal.indexOf(":")==reStr.length) || (retVal.indexOf(fwdStr)==0 && retVal.indexOf(":") == fwdStr.length)) retVal = retVal.substring((retVal.indexOf(":") + 2),retVal.length); break; default: var retVal = this.parent.dataSource[index][sortIndex].toUpperCase(); break; } return retVal; }; TextColumn.prototype.getGroupData = function(index) { var groupIndex = parseInt(this.dataIndex); if(groupIndex==14) groupIndex==-14; switch(groupIndex) { case 0: var retVal = this.parent.dataSource[index][0]; break; case 4: var retVal = ((this.parent.dataSource[index][4][1]<<16) + this.parent.dataSource[index][4][0]); break; case 6: var retVal = this.parent.dataSource[index][6]; break; case 8: var retVal = this.parent.dataSource[index][11]; break; default: var retVal = this.parent.dataSource[index][groupIndex].toUpperCase(); break; } return retVal; }; function NumberColumn(parent, dataIndex, title, icon, width, sortOrder, align) { this.parent = parent; this.dataIndex = dataIndex?dataIndex:6; this.title = makeTitle(title, icon); this.width = width?width:40; this.sortOrder = sortOrder?-1:1; this.align = align?align:"right"; }; new NumberColumn(null); NumberColumn.prototype.makeCell = function(rowIndex,indent) { return "" + makeIndent(indent,this.width) + "
" + this.parent.dataSource[rowIndex][this.dataIndex] + "
"; }; NumberColumn.prototype.getSortData = function(index) { return this.parent.dataSource[index][this.dataIndex]; }; NumberColumn.prototype.getGroupData = function(index) { return this.parent.dataSource[index][this.dataIndex]; }; function DateColumn(parent, dataIndex, title, icon, width, sortOrder, align) { this.parent = parent; this.dataIndex = dataIndex?dataIndex:2; this.title = makeTitle(title, icon); this.width = width?width:40; this.sortOrder = sortOrder?-1:1; this.align = align?align:"left"; } new DateColumn(null); DateColumn.prototype.makeCell = function(rowIndex,indent) { var date = this.parent.dataSource[rowIndex][this.dataIndex]; var URL = getBaseURL( this.parent.dataSource[rowIndex][19]); var action = "srcwin.URLClick(activeManager.dataSource[" + rowIndex + "]," + rowIndex + ");return false;"; return "" + makeIndent(indent,this.width) + "
" + (date.getTime()?formatDate(date,this.parent.view.use24hr):"-") + "
"; }; DateColumn.prototype.getSortData = function(index) { return this.parent.dataSource[index][this.dataIndex].getTime(); }; DateColumn.prototype.getGroupData = function(index) { var data = this.parent.dataSource[index][this.dataIndex]; return (new Date(data.getFullYear(),data.getMonth(),data.getDate(),0,0,0,0)).getTime(); }; function sortComparison(a,b) { var item1 = sortArray[a]; var item2 = sortArray[b]; var retVal = 0; var param = -1; while(!retVal && ++param < item1.length) retVal = (item1[param]>item2[param]?1:(item1[param] -1) { endIndex = outString.toUpperCase().indexOf(endIf.toUpperCase(),startIndex); if(endIndex == -1) endIndex = outString.length; outString = outString.substring(0,startIndex) + (condition?outString.substring(startIndex + startIf.length,endIndex):"") + (endIndex!=outString.length?outString.substring(endIndex + endIf.length,outString.length):""); } return outString; }; function decodeAttrAlign(bitMask) { return(bitMask&2?"right":(bitMask&4?"center":"left")); } function makeIndent(indent,width) { return (indent?"15?15:(Math.floor(width/2))) + "\" height=\"1\" border=\"0\">":""); } function makeTitle(title,icon) { return (icon?"\""":(title?title:"   ")); } function formatDate(date,use24Hr) { return date.getFullYear() + "/" + format(date.getMonth() + 1) + "/" + format(date.getDate()) + "  " + (use24Hr?format(date.getHours()) + format(date.getMinutes()):(date.getHours()%12==0?12:date.getHours()%12) + ":" + format(date.getMinutes()) + " " + (date.getHours()>11?"PM":"AM")); } function getBaseURL(URL) { if(URL.charAt(0) == '/') return URL; else return srcwin.path + URL; } function format(str,len) { while(str.toString().length < (len?len:2)) str = "0" + str; return str; } function numToMetricString(number) { var suffixes = new Array('','K','M','G','T'); suffix = 0; var decimal = ""; while(!isNaN(number) && number>1000 && suffix < 4) { decimal = new String(Math.floor(number/102.4)); number = Math.floor(number/1024); suffix++; } if(number < 10 && suffix > 0) { var outString = decimal.substring(0,decimal.length-1); if(decimal.charAt(decimal.length-1) != 0) outString += "." + decimal.charAt(decimal.length-1); } else var outString = new String(number); if(outString=="0") outString = "0K"; else outString += suffixes[suffix]; return outString; } function decodeBitField(bitfield, bit) { var result = bitfield&bit; return result; } function isThreadableValue(value) { if(value==0) return false; else if(value=="") return false; else if(typeof(value)=="string" && value.length >= 5 && value.substring(0,3) == "[0:") return false; else return true; }