What happened to the Messenger Plus! forums on msghelp.net?
Shoutbox » MsgHelp Archive » Messenger Plus! for Live Messenger » Scripting » [Question] ListViewControl - Numeric sortable Columns

[Question] ListViewControl - Numeric sortable Columns
Author: Message:
tryxter
Junior Member
**

Avatar
A. Maia Ferreira @ PTnet

Posts: 51
Reputation: 1
35 / Male / –
Joined: Jan 2007
O.P. [Question] ListViewControl - Numeric sortable Columns
Since I haven't found it on the schema information, i searched the forums, and I realized that it's not implemented but it's possible to do...

Can anyone explain me how?
01-11-2007 11:00 PM
Profile E-Mail PM Find Quote Report
CookieRevised
Elite Member
*****

Avatar

Posts: 15519
Reputation: 173
– / Male / Flag
Joined: Jul 2003
Status: Away
RE: [Question] ListViewControl - Numeric sortable Columns
Sorting columns doesn't seem to be possible yet as there are no functions or events for it (yet).

Also, using the Windows APIs and subclassing the listview will not work because you must use a callback function to be able to tell the sort APIs how to sort. Which isn't supported in JScript.

However, you can make some workarounds. But those will be just that: dodgy workarounds. eg: You could subclass the listview and detect a column button click. Upon this detection you could clear the entire listview and recreate it using the array you used to store all the elements, but sort it first. But I suggest you don't think about implementing something like this on large lists as it will be relativly slow. Not to mention that user selections, tick boxes, etc all will be cleared each time too (unless you first store those too, and reset them after the new listview is filled in... but which will slow things down even more).

So, either fill your listview with an already sorted list, use the different XML tags and stuff to have a prefixed sort order, or wait until Patchou implements a function/event for it so you can sort on the fly.

This post was edited on 01-12-2007 at 05:05 AM by CookieRevised.
.-= A 'frrrrrrrituurrr' for Wacky =-.
01-12-2007 04:59 AM
Profile PM Find Quote Report
tryxter
Junior Member
**

Avatar
A. Maia Ferreira @ PTnet

Posts: 51
Reputation: 1
35 / Male / –
Joined: Jan 2007
O.P. RE: [Question] ListViewControl - Numeric sortable Columns
I guess I'll try to sort them in the array...
01-12-2007 11:31 AM
Profile E-Mail PM Find Quote Report
Mnjul
forum super mod
******

Avatar
plz wub me

