Hi,

You'll find attached a patch for custom contact sorting.
Currently (and the default value in the patch) they are sorted by status
and activity.
Other possibilities are:
by status and nickname
by activity
by nickname


Awaiting comments,
Iulian

PS: the patch was made against the davrieb#mob git repository.
diff --git a/src/hooks/abstracthook.cc b/src/hooks/abstracthook.cc
index d9cd149..cc29f9a 100644
--- a/src/hooks/abstracthook.cc
+++ b/src/hooks/abstracthook.cc
@@ -33,6 +33,7 @@
 #include "ljhook.h"
 #include "gaduhook.h"
 #include "msnhook.h"
+#include "icqcontacts.h"
 
 #include "icqface.h"
 
diff --git a/src/hooks/gaduhook.cc b/src/hooks/gaduhook.cc
index 50ccf17..f573db6 100644
--- a/src/hooks/gaduhook.cc
+++ b/src/hooks/gaduhook.cc
@@ -30,6 +30,7 @@
 #include "gaduhook.h"
 #include "icqface.h"
 #include "imlogger.h"
+#include "icqcontacts.h"
 
 #include "libgadu-config.h"
 #include "libgadu.h"
diff --git a/src/hooks/icqhook.cc b/src/hooks/icqhook.cc
index 0eced48..58ae51e 100644
--- a/src/hooks/icqhook.cc
+++ b/src/hooks/icqhook.cc
@@ -31,6 +31,7 @@
 #include "icqface.h"
 #include "imlogger.h"
 #include "icqgroups.h"
+#include "icqcontacts.h"
 
 #include "accountmanager.h"
 #include "eventmanager.h"
diff --git a/src/hooks/icqhook.h b/src/hooks/icqhook.h
index 49dc3ec..9a6a132 100644
--- a/src/hooks/icqhook.h
+++ b/src/hooks/icqhook.h
@@ -6,7 +6,6 @@
 #ifdef BUILD_ICQ
 
 #include "icqmlist.h"
-#include "icqcontacts.h"
 
 #include "libicq2000/Client.h"
 #include "libicq2000/events.h"
diff --git a/src/hooks/jabberhook.cc b/src/hooks/jabberhook.cc
index 174fb7b..99637e8 100644
--- a/src/hooks/jabberhook.cc
+++ b/src/hooks/jabberhook.cc
@@ -32,6 +32,7 @@
 #include "eventmanager.h"
 #include "icqgroups.h"
 #include "impgp.h"
+#include "icqcontacts.h"
 
 #ifdef HAVE_LIBOTR
   #include "imotr.h"
diff --git a/src/hooks/ljhook.cc b/src/hooks/ljhook.cc
index 440e608..91a1b12 100644
--- a/src/hooks/ljhook.cc
+++ b/src/hooks/ljhook.cc
@@ -30,6 +30,7 @@
 #include "rsshook.h"
 #include "icqface.h"
 #include "eventmanager.h"
+#include "icqcontacts.h"
 
 #include <sys/utsname.h>
 
