Hi all,

I have rewritten the auto-away logic and would like you all to test it out and 
tell me how it works for you. This is how I'm hoping it will work:
- auto-away, except from offline and NA
- auto-na, except from offline
- auto-offline, except from offline
- never change status from offline except when it's auto-offline
- always return to the status that was set before auto-away/na/offline
- separate behaviour for all protocols

For testing purposes 1 min is just 30 secs in the this patch. Also note that 
it might take up to 10 secs for Licq to notice that you are active again, so 
show some patience :) And having the network window open is a good way to see 
what's happening.

// Erik

-- 
Don't worry, tomorrow won't be a better day!

Erik Johansson
http://ejohansson.se
Index: src/mainwin.cpp
===================================================================
--- src/mainwin.cpp	(revision 4614)
+++ src/mainwin.cpp	(working copy)
@@ -135,6 +135,7 @@
 
 }
 
+#include <map>
 #include <cctype>
 
 using std::isdigit;
@@ -147,8 +148,6 @@
 #undef FocusOut
 #undef Status
 
-extern char *PPIDSTRING(unsigned long);
-
 static QPixmap *ScaleWithBorder(const QPixmap &pm, int w, int h, struct Border border)
 {
    QPainter p;
@@ -3952,20 +3951,23 @@
    mnuSystem->setItemChecked(mnuSystem->idAt(MNUxITEM_MINIxMODE), m_bInMiniMode);
 }
 
+struct SAutoAwayInfo
+{
+  SAutoAwayInfo() : isAutoAway(false) {}
+  bool isAutoAway;
 
+  unsigned short preAutoAwayStatus;
+  unsigned short setAutoAwayStatus;
+};
+
 //-----CMainWindow::autoAway--------------------------------------------------
 void CMainWindow::autoAway()
 {
-#ifdef USE_SCRNSAVER
+#ifndef USE_SCRNSAVER
+  autoAwayTimer.stop();
+#else
   static XScreenSaverInfo *mit_info = NULL;
-  static bool bAutoAway = false;
-  static bool bAutoNA = false;
-  static bool bAutoOffline = false;
 
-  bool bTempAutoAway = bAutoAway;
-  bool bTempAutoNA = bAutoNA;
-  bool bTempAutoOffline = bAutoOffline;
-
   if (mit_info == NULL)
   {
     int event_base, error_base;
@@ -3987,12 +3989,14 @@
     autoAwayTimer.stop();
     return;
   }
-  Time idleTime = mit_info->idle;
 
+  const unsigned long idleTime = mit_info->idle;
+  static std::map<unsigned long, SAutoAwayInfo> autoAwayInfo;
+
   // Go through each protocol, as the statuses may differ
   FOR_EACH_PROTO_PLUGIN_START(licqDaemon)
   {
-    unsigned long nPPID = (*_ppit)->PPID();
+    const unsigned long nPPID = (*_ppit)->PPID();
 
     // Fetch current status
     unsigned short status = ICQ_STATUS_OFFLINE;
@@ -4003,6 +4007,91 @@
       gUserManager.DropOwner(nPPID);
     }
 
+    SAutoAwayInfo& info = autoAwayInfo[nPPID];
+
+    // Check no one changed the status behind our back
+    if (info.isAutoAway && info.setAutoAwayStatus != status)
+    {
+      gLog.Warn("%sSomeone changed the status behind our back (%u != %u; PPID: 0x%lx).\n",
+                L_WARNxSTR, info.setAutoAwayStatus, status, nPPID);
+      info.isAutoAway = false;
+      continue;
+    }
+
+    // If we are offline, and it isn't auto offline, we shouldn't do anything
+    if (status == ICQ_STATUS_OFFLINE && !info.isAutoAway)
+      continue;
+
+    bool returnFromAutoAway = false;
+    unsigned short wantedStatus;
+    if (autoOfflineTime > 0 && idleTime > (unsigned long)(autoOfflineTime * 30000)) // FIXME 60 000
+      wantedStatus = ICQ_STATUS_OFFLINE;
+    else if (autoNATime > 0 && idleTime > (unsigned long)(autoNATime * 30000)) // FIXME
+      wantedStatus = ICQ_STATUS_NA;
+    else if (autoAwayTime > 0 && idleTime > (unsigned long)(autoAwayTime * 30000)) // FIXME
+      wantedStatus = ICQ_STATUS_AWAY;
+    else
+    {
+      // The user is active and we're not auto away
+      if (!info.isAutoAway)
+        continue;
+
+      returnFromAutoAway = true;
+      wantedStatus = info.preAutoAwayStatus;
+    }
+
+    // MSN does not support NA
+    if (nPPID == MSN_PPID && wantedStatus == ICQ_STATUS_NA)
+      wantedStatus = ICQ_STATUS_AWAY;
+
+    // Never change from NA to away unless we are returning from auto away
+    if (status == ICQ_STATUS_NA && wantedStatus == ICQ_STATUS_AWAY && !returnFromAutoAway)
+      continue;
+
+    if (status == wantedStatus)
+      continue;
+
+    // If we're not auto away, save current status
+    if (!info.isAutoAway)
+    {
+      info.isAutoAway = true;
+      info.preAutoAwayStatus = status;
+    }
+    else if (returnFromAutoAway)
+      info.isAutoAway = false;
+
+    // Set auto response
+    if (wantedStatus == ICQ_STATUS_NA && autoNAMess)
+    {
+      SARList &sar = gSARManager.Fetch(SAR_NA);
+      ICQOwner *o = gUserManager.FetchOwner(nPPID, LOCK_W);
+      if (o != NULL)
+      {
+        o->SetAutoResponse(QString(sar[autoNAMess-1]->AutoResponse()).local8Bit());
+        gUserManager.DropOwner(nPPID);
+      }
+      gSARManager.Drop();
+    }
+    else if (wantedStatus == ICQ_STATUS_AWAY && autoAwayMess)
+    {
+      SARList &sar = gSARManager.Fetch(SAR_AWAY);
+      ICQOwner *o = gUserManager.FetchOwner(nPPID, LOCK_W);
+      if (o != NULL)
+      {
+        o->SetAutoResponse(QString(sar[autoAwayMess-1]->AutoResponse()).local8Bit());
+        gUserManager.DropOwner(nPPID);
+      }
+      gSARManager.Drop();
+    }
+
+    gLog.Warn("%sChanging status to %u from %u (PPID 0x%lx).\n",
+              L_WARNxSTR, wantedStatus, status, nPPID);
+
+    // Change status
+    info.setAutoAwayStatus = wantedStatus;
+    changeStatus(wantedStatus, nPPID);
+
+#if 0
     // Since MSN doesn't support NA, we have to "fake" it.
     if (nPPID == MSN_PPID && bAutoNA && !bAutoOffline && status == ICQ_STATUS_AWAY)
       status = ICQ_STATUS_NA;
@@ -4114,13 +4203,9 @@
         bTempAutoAway = false;
       }
     }
+#endif
   }
   FOR_EACH_PROTO_PLUGIN_END
-  
-  bAutoOffline = bTempAutoOffline;
-  bAutoNA = bTempAutoNA;
-  bAutoAway = bTempAutoAway;
-
 #endif // USE_SCRNSAVER
 }
 

Attachment: pgpuKbdSaBABo.pgp
Description: PGP signature

Reply via email to