Changeset 1047
- Timestamp:
- 2008-08-20 14:24:07 (3 months ago)
- Files:
-
- trunk/chrome/content/common/internalFunctions.js (modified) (13 diffs)
- trunk/chrome/content/dta/select.js (modified) (14 diffs)
- trunk/chrome/content/dta/select.xul (modified) (1 diff)
- trunk/chrome/locale/en-US/select.dtd (modified) (1 diff)
- trunk/modules/utils.jsm (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/chrome/content/common/internalFunctions.js
r1028 r1047 74 74 /** 75 75 * Get DOM Element(s) by Id. Missing ids are silently ignored! 76 * @param ids One of more Ids 77 * @return Either the element when there was just one parameter, or an array of elements. 76 * 77 * @param ids 78 * One of more Ids 79 * @return Either the element when there was just one parameter, or an array of 80 * elements. 78 81 */ 79 82 function $() { … … 97 100 /** 98 101 * Opens up a directory picker and returns the user selected path. 99 * @param predefined The starting path to display when dialog opens up 102 * 103 * @param predefined 104 * The starting path to display when dialog opens up 100 105 * @text text The description text to be displayed 101 * @return A string containing the user selected path, or false if user cancels the dialog. 106 * @return A string containing the user selected path, or false if user 107 * cancels the dialog. 102 108 */ 103 109 FilePicker: Components.Constructor('@mozilla.org/filepicker;1', 'nsIFilePicker', 'init'), … … 128 134 }, 129 135 /** 130 * Performs all the needed controls to see if the specified path is valid, is creable and writable and his drive has some free disk space. 131 * @param path The path to test 132 * @return a nsILocalFile to the specified path if it's valid, false if it wasn't 136 * Performs all the needed controls to see if the specified path is valid, is 137 * creable and writable and his drive has some free disk space. 138 * 139 * @param path 140 * The path to test 141 * @return a nsILocalFile to the specified path if it's valid, false if it 142 * wasn't 133 143 */ 134 144 validateDir: function(path) { … … 165 175 }, 166 176 /** 167 * Gets the disk-space available for a nsILocalFile. 168 * Here, because diskSpaceAvailable requires valid path and/or path to be a directory 169 * @param file Valid nsILocalFile 177 * Gets the disk-space available for a nsILocalFile. Here, because 178 * diskSpaceAvailable requires valid path and/or path to be a directory 179 * 180 * @param file 181 * Valid nsILocalFile 170 182 * @return the disk-space available to the caller 171 183 * @author Nils … … 182 194 /** 183 195 * Play a sound file (if prefs allow to do so) 184 * @param name Name of the sound (corresponding to the pref name and the file name of desired sound) 196 * 197 * @param name 198 * Name of the sound (corresponding to the pref name and the file 199 * name of desired sound) 185 200 */ 186 201 playSound: function(name) { … … 197 212 /** 198 213 * returns a formated representation of a (file) size 199 * @param aNumber The number to format 214 * 215 * @param aNumber 216 * The number to format 200 217 * @author Nils 201 218 */ … … 314 331 ); 315 332 316 317 333 /** 318 334 * Get the icon URI corresponding to an URI (special mac handling) 335 * 319 336 * @author Nils 320 337 * @author Stefano 321 * @param link Some sort of DTA_URL, nsIURI or string to get the icon for 322 * @param metalink Is it a metalink? 323 * @param size The desired iconsize; 338 * @param link 339 * Some sort of DTA_URL, nsIURI or string to get the icon for 340 * @param metalink 341 * Is it a metalink? 342 * @param size 343 * The desired iconsize; 324 344 * @return String containing the icon URI 325 345 */ … … 383 403 384 404 /** 385 * Encapulates all stringbundles of the current document and provides unified access 405 * Encapulates all stringbundles of the current document and provides unified 406 * access 407 * 386 408 * @author Nils 387 409 * @see _ … … 420 442 /** 421 443 * Get a (formatted) locale property string. 422 * @param stringId Id of desired string corresponding to the .properties file(s) 423 * @param ... Optional. Format parameters 444 * 445 * @param stringId 446 * Id of desired string corresponding to the .properties file(s) 447 * @param ... 448 * Optional. Format parameters 424 449 * @return String for given Name 425 * @throws Exception if stringID is not found or before the dialog was initialized 450 * @throws Exception 451 * if stringID is not found or before the dialog was initialized 426 452 * @author Nils 427 453 */ … … 439 465 /** 440 466 * XP compatible reveal/launch 467 * 441 468 * @author Nils (derived from DownloadManager code) 442 469 */ … … 461 488 /** 462 489 * Launch/Execute a file 463 * @param nsILocalFile/String pointing to the desired file 490 * 491 * @param nsILocalFile/String 492 * pointing to the desired file 464 493 */ 465 494 launch: function(file) { … … 478 507 }, 479 508 /** 480 * Reveal a file, which will open the directory and furthermore select the file on some platforms. 481 * @param nsILocalFile/String pointing to the desired file 509 * Reveal a file, which will open the directory and furthermore select the 510 * file on some platforms. 511 * 512 * @param nsILocalFile/String 513 * pointing to the desired file 482 514 */ 483 515 reveal: function(file) { … … 503 535 /** 504 536 * Convert a value into a hash 505 * @param data Data to hash. Either an nsInputStream or String-castable. 506 * @param algorithm Optional. Either a number or a string referring to an nsICryptoHash function. (default: sha1) 507 * @param encoding Optional. One of: HASH_HEX (0), HASH_BIN(1), HASH_B64 (2) (default: HASH_HEX) 508 * @param datalen Optional, only for streams. Length of data to hash (default: hash whole stream) 537 * 538 * @param data 539 * Data to hash. Either an nsInputStream or String-castable. 540 * @param algorithm 541 * Optional. Either a number or a string referring to an nsICryptoHash 542 * function. (default: sha1) 543 * @param encoding 544 * Optional. One of: HASH_HEX (0), HASH_BIN(1), HASH_B64 (2) (default: 545 * HASH_HEX) 546 * @param datalen 547 * Optional, only for streams. Length of data to hash (default: hash 548 * whole stream) 509 549 * @return A string representing the hash a in given encoding. 510 550 * @author Nils trunk/chrome/content/dta/select.js
r1030 r1047 39 39 40 40 /** 41 * implemtents nsITreeView 42 * manages our link trees 41 * implemtents nsITreeView manages our link trees 43 42 */ 44 43 function Tree(links, type) { … … 49 48 // internal list of links. 50 49 // better make this a real array (links parameter is usually an object) 51 this._links = links; 52 this._links.forEach( 50 this._links = links.map( 53 51 function(link) { 54 52 // "lazy initialize" the icons. 55 53 // cache them so that we don't have to lookup them again and again. 56 // but do not precompute them, as we don't know if we'll ever display them. 54 // but do not precompute them, as we don't know if we'll ever display 55 // them. 57 56 link.__defineGetter__( 58 57 'icon', … … 81 80 } 82 81 ); 83 84 // .checked will hold the correspoding 'property' string, either none, manuallySelected, or f0-f8 82 link.__defineGetter__( 83 'resname', 84 function() { 85 if (!this._resname) { 86 this._resname = this.url.usable.getUsableFileName(); 87 } 88 return this._resname; 89 } 90 ); 91 92 // .checked will hold the correspoding 'property' string, either none, 93 // manuallySelected, or f0-f8 85 94 link.checked = ''; 86 95 link.mask = null; 87 },88 this96 return link; 97 } 89 98 ); 90 99 … … 101 110 102 111 // get atoms, but provide caching. 103 // we have a limited set of atoms anyway, so we don't have to expect a huge cache. 112 // we have a limited set of atoms anyway, so we don't have to expect a huge 113 // cache. 104 114 getAtom: function(str) { 105 115 if (!(str in this._atoms)) { … … 131 141 // compute and set the checked count 132 142 var checked = 0; 133 this._links.forEach(function(e) { if (e.checked.length) ++checked;});143 this._links.forEach(function(e) { if (e.checked.length){++checked;} }); 134 144 135 145 if (checked) { … … 177 187 case 1: return l.url.usable; 178 188 179 // col 2 is the description 180 case 2: return l.desc; 181 182 // col 3 is the renaming mask 183 case 3: return l.mask ? l.mask : _('default'); 189 // col 2 is the resname 190 case 2: return l.resname; 191 192 // col 3 is the description 193 case 3: return l.desc; 194 195 // col 4 is the renaming mask 196 case 4: return l.mask ? l.mask : _('default'); 184 197 } 185 198 return null; … … 187 200 188 201 isSorted: function() { 189 // not sorted 190 return true; 202 return !!this._sortColumn; 191 203 }, 192 204 isContainer: function(idx) { 193 // being a container means we got children... but we don't have any children because we're a list actually 205 // being a container means we got children... but we don't have any children 206 // because we're a list actually 194 207 return false; 195 208 }, … … 227 240 getCellValue: function(idx, column) { 228 241 // col 0 is the checkbox 229 // didn't test the column index, as there is just one column that may call it 242 // didn't test the column index, as there is just one column that may call 243 // it 230 244 // BEWARE: other code in Dialog will call this function providing no column! 231 245 return this._links[idx].checked.length ? "true" : "false"; … … 245 259 this._sortDirection = false; 246 260 } 261 let sd; 262 this._links.forEach(function(e, i) { e._sortId = i; }); 263 247 264 let tp = this; 248 let sd;265 this._links = Utils.naturalSort(this._links, function(e) tp.getCellText(e._sortId, col)); 249 266 if (this._sortDirection) { 250 sd = function(ca, cb) { return ca > cb ? -1 : ca < cb ? 1 : 0; }; 251 } 252 else { 253 sd = function(ca, cb) { return ca > cb ? 1 : ca < cb ? -1 : 0; }; 254 } 255 this._links.forEach(function(e, i) { e._sortId = i; }); 256 this._links.sort( 257 function(a,b) { 258 return sd(tp.getCellText(a._sortId, col), tp.getCellText(b._sortId, col)); 259 } 260 ); 267 this._links.reverse(); 268 } 261 269 this.invalidate(); 262 270 }, … … 274 282 // AppendElement will just accept nsIAtom. 275 283 // no documentation on devmo, xulplanet though :p 276 prop.AppendElement(this.getAtom(l.checked));284 // prop.AppendElement(this.getAtom(l.checked)); 277 285 }, 278 286 getCellProperties: function(idx, column, prop) { … … 300 308 // a lil' hacky. 301 309 // Dialog.toggleSelection will call us with a null column 302 // makeSelection will invalidate the whole tree after it is done, so we don't have to sacrifice performance here. 310 // makeSelection will invalidate the whole tree after it is done, so we 311 // don't have to sacrifice performance here. 303 312 // we still have to invalidate if it was a click by the user. 304 313 if (col) { … … 505 514 } 506 515 }, 507 // will be called initially and whenever something changed 516 // will be called initially and whenever something changed 508 517 makeSelection: function() { 509 518 let tree = this.current; … … 598 607 for (var i = start.value; i <= end.value; ++i) { 599 608 switch (mode) { 600 // calling setCellValue with a null column will prevent the box from invalidating 609 // calling setCellValue with a null column will prevent the box from 610 // invalidating 601 611 // note, that 602 612 case 1: … … 771 781 if (topic == 'DTA:filterschanged') { 772 782 // the heavy work will be performed by changeTab.. 773 // it will create the filter boxen for us, and furthermore do another selection 783 // it will create the filter boxen for us, and furthermore do another 784 // selection 774 785 this.changeTab(this.current.tab); 775 786 } trunk/chrome/content/dta/select.xul
r983 r1047 95 95 <treecol label="&url.value;" flex="35" crop="right" persist="width hidden" /> 96 96 <splitter class="tree-splitter"/> 97 <treecol label="&resname.value;" flex="15" crop="right" hidden="true" persist="width hidden" /> 98 <splitter class="tree-splitter"/> 97 99 <treecol label="&header.desc.label;" flex="9" persist="width hidden" /> 98 100 <splitter class="tree-splitter"/> trunk/chrome/locale/en-US/select.dtd
r983 r1047 23 23 <!ENTITY disableother.label "Disable other filters"> 24 24 <!ENTITY disableother.tooltip "Disable other filters and only use fast filtering. (This setting is not remembered at the moment)"> 25 <!ENTITY resname.value "Resource name"> trunk/modules/utils.jsm
r1023 r1047 45 45 'formatTimeDelta', 46 46 'getTimestamp', 47 'naturalSort', 47 48 ]; 48 49 … … 207 208 return rv; 208 209 } 210 211 function naturalSort(arr, mapper) { 212 if (typeof mapper != 'function' && !(mapper instanceof Function)) { 213 mapper = function(e) e; 214 } 215 let isDigit = function(a, i) { 216 i = a[i]; 217 return i >= '0' && i <= '9'; 218 }; 219 let compare = function(a, b) { 220 return a === b ? 0 : (a < b ? -1 : 1); 221 } 222 arr = arr.map( 223 function(b) { 224 let e = mapper(b); 225 if (e == null || e == undefined || typeof e == 'number') { 226 return {elem: b, chunks: [e]}; 227 } 228 let a = e.toString().replace(/\b(?:a|one|the)\b/g, ' ').replace(/^\s+|\s+$/g, '').replace(/\s+/g, ' ').toLowerCase(); 229 let len = a.length; 230 if (!len) { 231 return {elem: b, chunks: [a]}; 232 } 233 let rv = []; 234 let last = isDigit(a, 0); 235 let cur = last; 236 start = 0; 237 238 for (let i = 0; i < len; ++i) { 239 cur = isDigit(a, i); 240 if (cur != last) { 241 rv.push(cur ? a.substr(start, i - start) : Number(a.substr(start, i - start))); 242 start = i; 243 last = cur; 244 } 245 } 246 if (!rv.length || len - start != 1) { 247 rv.push(cur ? Number(a.substr(start)) : a.substr(start)); 248 } 249 return {elem: b, chunks: rv}; 250 } 251 ); 252 arr.sort( 253 function (a, b) { 254 let ai, bi; 255 [a, b] = [a.chunks, b.chunks]; 256 let m = Math.max(a.length, b.length); 257 for (let i = 0; i < m; ++i) { 258 let ai = a[i], bi = b[i]; 259 let rv = compare(typeof ai, typeof bi); 260 if (rv) { 261 return rv; 262 } 263 rv = compare(ai, bi); 264 if (rv) { 265 return rv; 266 } 267 } 268 return a.length - b.length; 269 } 270 ); 271 return arr.map(function(a) a.elem); 272 }