Posts: 5396
Reputation: 58
– / Other / Flag
Joined: Nov 2002
Status: Away
RE: [Question] ListViewControl - Numeric sortable Columns
If you know C/C++, create a DLL for it (that's what I do for HopperLive) :)

This post was edited on 01-12-2007 at 04:41 PM by Mnjul.
01-12-2007 04:41 PM
Profile PM Web Find Quote Report
markee
Veteran Member
*****

Avatar

Posts: 1621
Reputation: 50
36 / Male / Flag
Joined: Jan 2006
RE: [Question] ListViewControl - Numeric sortable Columns
This should take the text that you have in the List View and sort it by the column of your choice (numerically or by text).  I haven't tested it but it should work (I at least checked for syntax errors today 8-)).  I did have something else here but realised I needed to change the sort function for this to be possible.  I hope you like it.  If you want any more information about this (or find a bug) please don't be afraid to ask, you can find my email/WLM address in my profile.
code:
[...]

var PlusWnd;//The Plus/Child Window object that the List View is in
var ControlID;//the ControlId of the List View
var Col;//sort by this column number

[...]

//Get the text in the List View
var arr = new Array();
var i=0;
while(PlusWnd.LstView_GetItemText(ControlID,0,i)!=undefined){
   arr[i] = new Array();
   for(j=0;j<PlusWnd.LstView_GetCount(ControlID);j++){
      arr[i][j] = PlusWnd.LstView_GetItemText(ControlID,j,i);
   }
   i++;
}
//Remove all the text in the List View
while(PlusWnd.LstView_GetCount(ControlID)!=0){
   PlusWnd.ListView_RemoveItem(ControlID,0);
}
//Arrange the data in the correct order
for(i in arr){
   if(i!=Col){
      for(j in arr[i]){
         arr[i][j] = arr[Col][j]+" "+arr[i][j];
      }
      arr[i] = arr[i].sort(num);
   }
}
arr[Col][j] = arr[Col][j].sort(num);
for(i in arr){
   if(i!=Col){
      for(j in arr[i]){
         arr[i][j] = arr[i][j].replace(RegExp("^"+arr[Col][j]+"\s",""),"");
      }
   }
}
//Put text back into the List View
for(j in arr[Col]){
   PlusWnd.LstView_AddItem(ControlID,arr[Col][j],j,Col);
}
for(i in arr){
   if(i!=Col){
      for(j in arr[i]){
         PlusWnd.LstView_SetItemText(ControllID,j,i,arr[i][j]);
      }
   }
}

[...]

//method of sorting array
function num(x,y){
   x_value = parseInt(x);
   y_value = parseInt(y);
   if (x_value > y_value) return 1;
   else if (x_value == y_value) return 0;
   else return -1;
}

This post was edited on 01-13-2007 at 06:22 AM by markee.
[Image: markee.png]
01-13-2007 06:09 AM
Profile PM Find Quote Report
CookieRevised
Elite Member
*****

Avatar

Posts: 15519
Reputation: 173
– / Male / Flag
Joined: Jul 2003
Status: Away
RE: [Question] ListViewControl - Numeric sortable Columns
some remarks on the actual code of markee:

* while(PlusWnd.LstView_GetItemText(ControlID,0,i)!=undefined) isn't going to work since GetItemText is always going to return a string, even for columns which doesn't exist (undefined isn't returned). Thus, the code will probably loop indefinitely. So better use a fixed column count or check upon an empty string.

* There are some issues with the code, especially when used on listviews containing other stuff than numbers. But also on listviews containing only numbers, the sort routine can be made better:

* In your multidimensional array, you take the columns in the first dimension and the items in the second. If you do it the other way around you don't need to concatenate columns, nor use a reg. exp. to strip things back down.
It is also wrong to assume that the rest of the columns need to be sorted too, since they can have any order; aka you don't know which column to sort before the other column.

So, IMHO, better add the sorteable column as the first column, followed by all the other columns, into an array for each element. The main array (dimension 1) simply consists of all these smaller column arrays with the sorteable listview column as first column. Then simply sort that main array and you're done.

* Instead of removing everything and then adding everything again, it will be much faster to change the listview items with LstView_SetItemText once the array is sorted. The number of items doesn't change anyways.

EDIT: oh, and:
//method of sorting array
function num(x,y){
    var number = parseInt( x) - parseInt( y);
    return number === 0 ? 0 : number < 0 ? -1 : 1
}

Thus something like this:
code:
//Get the text in the List View
var arr = new Array();
for (var i=0; i < pPlusWnd.LstView_GetCount(CONTROLID); i++) {
        arr[i] = new Array();
        arr[i][0] = pPlusWnd.LstView_GetItemText(CONTROLID, i, SORTCOL);
        for (var j=0; j < SORTCOL; j++)
                arr[i][j+1] = pPlusWnd.LstView_GetItemText(CONTROLID, i, j);
        for (var j=SORTCOL+1; j < TOTCOLS; j++)
                arr[i][j] = pPlusWnd.LstView_GetItemText(CONTROLID, i, j);
}

//Arrange the data in the correct order
arr = arr.sort(function(x, y) {
        number = parseInt(x) - parseInt(y);
        return number == 0 ? 0 : number < 0 ? -1 : 1
});

//Put text back into the List View
for (var i=0; i < pPlusWnd.LstView_GetCount(CONTROLID); i++) {
        pPlusWnd.LstView_SetItemText(CONTROLID, i, SORTCOL, arr[i][0])
        for (var j=0; j < SORTCOL; j++)
                pPlusWnd.LstView_SetItemText(CONTROLID, i, j, arr[i][j+1]);
        for (var j=SORTCOL+1; j < TOTCOLS; j++)
                pPlusWnd.LstView_SetItemText(CONTROLID, i, j, arr[i][j]);
}
Where TOTCOLS is the total number of columns in the listview.
And SORTCOL is the column index (base 0) to sort.

This can of course be optimized further depending on how many columns you have, etc

And if you want sort descending, then either:
- change "-1 : 1"  into  "1: -1"
- or change "parseInt( x) - parseInt( y)"  into  "parseInt( y) - parseInt( x)"
- or change "number < 0"  into  "number > 0"
                      (well, you catch my drift: make sure the returned sign is changed in one way or the other :p)
in the unnamed sort function.

;)

This post was edited on 08-12-2007 at 05:41 PM by CookieRevised.
.-= A 'frrrrrrrituurrr' for Wacky =-.
01-13-2007 07:22 AM
Profile PM Find Quote Report
« Next Oldest Return to Top Next Newest »


Threaded Mode | Linear Mode
View a Printable Version
Send this Thread to a Friend
Subscribe | Add to Favorites
Rate This Thread:

Forum Jump:

Forum Rules:
You cannot post new threads
You cannot post replies
You cannot post attachments
You can edit your posts
HTML is Off
myCode is On
Smilies are On
[img] Code is On