Changeset 1047

Show
Ignore:
Timestamp:
2008-08-20 14:24:07 (3 months ago)
Author:
MaierMan
Message:
  • Use naturalSort in select
  • Provide Resource Name column (hidden per default)
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/chrome/content/common/internalFunctions.js

    r1028 r1047  
    7474/** 
    7575 * 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. 
    7881 */ 
    7982function $() { 
     
    97100        /** 
    98101         * 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 
    100105         * @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. 
    102108         */ 
    103109        FilePicker: Components.Constructor('@mozilla.org/filepicker;1', 'nsIFilePicker', 'init'), 
     
    128134        }, 
    129135        /** 
    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 
    133143         */ 
    134144        validateDir: function(path) { 
     
    165175        }, 
    166176        /** 
    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 
    170182         * @return the disk-space available to the caller 
    171183         * @author Nils 
     
    182194        /** 
    183195         * 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) 
    185200         */ 
    186201        playSound: function(name) { 
     
    197212        /** 
    198213         * returns a formated representation of a (file) size 
    199          * @param aNumber The number to format 
     214         *  
     215         * @param aNumber 
     216         *          The number to format 
    200217         * @author Nils 
    201218         */ 
     
    314331); 
    315332 
    316  
    317333/** 
    318334 * Get the icon URI corresponding to an URI (special mac handling) 
     335 *  
    319336 * @author Nils 
    320337 * @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; 
    324344 * @return String containing the icon URI 
    325345 */ 
     
    383403 
    384404/** 
    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 *  
    386408 * @author Nils 
    387409 * @see _ 
     
    420442/** 
    421443 * 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 
    424449 * @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 
    426452 * @author Nils 
    427453 */ 
     
    439465/** 
    440466 * XP compatible reveal/launch 
     467 *  
    441468 * @author Nils (derived from DownloadManager code) 
    442469 */ 
     
    461488        /** 
    462489         * Launch/Execute a file 
    463          * @param nsILocalFile/String pointing to the desired file 
     490         *  
     491         * @param nsILocalFile/String 
     492         *          pointing to the desired file 
    464493         */ 
    465494        launch: function(file) { 
     
    478507        }, 
    479508        /** 
    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 
    482514         */ 
    483515        reveal: function(file) { 
     
    503535/** 
    504536 * 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) 
    509549 * @return A string representing the hash a in given encoding. 
    510550 * @author Nils 
  • trunk/chrome/content/dta/select.js

    r1030 r1047  
    3939 
    4040/** 
    41  * implemtents nsITreeView 
    42  * manages our link trees 
     41 * implemtents nsITreeView manages our link trees 
    4342 */ 
    4443function Tree(links, type) { 
     
    4948        // internal list of links. 
    5049        // 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( 
    5351                function(link) { 
    5452                        // "lazy initialize" the icons. 
    5553                        // 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. 
    5756                        link.__defineGetter__( 
    5857                                'icon', 
     
    8180                                } 
    8281                        ); 
    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 
    8594                        link.checked = ''; 
    8695                        link.mask = null; 
    87                 }, 
    88                 this 
     96                       return link; 
     97                } 
    8998        ); 
    9099 
     
    101110 
    102111        // 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. 
    104114        getAtom: function(str) { 
    105115                if (!(str in this._atoms)) { 
     
    131141                // compute and set the checked count 
    132142                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;} }); 
    134144 
    135145                if (checked) { 
     
    177187                        case 1: return l.url.usable; 
    178188 
    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'); 
    184197                } 
    185198                return null; 
     
    187200 
    188201        isSorted: function() { 
    189                 // not sorted 
    190                 return true; 
     202                return !!this._sortColumn; 
    191203        }, 
    192204        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 
    194207                return false; 
    195208        }, 
     
    227240        getCellValue: function(idx, column) { 
    228241                // 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 
    230244                // BEWARE: other code in Dialog will call this function providing no column! 
    231245                return this._links[idx].checked.length ? "true" : "false"; 
     
    245259                        this._sortDirection = false; 
    246260                } 
     261                let sd; 
     262                this._links.forEach(function(e, i) { e._sortId = i; }); 
     263                 
    247264                let tp = this; 
    248                 let sd
     265                this._links = Utils.naturalSort(this._links, function(e) tp.getCellText(e._sortId, col))
    249266                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                } 
    261269                this.invalidate(); 
    262270        }, 
     
    274282                // AppendElement will just accept nsIAtom. 
    275283                // no documentation on devmo, xulplanet though :p 
    276                 prop.AppendElement(this.getAtom(l.checked)); 
     284                // prop.AppendElement(this.getAtom(l.checked)); 
    277285        }, 
    278286        getCellProperties: function(idx, column, prop) { 
     
    300308                // a lil' hacky. 
    301309                // 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. 
    303312                // we still have to invalidate if it was a click by the user. 
    304313                if (col) { 
     
    505514                } 
    506515        }, 
    507         // will be called initially and whenever something changed      
     516        // will be called initially and whenever something changed 
    508517        makeSelection: function() { 
    509518                let tree = this.current; 
     
    598607                        for (var i = start.value; i <= end.value; ++i) { 
    599608                                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 
    601611                                        // note, that 
    602612                                        case 1: 
     
    771781                if (topic == 'DTA:filterschanged') { 
    772782                        // 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 
    774785                        this.changeTab(this.current.tab); 
    775786                } 
  • trunk/chrome/content/dta/select.xul

    r983 r1047  
    9595                        <treecol label="&url.value;" flex="35" crop="right" persist="width hidden" /> 
    9696                        <splitter class="tree-splitter"/> 
     97                        <treecol label="&resname.value;" flex="15" crop="right" hidden="true" persist="width hidden" /> 
     98                        <splitter class="tree-splitter"/> 
    9799                        <treecol label="&header.desc.label;" flex="9" persist="width hidden" /> 
    98100                        <splitter class="tree-splitter"/> 
  • trunk/chrome/locale/en-US/select.dtd

    r983 r1047  
    2323<!ENTITY disableother.label "Disable other filters"> 
    2424<!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  
    4545        'formatTimeDelta', 
    4646        'getTimestamp', 
     47        'naturalSort', 
    4748]; 
    4849 
     
    207208        return rv; 
    208209} 
     210 
     211function 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}