Index: kmess/contactlistviewitem.cpp
===================================================================
--- kmess/contactlistviewitem.cpp	(revisione 2200)
+++ kmess/contactlistviewitem.cpp	(copia locale)
@@ -31,7 +31,9 @@
 #include "kmessdebug.h"
 #include "currentaccount.h"
 #include "contact/contact.h"
+#include "contact/group.h"
 #include "emoticonmanager.h"
+#include "grouplistviewitem.h"
 
 #ifdef KMESSDEBUG_CONTACTLISTVIEWITEM
 #define KMESSDEBUG_CONTACTLISTVIEWITEM_GENERAL
@@ -385,36 +387,50 @@
 // Update the visibility of the contact
 void ContactListViewItem::slotUpdateVisiblity()
 {
-  // Visibility depends on whether or not allowed and removed contacts are shown.
+  // Visibility of a contact depends on the list grouping mode, and on the contact status.
+
   CurrentAccount *currentAccount = CurrentAccount::instance();
+  int groupMode = currentAccount->getContactsGroupMode();
+  GroupListViewItem *parent = static_cast<GroupListViewItem*>( QListViewItem::parent() );
 
-  if(QListViewItem::parent() == 0 && ! currentAccount->getShowContactsByGroup())
+  // Hide root items if contacts are grouped between online and offline; and when the contact without
+  // group is offline if contact sare divided in groups+offline contacts.
+  if( parent == 0 &&
+    ( groupMode == Account::BYSTATUS || (groupMode == Account::MIXED && contact_->isOffline() ) ) )
   {
-    // Hide root items if contacts are shown in online/offline groups.
-    setVisible(false);
+    setVisible( false );
+    return;
   }
-  else if(contact_->isOffline() && ! currentAccount->getShowOfflineContacts())
+
+  // Hide offline contacts in groups, when in mixed mode
+  if(    groupMode == Account::MIXED && contact_->isOffline()
+      && parent && ! parent->getGroup()->isSpecialGroup() )
   {
-    // Hide if online contacts are not shown
-    setVisible(false);
+    setVisible( false );
+    return;
   }
+
+  // Hide if offline contacts are not shown
+  if( contact_->isOffline() && ! currentAccount->getShowOfflineContacts() )
+  {
+    setVisible( false );
+    return;
+  }
+
+  if( contact_->isFriend() )
+  {
+    // Friends should always be visible
+    setVisible( true );
+  }
+  else if( contact_->isAllowed() )
+  {
+    // Whether or not allowed contacts are visible depends on the contact setting
+    setVisible( currentAccount->getShowAllowedContacts() );
+  }
   else
   {
-    if(contact_->isFriend())
-    {
-      // Friends should always be visible
-      setVisible(true);
-    }
-    else if(contact_->isAllowed())
-    {
-      // Whether or not allowed contacts are visible depends on the contact setting
-      setVisible( currentAccount->getShowAllowedContacts() );
-    }
-    else
-    {
-      // Whether or not removed contacts are visible depends on the contact setting
-      setVisible( currentAccount->getShowRemovedContacts() );
-    }
+    // Whether or not removed contacts are visible depends on the contact setting
+    setVisible( currentAccount->getShowRemovedContacts() );
   }
 }
 
Index: kmess/kmess.cpp
===================================================================
--- kmess/kmess.cpp	(revisione 2199)
+++ kmess/kmess.cpp	(copia locale)
@@ -631,20 +631,19 @@
 void KMess::changeViewMode(int mode)
 {
 #ifdef KMESSTEST
-  ASSERT( ( mode == 0 ) || ( mode == 1 ) );
+  ASSERT( ( mode >= 0 ) && ( mode <= 2 ) );
 #endif
-  if ( mode == 0 )
+
+  switch( currentAccount_->getContactsGroupMode() )
   {
-    CurrentAccount::instance()->setShowContactsByGroup( true );
+    case 0: CurrentAccount::instance()->setContactsGroupMode( Account::BYGROUP  ); break;
+    case 1: CurrentAccount::instance()->setContactsGroupMode( Account::MIXED    ); break;
+    case 2: CurrentAccount::instance()->setContactsGroupMode( Account::BYSTATUS ); break;
+
+    default:
+      kdDebug() << "KMess - changeViewMode() - WARNING - Invalid view mode = " << mode << endl;
+      break;
   }
-  else if ( mode == 1 )
-  {
-    CurrentAccount::instance()->setShowContactsByGroup( false );
-  }
-  else
-  {
-    kdDebug() << "KMess - changeViewMode() - WARNING - Invalid view mode = " << mode << endl;
-  }
 }
 
 
