Download this source

I take no responsibility for this source. It's freeware, do whatever you like with it.

This source show how to sort and refresh a listview-gadget. The sort-gadget exchange the direction every time.

;
#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <utility/tagitem.h>
#include <libraries/gadtools.h>

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include <clib/exec_protos.h>
#include <clib/graphics_protos.h>
#include <clib/intuition_protos.h>
#include <clib/gadtools_protos.h>

#define LISTLEFT Secwin[0]
#define LISTTOP  Secwin[1]
#define LISTWIDTH Secwin[2]
#define LISTHEIGHT Secwin[3]
#define MAXROW  20
#define GADHEIGHT 20

SHORT Secwin[4]   = {0,139,446,88};  /* List-windows position */
BOOL flag;

struct Month
{
  struct Node nd;
  UBYTE txt[MAXROW];
};

void NewList(struct List *);

void bail_out(int code, STRPTR error),CreateAllGadgets(WORD,WORD);
ULONG SortList( struct List * );
int NodeNameCompare( struct Node **, struct Node ** );
int NodeNameCompare2( struct Node **, struct Node ** );

STRPTR MonthLabels[] =
{
 "January",
 "February",
 "March",
 "April",
 "May",
 "June",
 "July",
 "August",
 "September",
 "October",
 "November",
 "December",
 NULL,
};

struct List listpek;

struct Screen *mysc;
struct Remember *RKey;
struct Gadget *glist;
struct Window *mywin;
void *vi;

BOOL terminated;

struct Gadget *lvgad,*gad;
WORD x,y;

void main(void)
{
 struct IntuiMessage *imsg;
 struct Gadget *gad;
 ULONG imsgClass;
 UWORD imsgCode;

 terminated = FALSE;

 if(!(mysc = LockPubScreen(NULL)))
  bail_out(20, "Couldn't lock default public screen");

 if(!(vi = GetVisualInfo(mysc,TAG_DONE)))
  bail_out(20, "GetVisualInfo() failed");

 if(!(mywin = (struct Window *)OpenWindowTags(NULL,
  WA_Left,LISTLEFT,WA_Top,LISTTOP,WA_InnerWidth,LISTWIDTH,WA_InnerHeight,LISTHEIGHT,

  WA_IDCMP,LISTVIEWIDCMP | IDCMP_CLOSEWINDOW | IDCMP_NEWSIZE,

  WA_Flags,WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET,
  WA_PubScreen,NULL,TAG_DONE)))
   bail_out(20, "OpenWindow() failed");

 CreateAllGadgets(LISTWIDTH,LISTHEIGHT);

 while(!terminated)
 {
  Wait(1 << mywin->UserPort->mp_SigBit);
  while((!terminated) && (imsg = GT_GetIMsg(mywin->UserPort)))
  {
   imsgClass = imsg->Class;
   imsgCode = imsg->Code;
   gad = (struct Gadget *)imsg->IAddress;
   GT_ReplyIMsg(imsg);
   switch (imsgClass)
   {
    case GADGETUP:
      if(gad->GadgetID == 1)
      {
        flag ^= 1;        /* switch between 0 and 1 */
            GT_SetGadgetAttrs(lvgad,mywin,NULL,GTLV_Labels, ~0, TAG_DONE);
        SortList(&listpek);
           GT_SetGadgetAttrs(lvgad,mywin,NULL,GTLV_Labels, &listpek, TAG_DONE);
        }
      else
      {
       printf("GADGETUP.  ");
       printf("ListView: clicked on '%s'\n", MonthLabels[imsgCode]);
          }
     break;

    case NEWSIZE:
     RemoveGList(mywin,glist, -1);
     FreeGadgets(glist);
     x = mywin->Width - mywin->BorderLeft - mywin->BorderRight;
     y = mywin->Height - mywin->BorderTop - mywin->BorderBottom;
     Move(mywin->RPort,0,0);
     ClearScreen(mywin->RPort);
     CreateAllGadgets(x,y);
     break;

    case CLOSEWINDOW:
     terminated = TRUE;
     break;

    case IDCMP_REFRESHWINDOW:
     GT_BeginRefresh(mywin);
     GT_EndRefresh(mywin,TRUE);
   }
  }
 }
 bail_out(0, NULL);
}

