You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
konversation/konversation/src/serverison.cpp

243 lines
9.4 KiB

/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
*/
/*
serverison.h - Class to give a list of all the nicks known to the
addressbook and watchednick list that are on this
server. There is one instance of this class for
each Server object.
begin: Fri Sep 03 2004
copyright: (C) 2004 by John Tapsell
email: john@geola.co.uk
*/
#include "serverison.h"
#include "server.h"
#include "addressbook.h"
#include "konversationapplication.h"
#include "nickinfo.h"
#include "viewcontainer.h"
#include <tqmap.h>
#include <tqstring.h>
#include <tqstringlist.h>
#include <tdeabc/addressbook.h>
#include <tdeabc/stdaddressbook.h>
ServerISON::ServerISON(Server* server) : m_server(server)
{
m_ISONList_invalid = true;
//We need to know when the addressbook changes because if the info for an offline nick changes,
//we won't get a nickInfoChanged signal.
connect( Konversation::Addressbook::self()->getAddressBook(), TQT_SIGNAL( addressBookChanged( AddressBook * ) ),
this, TQT_SLOT( addressbookChanged() ) );
connect( Konversation::Addressbook::self(), TQT_SIGNAL(addresseesChanged()),
this, TQT_SLOT(addressbookChanged()));
connect( m_server, TQT_SIGNAL(nickInfoChanged(Server*, const NickInfoPtr)),
this, TQT_SLOT(nickInfoChanged(Server*, const NickInfoPtr)));
connect( m_server,
TQT_SIGNAL(channelMembersChanged(Server*, const TQString&, bool, bool, const TQString& )),
this,
TQT_SLOT(slotChannelMembersChanged(Server*, const TQString&, bool, bool, const TQString& )));
connect( m_server,
TQT_SIGNAL(channelJoinedOrUnjoined(Server*, const TQString&, bool )),
this,
TQT_SLOT(slotChannelJoinedOrUnjoined(Server*, const TQString&, bool )));
connect(KonversationApplication::instance(), TQT_SIGNAL(serverGroupsChanged(const Konversation::ServerGroupSettings*)),
this, TQT_SLOT(slotServerGroupsChanged()));
}
TQStringList ServerISON::getWatchList()
{
if(m_ISONList_invalid)
recalculateAddressees();
return m_watchList;
}
TQStringList ServerISON::getISONList()
{
if(m_ISONList_invalid)
recalculateAddressees();
return m_ISONList;
}
TQStringList ServerISON::getAddressees()
{
if(m_ISONList_invalid)
recalculateAddressees();
return m_addresseesISON;
}
KABC::Addressee ServerISON::getOfflineNickAddressee(TQString& nickname)
{
TQString lcNickname = nickname.lower();
if(m_ISONList_invalid)
recalculateAddressees();
if (m_offlineNickToAddresseeMap.contains(lcNickname))
return m_offlineNickToAddresseeMap[lcNickname];
else
return KABC::Addressee();
}
void ServerISON::recalculateAddressees()
{
// If not watching nicks, no need to build notify list.
if (Preferences::useNotify())
{
// Get all nicks known to be online.
const NickInfoMap* allNicks = m_server->getAllNicks();
// Build a map of online nicknames with associated addressbook entry,
// indexed by KABC::Addressee uid.
// Note that there can be more than one nick associated with an addressee.
TQMap<TQString,TQStringList> addresseeToOnlineNickMap;
NickInfoMap::ConstIterator nickInfoItEnd = allNicks->constEnd();
for(NickInfoMap::ConstIterator nickInfoIt=allNicks->constBegin();
nickInfoIt != nickInfoItEnd; ++nickInfoIt)
{
NickInfoPtr nickInfo = nickInfoIt.data();
KABC::Addressee addressee = nickInfo->getAddressee();
if (!addressee.isEmpty())
{
TQString uid = addressee.uid();
TQStringList nicknames = addresseeToOnlineNickMap[uid];
nicknames.append(nickInfo->getNickname());
addresseeToOnlineNickMap[uid] = nicknames;
}
}
// Lowercase server name and server group.
TQString lserverName = m_server->getServerName().lower();
TQString lserverGroup = m_server->getDisplayName().lower();
// Build notify list from nicks in addressbook, eliminating dups (case insensitive).
TQMap<TQString,TQString> ISONMap;
m_offlineNickToAddresseeMap.clear();
for( KABC::AddressBook::ConstIterator it =
Konversation::Addressbook::self()->getAddressBook()->begin();
it != Konversation::Addressbook::self()->getAddressBook()->end(); ++it )
{
if(Konversation::Addressbook::self()->hasAnyNicks(*it))
{
TQString uid = (*it).uid();
// First check if we already know that this addressee is online.
// If so, add all the nicks of the addressee that are online, but do not
// add the offline nicks. There is no point in monitoring such nicks.
if (addresseeToOnlineNickMap.contains(uid))
{
TQStringList nicknames = addresseeToOnlineNickMap[uid];
TQStringList::iterator itEnd = nicknames.end();
for(TQStringList::iterator it = nicknames.begin(); it != itEnd; ++it)
{
ISONMap.insert((*it).lower(), (*it), true);
}
}
else
{
// If addressee is not known to be online, add all of the nicknames
// of the addressee associated with this server or server group (if any)
// to the notify list.
// Simultaneously, build a map of all offline nicks and corresponding
// KABC::Addressee, indexed by lowercase nickname.
TQStringList nicks = TQStringList::split( TQChar( 0xE000 ),
(*it).custom("messaging/irc", "All") );
TQStringList::ConstIterator nicksItEnd = nicks.constEnd();
for( TQStringList::ConstIterator nicksIt = nicks.constBegin();
nicksIt != nicksItEnd; ++nicksIt )
{
TQString lserverOrGroup = (*nicksIt).section(TQChar(0xE120),1).lower();
if(lserverOrGroup == lserverName || lserverOrGroup == lserverGroup ||
lserverOrGroup.isEmpty())
{
TQString nickname = (*nicksIt).section(TQChar(0xE120),0,0);
TQString lcNickname = nickname.lower();
ISONMap.insert(lcNickname, nickname, true);
m_offlineNickToAddresseeMap.insert(lcNickname, *it, true);
}
}
}
}
}
// The part of the ISON list due to the addressbook.
m_addresseesISON = ISONMap.values();
// Merge with watch list from prefs, eliminating dups (case insensitive).
// TODO: Don't add nick on user watch list if nick is known to be online
// under a different nickname?
TQStringList prefsWatchList =
Preferences::notifyListByGroupName(m_server->getDisplayName());
TQStringList::iterator itEnd = prefsWatchList.end();
for(TQStringList::iterator it = prefsWatchList.begin(); it != itEnd; ++it)
{
ISONMap.insert((*it).lower(), (*it), true);
}
// Build final watch list.
m_watchList = ISONMap.values();
// Eliminate nicks that are online in a joined channel, since there is no point
// in doing an ISON on such nicks.
m_ISONList.clear();
itEnd = m_watchList.end();
for(TQStringList::iterator it = m_watchList.begin(); it != itEnd; ++it)
{
if (m_server->getNickJoinedChannels(*it).isEmpty())
{
m_ISONList.append(*it);
}
}
}
else
{
m_addresseesISON.clear();
m_ISONList.clear();
}
m_ISONList_invalid = false;
}
// When user changes preferences and has nick watching turned on, rebuild notify list.
void ServerISON::slotServerGroupsChanged()
{
kdDebug() << "ServerISON::slotServerGroupsChanged" << endl;
m_ISONList_invalid = true;
}
void ServerISON::nickInfoChanged(Server* /*server*/, const NickInfoPtr /*nickInfo*/) {
//We need to call recalculateAddressees before returning m_ISONList
//Maybe we could do something like:
//if(m_ISONList.contains(nickInfo->getNickName())) return;
m_ISONList_invalid = true;
}
void ServerISON::addressbookChanged()
{
//We need to call recalculateAddressees before returning m_ISONList
m_ISONList_invalid = true;
}
void ServerISON::slotChannelMembersChanged(Server* /*server*/, const TQString& /*channelName*/,
bool joined, bool parted, const TQString& nickname)
{
// Whenever a nick on the watch list leaves the last joined channel, must recalculate lists.
// The nick will be added to the ISON list.
if (joined && parted && m_watchList.contains(nickname))
if (m_server->getNickJoinedChannels(nickname).isEmpty()) m_ISONList_invalid = true;
}
void ServerISON::slotChannelJoinedOrUnjoined(Server* /*server*/,
const TQString& /*channelName*/, bool /*joined*/)
{
// If user left or joined a channel, need to recalculate lists, since watched nicks
// may need to be moved from/to ISON list.
m_ISONList_invalid = true;
}
#include "serverison.moc"