@@ -885,14 +884,15 @@
   showAllowedAction_->setChecked( currentAccount_->getShowAllowedContacts() );
   showOfflineAction_->setChecked( currentAccount_->getShowOfflineContacts() );
   showRemovedAction_->setChecked( currentAccount_->getShowRemovedContacts() );
-  if ( currentAccount_->getShowContactsByGroup() )
+
+  switch( currentAccount_->getContactsGroupMode() )
   {
-    viewMode_->setCurrentItem( 0 );
+    case Account::BYSTATUS:  viewMode_->setCurrentItem( 2 ); break;
+    case Account::MIXED:     viewMode_->setCurrentItem( 1 ); break;
+    case Account::BYGROUP:
+    default:                 viewMode_->setCurrentItem( 0 ); break;
   }
-  else
-  {
-    viewMode_->setCurrentItem( 1 );
-  }
+
   // Show the connected message
   statusMessage( i18n("Connected"), TYPE_MESSAGE );
 
Index: kmess/account.cpp
===================================================================
--- kmess/account.cpp	(revisione 2199)
+++ kmess/account.cpp	(copia locale)
@@ -65,7 +65,7 @@
    savedChatDirectoryStructure_( 0 ),
    shakeNudge_(true),
    showAllowedContacts_(false),
-   showContactsByGroup_(true),
+   contactsGroupMode_(BYGROUP),
    showEmail_(true),
    showMessageTime_(true),
    showNowListening_(false),
@@ -128,7 +128,7 @@
                                account->getFriendlyName(),
                                account->getPassword() );
   setShowAllowedContacts     ( account->getShowAllowedContacts() );
-  setShowContactsByGroup     ( account->getShowContactsByGroup() );
+  setContactsGroupMode       ( account->getContactsGroupMode()   );
   setShowOfflineContacts     ( account->getShowOfflineContacts() );
   setShowRemovedContacts     ( account->getShowRemovedContacts() );
   setEmoticonStyle           ( account->getEmoticonStyle()       );
@@ -189,7 +189,7 @@
   setShowAllowedContacts( account->getShowAllowedContacts() );
   setShowOfflineContacts( account->getShowOfflineContacts() );
   setShowRemovedContacts( account->getShowRemovedContacts() );
-  setShowContactsByGroup( account->getShowContactsByGroup() );
+  setContactsGroupMode  ( account->getContactsGroupMode()   );
   setAutoreplyMessage   ( account->getAutoreplyMessage()    );
   setEmailSupported     ( account->getEmailSupported()      );
   setGuestAccount       ( account->isGuestAccount()         );
@@ -488,10 +488,10 @@
 
 
 
-// Read whether contacts are shown by group or by online/offline.
-bool Account::getShowContactsByGroup() const
+// Get how the contacts are grouped together in the contact list.
+const int& Account::getContactsGroupMode() const
 {
-  return showContactsByGroup_;
+  return contactsGroupMode_;
 }
 
 
@@ -711,6 +711,7 @@
   contactFont_.setUnderline      ( config->readBoolEntry( "contactfontunderline",         false                           ) );
   contactFont_.setPointSize      ( config->readNumEntry ( "contactfontpointsize",         10                              ) );
   contactFontColor_              = config->readEntry    ( "contactfontcolor" ,            "#000000"                         );
+  contactsGroupMode_             = config->readNumEntry ( "contactsGroupMode",            0                                 );
   customImageIndex_              = config->readNumEntry ( "customimageindex",             0                                 );
   doNotifyContactsOnline_        = config->readBoolEntry( "doNotifyContactsOnline",       true                              );
   doNotifyContactsStatus_        = config->readBoolEntry( "doNotifyContactsStatus",       false                             );
@@ -738,7 +739,6 @@
   savedChatDirectoryStructure_   = config->readNumEntry ( "savedChatDirectoryStructure",  0                                 );
   shakeNudge_                    = config->readBoolEntry( "shakeNudge",                   true                              );
   showAllowedContacts_           = config->readBoolEntry( "showAllowed",                  false                             );
-  showContactsByGroup_           = config->readBoolEntry( "showByGroup",                  true                              );
   showEmail_                     = config->readBoolEntry( "showEmail",                    true                              );
   showImage_                     = config->readBoolEntry( "showImage",                    true                              );
   showMessageTime_               = config->readBoolEntry( "showMessageTime",              true                              );