diff --git a/src/icqconf.cc b/src/icqconf.cc
index b08e6f0..70e103c 100644
--- a/src/icqconf.cc
+++ b/src/icqconf.cc
@@ -50,6 +50,7 @@ icqconf::icqconf() {
     rc = rcdark;
     cm = cmproto;
     fgroupmode = nogroups;
+    fsortmode = sort_by_status_and_activity;
 
     autoaway = autona = 0;
 
@@ -490,6 +491,10 @@ void icqconf::loadmainconfig() {
            if(param == "group2") fgroupmode = group2; else
            if(param == "protocolormode") cm = icqconf::cmproto; else
            if(param == "statuscolormode") cm = icqconf::cmstatus; else
+           if(param == "sort_by_status_and_activity") 
setsortmode(icqconf::sort_by_status_and_activity); else
+           if(param == "sort_by_status_and_name") 
setsortmode(icqconf::sort_by_status_and_name); else
+           if(param == "sort_by_activity") 
setsortmode(icqconf::sort_by_activity); else
+           if(param == "sort_by_name") setsortmode(icqconf::sort_by_name); else
            if(param == "smtp") setsmtphost(buf); else
            if(param == "browser") setbrowser(browser); else
            if(param == "http_proxy") sethttpproxyhost(buf); else
@@ -632,6 +637,13 @@ void icqconf::save() {
                    break;
            }
 
+           switch(getsortmode()) {
+               case sort_by_status_and_activity: f << 
"sort_by_status_and_activity" << endl; break;
+               case sort_by_status_and_name: f << "sort_by_status_and_name" << 
endl; break;
+               case sort_by_activity: f << "sort_by_activity" << endl; break;
+               case sort_by_name: f << "sort_by_name" << endl; break;
+           }
+            
            if(getmakelog()) f << "log" << endl;
            if(getproxyconnect()) f << "proxy_connect" << endl;
            if(getproxyssl()) f << "proxy_ssl" << endl;
@@ -1582,6 +1594,11 @@ void icqconf::setgroupmode(icqconf::groupmode amode) {
     fgroupmode = amode;
 }
 
+void icqconf::setsortmode(icqconf::sortmode smode) {
+    fsortmode = smode;
+    icqcontacts::setsortmode(smode);
+}
+
 void icqconf::initmultiproto(bool p[], string buf, bool excludenochat) {
     string w;
     protocolname pname;
diff --git a/src/icqconf.h b/src/icqconf.h
index f95b1f8..8acf6a4 100644
--- a/src/icqconf.h
+++ b/src/icqconf.h
@@ -15,7 +15,6 @@
 #include "colorschemer.h"
 
 #include "icqgroup.h"
-#include "icqcontact.h"
 
 #include "captcha.h"
 
@@ -104,6 +103,13 @@ class icqconf {
        enum regcolor { rcdark, rcblue, rcdontchange };
        enum groupmode { group1, group2, nogroups };
        enum colormode { cmproto, cmstatus };
+       // leave the sort_by_nb_of_sorts as the last value
+       // do not forget to add the new sort types to the icqcontacts.cc
+       enum sortmode { sort_by_status_and_activity,
+                       sort_by_status_and_name,
+                       sort_by_activity,
+                       sort_by_name,
+                       sort_by_nb_of_sorts};
 
        struct imserver {
            string server;
@@ -176,6 +182,7 @@ class icqconf {
        regcolor rc;
        groupmode fgroupmode;
        colormode cm;
+       sortmode fsortmode;
        int leftpanelwidth;
        int logpanelheight;
        int chatpanelheight;
@@ -296,6 +303,9 @@ class icqconf {
        groupmode getgroupmode() const { return fgroupmode; }
        void setgroupmode(groupmode amode);
 
+       sortmode getsortmode() const { return fsortmode; }
+       void setsortmode(sortmode smode);
+
        string getsockshost() const;
        unsigned int getsocksport() const;
        void setsockshost(const string &nsockshost);
diff --git a/src/icqcontact.cc b/src/icqcontact.cc
index 0804974..8314926 100644
--- a/src/icqcontact.cc
+++ b/src/icqcontact.cc
@@ -733,15 +733,25 @@ char icqcontact::getshortstatus() const {
 }
 
 bool icqcontact::operator > (const icqcontact &acontact) const {
-    if(acontact.lastread != lastread) {
-       return acontact.lastread > lastread;
-    } else if(acontact.cdesc.uin != cdesc.uin) {
-       return acontact.cdesc.uin > cdesc.uin;
+    if(lastread != acontact.lastread) {
+       return lastread < acontact.lastread;
+    } else if(cdesc.uin != acontact.cdesc.uin) {
+       return cdesc.uin > acontact.cdesc.uin;
     } else {
-       return acontact.cdesc.nickname.compare(cdesc.nickname);
+       return cdesc.nickname.compare(acontact.cdesc.nickname);
     }
 }
 
+// this is the bizaare compare by last read, then uin, then nickname
+int icqcontact::compare1(const icqcontact& a, const icqcontact& b){
+    return a > b ? 1 : -1;
+}
+
+// this is the compare by nickname
+int icqcontact::compare2(const icqcontact& a, const icqcontact& b){
+    return a.getdispnick().compare(b.getdispnick());
+}
+
 void icqcontact::setpostponed(const string &apostponed) {
     if(apostponed.find_first_not_of(" \r\n") != -1) postponed = apostponed;
        else postponed = "";
diff --git a/src/icqcontact.h b/src/icqcontact.h
index 5fb73bf..de3d69a 100644
--- a/src/icqcontact.h
+++ b/src/icqcontact.h
@@ -164,6 +164,8 @@ class icqcontact {
        void remindbirthday(bool r);
 
        bool operator > (const icqcontact &acontact) const;
+       static int compare1(const icqcontact& a, const icqcontact& b);
+       static int compare2(const icqcontact& a, const icqcontact& b);
 
        time_t getlasttyping() const { return lasttyping; }
        void setlasttyping(time_t t) { lasttyping = t; }
diff --git a/src/icqcontacts.cc b/src/icqcontacts.cc
index 6d42f91..c62607a 100644
--- a/src/icqcontacts.cc
+++ b/src/icqcontacts.cc
@@ -28,6 +28,52 @@
 #include "icqgroups.h"
 #include "abstracthook.h"
 
+/*
+*
+* SORT_CONTACTS
+*
+* o Online
+* f Free for chat
+* i Invisible
+* d Do not disturb
+* c Occupied
+* a Away
+* n N/A
+*
+* _ Offline
+* ! Not in list
+* N Non-ICQ
+* # Unread
+*
+*/
+
+#define SORT_CONTACTS   "#odcanl_!N"
+
+// this is the original status sort, where the contacts
+// get sorted by status
+static char getsortstatus1(const icqcontact& c){
+    return     c.hasevents() ? '#' : \
+    !c.inlist() ? '!' : \
+    c.getstatus() == invisible ? 'o' : \
+    c.getstatus() == freeforchat ? 'o' : \
+    c.getshortstatus() \
+;
+}
+
+// this is the modified status sort, where the contacts
+// don't get sorted by status (only by name or whatever)
+static char getsortstatus2(const icqcontact& c){
+    return c.hasevents() ? '#' : !c.inlist() ? '!' : 'o';
+}
+
+static icqcontacts_sort sortmodes[icqconf::sort_by_nb_of_sorts] = {
+    {getsortstatus1, icqcontact::compare1}, // sort_by_status_and_activity
+    {getsortstatus1, icqcontact::compare2}, // sort_by_status_and_name
+    {getsortstatus2, icqcontact::compare1}, // sort_by_activity
+    {getsortstatus2, icqcontact::compare2}  // sort_by_name
+};
+
+icqcontacts_sort *icqcontacts::sort_order = 
&sortmodes[icqconf::sort_by_status_and_activity];
 
 /* Function used to delete icqcontact when removed from the list */
 static void deletecontact(void *contact){
@@ -204,14 +250,18 @@ icqcontact *icqcontacts::get(const imcontact &cinfo) {
     return 0;
 }
 
+void icqcontacts::setsortmode(icqconf::sortmode smode){
+    sort_order = sortmodes+smode;
+}
+
 int icqcontacts::clistsort(void *p1, void *p2) {
     icqcontact *c1 = (icqcontact *) p1, *c2 = (icqcontact *) p2;
     static char *sorder = SORT_CONTACTS;
     char s1, s2;
     bool makegroup;
 
-    s1 = SORTCHAR(c1);
-    s2 = SORTCHAR(c2);
+    s1 = sort_order->sortstatus(*c1);
+    s2 = sort_order->sortstatus(*c2);
 
     switch(conf.getgroupmode()) {
        case icqconf::group1:
@@ -231,9 +281,9 @@ int icqcontacts::clistsort(void *p1, void *p2) {
        if(c1->getgroupid() > c2->getgroupid()) return -1; else
        if(c1->getgroupid() < c2->getgroupid()) return 1;
     }
-
+    
     if(s1 == s2) {
-       if(*c1 > *c2) return -1; else return 1;
+       return -sort_order->compare(*c1,*c2);
     } else {
        if(strchr(sorder, s1) > strchr(sorder, s2)) return -1; else return 1;
     }
diff --git a/src/icqcontacts.h b/src/icqcontacts.h
index 4a9ffd8..39ff3e7 100644
--- a/src/icqcontacts.h
+++ b/src/icqcontacts.h
@@ -1,44 +1,35 @@
 #ifndef __ICQCONTACTS_H__
 #define __ICQCONTACTS_H__
 
-/*
-*
-* SORT_CONTACTS
-*
-* o Online
-* f Free for chat
-* i Invisible
-* d Do not disturb
-* c Occupied
-* a Away
-* n N/A
-*
-* _ Offline
-* ! Not in list
-* N Non-ICQ
-* # Unread
-*
-*/
-
-#define SORT_CONTACTS   "#odcanl_!N"
-
-#define SORTCHAR(c) ( \
-    c->hasevents() ? '#' : \
-    !c->inlist() ? '!' : \
-    c->getstatus() == invisible ? 'o' : \
-    c->getstatus() == freeforchat ? 'o' : \
-    c->getshortstatus() \
-)
 
 #include "cmenus.h"
 
+#include "icqconf.h"
 #include "linkedlist.h"
 #include "icqcontact.h"
 #include "icqcommon.h"
 
+// a structure to keep the two methods used for sorting
+struct icqcontacts_sort {
+    /** the first sort is done by status (sortstatus function)
+     * that returns a custom character for each contact and
+     * and the order of status is found in icqcontacts.cc
+     * see SORT_CONTACTS define
+     */
+    char (*sortstatus)(const icqcontact& a);
+    /** the second sort is done when the contacts have
+     * the same status category as returned by sortstatus
+     * and they are compared with the "compare" function.
+     */
+    int (*compare)(const icqcontact& a, const icqcontact& b);
+};
+
 class icqcontacts: public linkedlist {
     protected:
        static int clistsort(void *p1, void *p2);
+    public:
+       static void setsortmode(icqconf::sortmode smode);
+       static icqcontacts_sort* sort_order;
 
     public:
        icqcontacts();
diff --git a/src/icqdialogs.cc b/src/icqdialogs.cc
index 766ac96..19cec67 100644
--- a/src/icqdialogs.cc
+++ b/src/icqdialogs.cc
@@ -67,6 +67,17 @@ const char *strrandomgroup(short unsigned int gr) {
     return "";
 }
 
+const char *strsortmode(icqconf::sortmode smode) {
+    switch(smode) {
+       case icqconf::sort_by_status_and_activity: return _("Status and 
Activity");
+       case icqconf::sort_by_status_and_name: return _("Status and Name");
+       case icqconf::sort_by_activity: return _("Activity");
+       case icqconf::sort_by_name: return _("Name");
+    }
+
+    return "";
+}
+
 bool icqface::sprofmanager(string &name, string &act) {
     dialogbox db;
     string buf, tname;
@@ -1147,6 +1158,7 @@ bool icqface::updateconf(icqconf::regsound &s, 
icqconf::regcolor &c) {
 
     icqconf::groupmode gmode = conf.getgroupmode();
     icqconf::colormode cm = conf.getcolormode();
+    icqconf::sortmode smode = conf.getsortmode();
 
     bool chatmode[protocolname_size], conv[protocolname_size],
        entersends[protocolname_size], nonimonline[protocolname_size];
@@ -1220,6 +1232,7 @@ bool icqface::updateconf(icqconf::regsound &s, 
icqconf::regcolor &c) {
 
        i = t.addnode(_(" Contact list "));
        t.addleaff(i, 0, 17, _(" Arrange contacts into groups : %s "), 
strgroupmode(gmode));
+       t.addleaff(i, 0, 54, _(" Sort contacts by : %s "), strsortmode(smode));
        t.addleaff(i, 0,  6, _(" Hide offline users : %s "), 
stryesno(hideoffl));
        t.addleaff(i, 0, 14, _(" Anti-spam: kill msgs from users not on the 
list : %s "), stryesno(antispam));
        t.addleaff(i, 0, 51, _(" Anti-spam: ignore authorization requests: %s 
"), stryesno(dropauthreq));
@@ -1450,6 +1463,13 @@ bool icqface::updateconf(icqconf::regsound &s, 
icqconf::regcolor &c) {
                    case 53:
                        askquit = !askquit;
                        break;
+                   case 54:
+                       smode =
+                           smode == icqconf::sort_by_status_and_activity ? 
icqconf::sort_by_status_and_name :
+                           smode == icqconf::sort_by_status_and_name ? 
icqconf::sort_by_activity :
+                           smode == icqconf::sort_by_activity ? 
icqconf::sort_by_name :
+                               icqconf::sort_by_status_and_activity;
+                       break;
                }
                break;
            case 1:
@@ -1492,6 +1512,9 @@ bool icqface::updateconf(icqconf::regsound &s, 
icqconf::regcolor &c) {
                    clist.rearrange();
                }
                conf.setcolormode(cm);
+               if (conf.getsortmode() != smode){
+                   conf.setsortmode(smode);
+               }
 
                conf.setsmtphost(smtp);
                conf.setbrowser(browser);
diff --git a/src/icqface.cc b/src/icqface.cc
index e89ecf6..928ea3c 100644
--- a/src/icqface.cc
+++ b/src/icqface.cc
@@ -673,7 +673,7 @@ void icqface::fillcontactlist() {
            continue;
        }
 
-       sc = SORTCHAR(c);
+       sc = icqcontacts::sort_order->sortstatus(*c);
 
        groupchange =
            (conf.getgroupmode() != icqconf::nogroups) &&
diff --git a/src/icqgroup.cc b/src/icqgroup.cc
index dd939d6..04c3062 100644
--- a/src/icqgroup.cc
+++ b/src/icqgroup.cc
@@ -24,6 +24,7 @@
 
 #include "icqgroup.h"
 #include "icqgroups.h"
+#include "icqcontacts.h"
 #include "abstracthook.h"
 
 icqgroup::icqgroup(int aid, const string &aname) {
diff --git a/src/icqgroup.h b/src/icqgroup.h
index c5dabfe..7b4cfaa 100644
--- a/src/icqgroup.h
+++ b/src/icqgroup.h
@@ -2,7 +2,6 @@
 #define __ICQGROUP_H__
 
 #include "icqcommon.h"
-#include "icqcontacts.h"
 #include "imcontact.h"
 
 class icqgroup {
diff --git a/src/imcontact.cc b/src/imcontact.cc
index c771b4f..21e5e9a 100644
--- a/src/imcontact.cc
+++ b/src/imcontact.cc
@@ -23,6 +23,7 @@
 */
 
 #include "imcontact.h"
+#include "icqcontact.h"
 #include "icqconf.h"
 
 imcontact contactroot(0, icq);
diff --git a/src/imcontroller.h b/src/imcontroller.h
index 1be908a..4ba361e 100644
--- a/src/imcontroller.h
+++ b/src/imcontroller.h
@@ -2,6 +2,7 @@
 #define __IMCONTROLLER_H__
 
 #include "icqconf.h"
+#include "icqcontact.h"
 
 #include <libicq2000/userinfoconstants.h>
 
diff --git a/src/imotr.cc b/src/imotr.cc
index eec3145..62d5c3c 100644
--- a/src/imotr.cc
+++ b/src/imotr.cc
@@ -1,6 +1,7 @@
 #include "imotr.h"
 #include "icqconf.h"
 #include "icqface.h"
+#include "icqcontacts.h"
 #include "abstracthook.h"
 #include "centerim.h"
 #include "hooks/jabberhook.h"
diff --git a/src/impgp.cc b/src/impgp.cc
index d390000..f62f923 100644
--- a/src/impgp.cc
+++ b/src/impgp.cc
@@ -4,6 +4,7 @@
 
 #include "icqconf.h"
 #include "icqface.h"
+#include "icqcontacts.h"
 #include "abstracthook.h"
 
 impgp pgp;
-- 
_______________________________________________
Centerim-devel mailing list
[email protected]
http://centerim.org/mailman/listinfo/centerim-devel
http://www.centerim.org/

Reply via email to