/* 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 #include #include #include #include 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; } TDEABC::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 TDEABC::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 TDEABC::Addressee uid. // Note that there can be more than one nick associated with an addressee. TQMap addresseeToOnlineNickMap; NickInfoMap::ConstIterator nickInfoItEnd = allNicks->constEnd(); for(NickInfoMap::ConstIterator nickInfoIt=allNicks->constBegin(); nickInfoIt != nickInfoItEnd; ++nickInfoIt) { NickInfoPtr nickInfo = nickInfoIt.data(); TDEABC::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 ISONMap; m_offlineNickToAddresseeMap.clear(); for( TDEABC::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 // TDEABC::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"