@@ -858,7 +858,7 @@
     config->writeEntry( "savedChatDirectoryStructure",  savedChatDirectoryStructure_  );
     config->writeEntry( "shakeNudge",                   shakeNudge_                   );
     config->writeEntry( "showAllowed",                  showAllowedContacts_          );
-    config->writeEntry( "showByGroup",                  showContactsByGroup_          );
+    config->writeEntry( "contactsGroupMode",            contactsGroupMode_            );
     config->writeEntry( "showEmail",                    showEmail_                    );
     config->writeEntry( "showMessageTime",              showMessageTime_              );
     config->writeEntry( "showNowListening",             showNowListening_             );
@@ -1290,16 +1290,16 @@
 
 
 
-// Set whether contacts are shown by group or by online/offline.
-void Account::setShowContactsByGroup( bool showContactsByGroup )
+// Change how the contacts are grouped together in the contact list.
+void Account::setContactsGroupMode( int contactsGroupMode )
 {
-  if ( showContactsByGroup != showContactsByGroup_ )
+  if ( contactsGroupMode != contactsGroupMode_ )
   {
-    showContactsByGroup_ = showContactsByGroup;
+    contactsGroupMode_ = contactsGroupMode;
     emit changedViewMode();
     dirty_ = true;
 #ifdef KMESSDEBUG_ACCOUNT_DIRTY
-    kdDebug() << "Account::setShowContactsByGroup(): Setting 'dirty' to true." << endl;
+    kdDebug() << "Account::setContactsGroupMode(): Setting 'dirty' to true." << endl;
 #endif
   }
 }
Index: kmess/account.h
===================================================================
--- kmess/account.h	(revisione 2199)
+++ kmess/account.h	(copia locale)
@@ -52,6 +52,12 @@
                                 , BYDAY           = 3
                                 };
 
+    // Groups organization
+    enum ListGroupMode { BYGROUP  = 0 // Group all contacts by their group
+                       , MIXED    = 1 // As BYGROUP but all offline contacts group together
+                       , BYSTATUS = 2 // Group contacts by status, online and offline
+                       };
+
     // The constructor
     Account();
     // The destructor
@@ -70,6 +76,8 @@
     const QFont&                 getContactFont() const;
     // Return the color of the forced contact font.
     const QString&               getContactFontColor() const;
+    // Get how the contacts are grouped together in the contact list.
+    const int&                   getContactsGroupMode() const;
     // Read the email command used when not using hotmail
     const QString&               getEmailCommand() const;
     // Return whether email notifications are supported
@@ -114,8 +122,6 @@
     const int&                   getSavedChatDirectoryStructure() const;
     // Read whether or not allowed contacts are shown.
     bool                         getShowAllowedContacts() const;
-    // Read whether contacts are shown by group or by online/offline.
-    bool                         getShowContactsByGroup() const;
     // Read whether the email information should be shown in the main view.
     bool                         getShowEmail() const;
     // Read the selected emoticon's list number
@@ -180,6 +186,8 @@
     void                         setChatInformation( bool useContactFont, bool useEmoticons, bool useFontEffects, bool showMessageTime, bool groupFollowupMessages, const QString& chatStyle );
     // Set chat logging information
     void                         setChatLoggingInformation( bool saveChats, const QString& saveChatPath, const int& directoryStructure );
+    // Change how the contacts are grouped together in the contact list.
+    void                         setContactsGroupMode( int groupMode );
     // Set email information
     void                         setEmailInformation( bool useHotmail, const QString&  emailCommand, bool showEmail, bool showOtherFolders );
     // Set the font
@@ -218,8 +226,6 @@
     void                         setNotifyEmails( bool doNotifyEmails );
     // Set whether or not allowed contacts are shown.
     void                         setShowAllowedContacts( bool showAllowedContacts );
-    // Set whether contacts are shown by group or by online/offline.
-    void                         setShowContactsByGroup( bool showContactsByGroup );
     // Set whether offline contacts should be shown.
     void                         setShowOfflineContacts( bool showOfflineContacts );
     // Set whether or not removed (reverse) contacts are shown.
@@ -307,8 +313,8 @@
     bool                         shakeNudge_;
     // Whether or not allowed contacts should be visible.
     bool                         showAllowedContacts_;
-    // Whether contacts should be shown by group (true) or by online/offline status (false).
-    bool                         showContactsByGroup_;
+    // How contacts should be grouped together in the list.
+    int                          contactsGroupMode_;
     // Whether or not to show any email notifications (the user may not
     //  have a hotmail account).
     bool                         showEmail_;