void bail_out(int code, STRPTR error)
{
 if (mywin)
  CloseWindow(mywin);

  if(vi)
  FreeVisualInfo(vi);

 if(glist)
  FreeGadgets(glist);

 if (mysc)
  UnlockPubScreen(NULL, mysc);

 if (RKey)
  FreeRemember(&RKey, TRUE);

 if (error)
  printf("Error: %s\n", error);
 exit(code);
}

void CreateAllGadgets(WORD x, WORD y)
{
 struct NewGadget ng;

 WORD index;
 struct Month *node;

 gad = CreateContext(&glist);
 if(!RKey)
 {
  NewList(&listpek);
  index = 0;
  while (MonthLabels[index])
  {
   node = (struct Month *)AllocRemember(&RKey, sizeof(struct Month), MEMF_CLEAR);
   sprintf(node->txt,"%s",MonthLabels[index++]);
   node->nd.ln_Name = (UBYTE *)node->txt;
   AddTail(&listpek, &node->nd);
  }
 }

 ng.ng_LeftEdge = mywin->BorderLeft;
 ng.ng_TopEdge = mywin->BorderTop;
 ng.ng_Height = GADHEIGHT;
 ng.ng_Width = x;
 ng.ng_VisualInfo = vi;
 ng.ng_GadgetText = "Sort";
 ng.ng_TextAttr = NULL;
 ng.ng_GadgetID = 1;
 ng.ng_Flags = 0;

 lvgad = gad = CreateGadget(BUTTON_KIND, gad, &ng, GTLV_Labels, &listpek, TAG_DONE);

 ng.ng_Height = y - GADHEIGHT;
 ng.ng_TopEdge = mywin->BorderTop + GADHEIGHT;
 ng.ng_GadgetID = 2;
 lvgad = CreateGadget(LISTVIEW_KIND, gad, &ng, GTLV_Labels, &listpek, TAG_DONE);
 AddGList(mywin,glist,-1, -1, NULL);
 RefreshWindowFrame(mywin);
 RefreshGList(glist, mywin, NULL, -1);
 GT_RefreshWindow(mywin, NULL);
}

/* The Function that is sent to qsort(). compare 2 strings*/
int NodeNameCompare(struct Node **node1, struct Node **node2 )
{
  return( strcmp( ( *node1 )->ln_Name, ( *node2 )->ln_Name ) );
}

int NodeNameCompare2(struct Node **node1, struct Node **node2 )
{
  return( strcmp( ( *node2 )->ln_Name, ( *node1 )->ln_Name ) );
}


/* Sort a linked list in the ln_Name field.
 * Returns:
 * 0 = All ok.
 * 1 = No mem
 */

ULONG SortList( struct List *list )
{
  struct Node *node;
  LONG nodecount = 0;
  struct Node **buf;

/* Count  nodes */
  for( node = list->lh_Head; node->ln_Succ; node = node->ln_Succ )
    nodecount++;

/* Allocates 1 memblock for pointer to sort*/
  if( buf = ( struct Node ** ) AllocVec( nodecount * 4, 0 ) )
  {
/* 2 identical Nodes buf,work */
    struct Node **work = buf;

/*  Copy the pointers */
    for( node = list->lh_Head; node->ln_Succ; node = node->ln_Succ )
      *work++ = node;

    if(flag)
      qsort( buf, nodecount, 4, NodeNameCompare );
    else
      qsort( buf, nodecount, 4, NodeNameCompare2 );

    NewList( list );

/* Put the names back in the Struct List * */
    for( work = buf; nodecount--; )
      AddTail( list, *work++ );

    FreeVec( buf );
    return( 0 );
  }
  else
    return( 1 );
}