Index: kmess/kmessinterface.cpp
===================================================================
--- kmess/kmessinterface.cpp	(revisione 2199)
+++ kmess/kmessinterface.cpp	(copia locale)
@@ -278,8 +278,9 @@
 #endif
 
   viewMode_ = new KSelectAction( i18n("&Sort Contacts by"), "view_tree", 0, this, "viewmode");
-  viewModes << i18n("Group") << i18n("Online/Offline");
+  viewModes << i18n("Group") << i18n("Groups/Offline") << i18n("Online/Offline");
   viewMode_->setItems(viewModes);
+
   connect ( viewMode_, SIGNAL( activated( int ) ), this, SLOT( changeViewMode( int ) ) );
 
   showTransferAction_ = new KAction(i18n("Show &Transfer Window"), "cache", 0,
Index: kmess/kmessview.cpp
===================================================================
--- kmess/kmessview.cpp	(revisione 2199)
+++ kmess/kmessview.cpp	(copia locale)
@@ -1363,6 +1363,7 @@
 
   GroupListViewItem *item;
   item = new GroupListViewItem(contactListView_, group);
+  int groupMode = currentAccount_->getContactsGroupMode();
 
   if(! group->isSpecialGroup() || group->getId() == SpecialGroups::INDIVIDUALS)
   {
@@ -1370,7 +1371,7 @@
     connect(item, SIGNAL(moveToGroup(Group*)), this, SLOT(slotForwardMoveContact(Group*)));
     connect(item, SIGNAL(copyToGroup(Group*)), this, SLOT(slotForwardCopyContact(Group*)));
     // Hide normal group if user likes to sort contacts by online/offline state
-    item->setVisible( currentAccount_->getShowContactsByGroup() );
+    item->setVisible( groupMode != Account::BYSTATUS );
   }
   else
   {
@@ -1385,12 +1386,11 @@
     }
     else if(group->getId() == SpecialGroups::ONLINE)
     {
-      item->setVisible( ! currentAccount_->getShowContactsByGroup() );
+      item->setVisible( groupMode == Account::BYSTATUS );
     }
     else if(group->getId() == SpecialGroups::OFFLINE)
     {
-      item->setVisible( ! currentAccount_->getShowContactsByGroup() &&
-                          currentAccount_->getShowOfflineContacts() );
+      item->setVisible( groupMode == Account::BYSTATUS && currentAccount_->getShowOfflineContacts() );
     }
   }
 }
@@ -1619,16 +1619,17 @@
   // Read the settings
   bool showAllowed = currentAccount_->getShowAllowedContacts();
   bool showRemoved = currentAccount_->getShowRemovedContacts();
-  bool showByGroup = currentAccount_->getShowContactsByGroup();
   bool showOffline = currentAccount_->getShowOfflineContacts();
+  int  groupMode   = currentAccount_->getContactsGroupMode();
 
+kdDebug() << "TEST - Group mode: " << groupMode << endl;
   QString            groupId;
   GroupListViewItem *groupItem = findFirstGroup();
-
   while(groupItem != 0)
   {
     groupId = groupItem->getGroup()->getId();
 
+kdDebug() << "TEST - name: " << groupItem->getGroup()->getName() << " - special: " << groupItem->getGroup()->isSpecialGroup() << endl;
     // Hide or show the special groups
     if(groupId == SpecialGroups::ALLOWED)
     {
@@ -1640,11 +1641,12 @@
     }
     else if(groupId == SpecialGroups::ONLINE)
     {
-      groupItem->setVisible( ! showByGroup );
+      groupItem->setVisible( groupMode == Account::BYSTATUS );
     }
     else if(groupId == SpecialGroups::OFFLINE)
     {
-      groupItem->setVisible( ! showByGroup && showOffline );
+      // Show both in groups+offline and online+offline display modes
+      groupItem->setVisible( groupMode != Account::BYGROUP && showOffline );
     }
     else
     {
@@ -1652,8 +1654,12 @@
       // This feature is used from slotUpdateViewMode()
       if(! groupItem->getGroup()->isSpecialGroup())
       {
-        groupItem->setVisible( showByGroup );
+        groupItem->setVisible( groupMode != Account::BYSTATUS );
       }
+      else
+      {
+        groupItem->setVisible( true );
+      }
     }
 
     groupItem = findNextGroup(groupItem);
