summaryrefslogtreecommitdiffstats
path: root/konversation/src/nicksonline.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'konversation/src/nicksonline.cpp')
-rw-r--r--konversation/src/nicksonline.cpp975
1 files changed, 975 insertions, 0 deletions
diff --git a/konversation/src/nicksonline.cpp b/konversation/src/nicksonline.cpp
new file mode 100644
index 0000000..85361ff
--- /dev/null
+++ b/konversation/src/nicksonline.cpp
@@ -0,0 +1,975 @@
+// -*- mode: c++; c-file-style: "bsd"; c-basic-offset: 4; tabs-width: 4; indent-tabs-mode: nil -*-
+
+/*
+ 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.
+*/
+
+/*
+ shows a user tree of friends per server
+ begin: Sam Aug 31 2002
+ copyright: (C) 2002 by Dario Abatianni
+ email: eisfuchs@tigress.com
+*/
+
+#include "nicksonline.h"
+#include "channel.h"
+#include "server.h"
+#include "konversationapplication.h"
+#include "connectionmanager.h"
+#include "images.h"
+#include "query.h"
+#include "linkaddressbook/linkaddressbookui.h"
+#include "linkaddressbook/addressbook.h"
+#include "linkaddressbook/nicksonlinetooltip.h"
+#include "konversationmainwindow.h"
+#include "viewcontainer.h"
+#include "nicksonlineitem.h"
+
+#include <qlayout.h>
+#include <qstringlist.h>
+#include <qhbox.h>
+#include <qpushbutton.h>
+#include <qlabel.h>
+#include <qpopupmenu.h>
+#include <qptrlist.h>
+#include <qwhatsthis.h>
+
+
+#include <kdebug.h>
+#include <klocale.h>
+#include <kdialog.h>
+#include <klistview.h>
+#include <kiconloader.h>
+#include <kprocess.h>
+#include <kmessagebox.h>
+
+
+NicksOnline::NicksOnline(QWidget* parent): ChatWindow(parent)
+{
+ setName(i18n("Watched Nicks Online"));
+ setType(ChatWindow::NicksOnline);
+
+ m_nickListView=new KListView(this);
+
+ // Set to false every 8 seconds to permit a whois on watched nicks lacking information.
+ // Remove when server or addressbook does this automatically.
+ m_whoisRequested = true;
+
+ m_nickListView->addColumn(i18n("Network/Nickname/Channel"));
+ m_kabcIconSet = KGlobal::iconLoader()->loadIconSet("kaddressbook",KIcon::Small);
+ m_nickListView->addColumn(i18n("Additional Information"));
+ m_nickListView->setFullWidth(true);
+ m_nickListView->setRootIsDecorated(true);
+ m_nickListView->setShowToolTips(false);
+ m_nickListView->setShadeSortColumn(true);
+ m_nickListView->setShowSortIndicator(true);
+
+ QString nickListViewWT = i18n(
+ "<p>These are all the nicknames on your Nickname Watch list, listed under the "
+ "server network they are connected to. The list also includes the nicknames "
+ "in KAddressBook associated with the server network.</p>"
+ "<p>The <b>Additional Information</b> column shows the information known "
+ "for each nickname.</p>"
+ "<p>The channels the nickname has joined are listed underneath each nickname.</p>"
+ "<p>Nicknames appearing under <b>Offline</b> are not connected to any of the "
+ "servers in the network.</p>"
+ "<p>Right-click with the mouse on a nickname to perform additional functions.</p>");
+ QWhatsThis::add(m_nickListView, nickListViewWT);
+
+ m_tooltip = new Konversation::KonversationNicksOnlineToolTip(m_nickListView->viewport(), this);
+
+ setMargin(margin());
+ setSpacing(spacing());
+
+ QHBox* buttonBox=new QHBox(this);
+ buttonBox->setSpacing(spacing());
+ QPushButton* editButton=new QPushButton(i18n("&Edit Watch List..."),
+ buttonBox,"edit_notify_button");
+ QString editButtonWT = i18n(
+ "Click to edit the list of nicknames that appear on this screen.");
+ QWhatsThis::add(editButton, editButtonWT);
+
+ connect(editButton, SIGNAL(clicked()), SIGNAL(editClicked()) );
+ connect(m_nickListView, SIGNAL(doubleClicked(QListViewItem*)),
+ this,SLOT(processDoubleClick(QListViewItem*)));
+
+ QLabel* addressbookLabel = new QLabel(i18n("Address book:"),
+ buttonBox, "nicksonline_addressbook_label");
+ QString addressbookLabelWT = i18n(
+ "When you select a nickname in the list above, the buttons here are used "
+ "to associate the nickname with an entry in KAddressBook.");
+ QWhatsThis::add(addressbookLabel, addressbookLabelWT);
+ addressbookLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+ m_editContactButton = new QPushButton(i18n("Edit C&ontact..."),
+ buttonBox, "nicksonline_editcontact_button");
+ QString editContactButtonWT = i18n(
+ "Click to create, view, or edit the KAddressBook entry associated with the nickname "
+ "selected above.");
+ QWhatsThis::add(m_editContactButton, editContactButtonWT);
+ m_editContactButton->setIconSet(m_kabcIconSet);
+ m_changeAssociationButton = new QPushButton(i18n("&Change Association..."),
+ buttonBox, "nicksonline_changeassociation_button");
+ QString changeAssociationButtonWT = i18n(
+ "Click to associate the nickname selected above with an entry in KAddressBook.");
+ QWhatsThis::add(m_changeAssociationButton, changeAssociationButtonWT);
+ m_changeAssociationButton->setIconSet(m_kabcIconSet);
+ m_deleteAssociationButton = new QPushButton(i18n("&Delete Association"),
+ buttonBox, "nicksonline_deleteassociation_button");
+ QString deleteAssociationButtonWT = i18n(
+ "Click to remove the association between the nickname selected above and a "
+ "KAddressBook entry.");
+ QWhatsThis::add(m_deleteAssociationButton, deleteAssociationButtonWT);
+ m_deleteAssociationButton->setIconSet(m_kabcIconSet);
+
+ connect(m_editContactButton, SIGNAL(clicked()),
+ this, SLOT(slotEditContactButton_Clicked()));
+ connect(m_changeAssociationButton, SIGNAL(clicked()),
+ this, SLOT(slotChangeAssociationButton_Clicked()));
+ connect(m_deleteAssociationButton, SIGNAL(clicked()),
+ this, SLOT(slotDeleteAssociationButton_Clicked()));
+ connect(m_nickListView, SIGNAL(selectionChanged()),
+ this, SLOT(slotNickListView_SelectionChanged()));
+
+ setupAddressbookButtons(nsNotANick);
+
+ // Create context menu. Individual menu entries are created in rightButtonClicked slot.
+ m_popupMenu = new QPopupMenu(this,"nicksonline_context_menu");
+ connect(m_nickListView, SIGNAL(rightButtonClicked(QListViewItem *, const QPoint &, int )),
+ this, SLOT(slotNickListView_RightButtonClicked(QListViewItem*, const QPoint &)));
+ connect(m_popupMenu, SIGNAL(activated(int)),
+ this, SLOT(slotPopupMenu_Activated(int)));
+
+ // Display info for all currently-connected servers.
+ refreshAllServerOnlineLists();
+
+ // Connect and start refresh timer.
+ m_timer = new QTimer(this, "nicksOnlineTimer");
+ connect(m_timer, SIGNAL (timeout()), this, SLOT(timerFired()));
+ // TODO: User preference for refresh interval.
+ m_timer->start(8000);
+}
+
+NicksOnline::~NicksOnline()
+{
+ m_timer->stop();
+ delete m_timer;
+ delete m_nickListView;
+}
+
+KListView* NicksOnline::getNickListView()
+{
+ return m_nickListView;
+}
+
+/**
+ * Returns the named child of parent item in a NicksOnlineItem
+ * @param parent Pointer to a NicksOnlineItem.
+ * @param name The name in the desired child QListViewItem, must be in column 0.
+ * @param type The type of entry to be found
+ * @return Pointer to the child QListViewItem or 0 if not found.
+ */
+QListViewItem* NicksOnline::findItemChild(const QListViewItem* parent, const QString& name, NicksOnlineItem::NickListViewColumn type)
+{
+ if (!parent) return 0;
+ QListViewItem* child;
+ for (child = parent->firstChild(); (child) ; child = child->nextSibling())
+ {
+ if(static_cast<NicksOnlineItem*>(child)->type() == type && child->text(0) == name) return child;
+ }
+ return 0;
+}
+
+/**
+ * Returns the first occurrence of a child item of a given type in a NicksOnlineItem
+ * @param parent Pointer to a NicksOnlineItem.
+ * @param type The type of entry to be found
+ * @return Pointer to the child QListViewItem or 0 if not found.
+ */
+QListViewItem* NicksOnline::findItemType(const QListViewItem* parent, NicksOnlineItem::NickListViewColumn type)
+{
+ if (!parent) return 0;
+ QListViewItem* child;
+ for (child = parent->firstChild(); (child) ; child = child->nextSibling())
+ {
+ if(static_cast<NicksOnlineItem*>(child)->type() == type) return child;
+ }
+ return 0;
+}
+
+/**
+ * Returns a pointer to the network QListViewItem with the given name.
+ * @param name The name of the network, assumed to be in column 0 of the item.
+ * @return Pointer to the QListViewItem or 0 if not found.
+ */
+QListViewItem* NicksOnline::findNetworkRoot(const QString& name)
+{
+ QListViewItem* child;
+ for (child = getNickListView()->firstChild(); (child) ; child = child->nextSibling())
+ {
+ if (child->text(0) == name) return child;
+ }
+ return 0;
+}
+
+/**
+ * Return a string containing formatted additional information about a nick.
+ * @param nickInfo A pointer to NickInfo structure for the nick. May be Null.
+ * @param addressee Addressbook entry for the nick. May be empty.
+ * @return A string formatted for display containing the information
+ * about the nick.
+ * @return needWhois True if a WHOIS needs to be performed on the nick
+ * to get additional information.
+ */
+QString NicksOnline::getNickAdditionalInfo(NickInfoPtr nickInfo, KABC::Addressee addressee,
+bool& needWhois)
+{
+ QString info;
+ if (!addressee.isEmpty())
+ {
+ if (addressee.fullEmail().isEmpty())
+ info += addressee.realName();
+ else
+ info += addressee.fullEmail();
+ }
+ QString niInfo;
+ if (nickInfo)
+ {
+ if (nickInfo->isAway())
+ {
+ niInfo += i18n("Away");
+ if (!nickInfo->getAwayMessage().isEmpty())
+ niInfo += '(' + nickInfo->getAwayMessage() + ')';
+ }
+ if (!nickInfo->getHostmask().isEmpty())
+ niInfo += ' ' + nickInfo->getHostmask();
+ if (!nickInfo->getRealName().isEmpty())
+ niInfo += " (" + nickInfo->getRealName() + ')';
+ if (!nickInfo->getNetServer().isEmpty())
+ {
+ niInfo += i18n( " online via %1" ).arg( nickInfo->getNetServer() );
+ if (!nickInfo->getNetServerInfo().isEmpty())
+ niInfo += " (" + nickInfo->getNetServerInfo() + ')';
+ }
+ if (!nickInfo->getOnlineSince().isNull())
+ niInfo += i18n( " since %1" ).arg( nickInfo->getPrettyOnlineSince() );
+ }
+ needWhois = niInfo.isEmpty();
+ if (!info.isEmpty() && !needWhois) info += ' ';
+ return info + niInfo;
+}
+
+/**
+ * Refresh the nicklistview for a single server.
+ * @param server The server to be refreshed.
+ */
+void NicksOnline::updateServerOnlineList(Server* servr)
+{
+ bool newNetworkRoot = false;
+ QString serverName = servr->getServerName();
+ QString networkName = servr->getDisplayName();
+ QListViewItem* networkRoot = findNetworkRoot(networkName);
+ // If network is not in our list, add it.
+ if (!networkRoot)
+ {
+ networkRoot = new NicksOnlineItem(NicksOnlineItem::NetworkRootItem,m_nickListView,networkName);
+ newNetworkRoot = true;
+ }
+ // Store server name in hidden column.
+ // Note that there could be more than one server in the network connected,
+ // but it doesn't matter because all the servers in a network have the same
+ // watch list.
+ networkRoot->setText(nlvcServerName, serverName);
+ // Update list of servers in the network that are connected.
+ QStringList serverList = QStringList::split(",", networkRoot->text(nlvcAdditionalInfo));
+ if (!serverList.contains(serverName)) serverList.append(serverName);
+ networkRoot->setText(nlvcAdditionalInfo, serverList.join(","));
+ // Get item in nicklistview for the Offline branch.
+ QListViewItem* offlineRoot = findItemType(networkRoot, NicksOnlineItem::OfflineItem);
+ if (!offlineRoot)
+ {
+ offlineRoot = new NicksOnlineItem(NicksOnlineItem::OfflineItem,networkRoot,i18n("Offline"));
+ offlineRoot->setText(nlvcServerName, serverName);
+ }
+
+ // Get watch list.
+ QStringList watchList = servr->getWatchList();
+ QStringList::iterator itEnd = watchList.end();
+ QString nickname;
+
+ for (QStringList::iterator it = watchList.begin(); it != itEnd; ++it)
+ {
+ nickname = (*it);
+ NickInfoPtr nickInfo = getOnlineNickInfo(networkName, nickname);
+
+ if (nickInfo && nickInfo->getPrintedOnline())
+ {
+ // Nick is online.
+ // Which server did NickInfo come from?
+ Server* server=nickInfo->getServer();
+ // Get addressbook entry (if any) for the nick.
+ KABC::Addressee addressee = nickInfo->getAddressee();
+ // Construct additional information string for nick.
+ bool needWhois = false;
+ QString nickAdditionalInfo = getNickAdditionalInfo(nickInfo, addressee, needWhois);
+ // Remove from offline branch if present.
+ QListViewItem* item = findItemChild(offlineRoot, nickname, NicksOnlineItem::NicknameItem);
+ if (item) delete item;
+ // Add to network if not already added.
+ QListViewItem* nickRoot = findItemChild(networkRoot, nickname, NicksOnlineItem::NicknameItem);
+ if (!nickRoot) nickRoot = new NicksOnlineItem(NicksOnlineItem::NicknameItem,networkRoot, nickname, nickAdditionalInfo);
+ nickRoot->setText(nlvcAdditionalInfo, nickAdditionalInfo);
+ nickRoot->setText(nlvcServerName, serverName);
+ // If no additional info available, request a WHOIS on the nick.
+ if (!m_whoisRequested)
+ {
+ if (needWhois)
+ {
+ requestWhois(networkName, nickname);
+ m_whoisRequested = true;
+ }
+ }
+ // Set Kabc icon if the nick is associated with an addressbook entry.
+ if (!addressee.isEmpty())
+ nickRoot->setPixmap(nlvcKabc, m_kabcIconSet.pixmap(
+ QIconSet::Small, QIconSet::Normal, QIconSet::On));
+ else
+ nickRoot->setPixmap(nlvcKabc, m_kabcIconSet.pixmap(
+ QIconSet::Small, QIconSet::Disabled, QIconSet::Off));
+
+ QStringList channelList = server->getNickChannels(nickname);
+ QStringList::iterator itEnd2 = channelList.end();
+
+ for (QStringList::iterator it2 = channelList.begin(); it2 != itEnd2; ++it2)
+ {
+ // Known channels where nickname is online and mode in each channel.
+ // FIXME: If user connects to multiple servers in same network, the
+ // channel info will differ between the servers, resulting in inaccurate
+ // mode and led info displayed.
+
+ QString channelName = (*it2);
+
+ ChannelNickPtr channelNick = server->getChannelNick(channelName, nickname);
+ QString nickMode;
+ if (channelNick->hasVoice()) nickMode = nickMode + i18n(" Voice");
+ if (channelNick->isHalfOp()) nickMode = nickMode + i18n(" HalfOp");
+ if (channelNick->isOp()) nickMode = nickMode + i18n(" Operator");
+ if (channelNick->isOwner()) nickMode = nickMode + i18n(" Owner");
+ if (channelNick->isAdmin()) nickMode = nickMode + i18n(" Admin");
+ QListViewItem* channelItem = findItemChild(nickRoot, channelName, NicksOnlineItem::ChannelItem);
+ if (!channelItem) channelItem = new NicksOnlineItem(NicksOnlineItem::ChannelItem,nickRoot,
+ channelName, nickMode);
+ channelItem->setText(nlvcAdditionalInfo, nickMode);
+
+ // Icon for mode of nick in each channel.
+ Images::NickPrivilege nickPrivilege = Images::Normal;
+ if (channelNick->hasVoice()) nickPrivilege = Images::Voice;
+ if (channelNick->isHalfOp()) nickPrivilege = Images::HalfOp;
+ if (channelNick->isOp()) nickPrivilege = Images::Op;
+ if (channelNick->isOwner()) nickPrivilege = Images::Owner;
+ if (channelNick->isAdmin()) nickPrivilege = Images::Admin;
+ if (server->getJoinedChannelMembers(channelName) != 0)
+ channelItem->setPixmap(nlvcChannel,
+ KonversationApplication::instance()->images()->getNickIcon(nickPrivilege, false));
+ else
+ channelItem->setPixmap(nlvcChannel,
+ KonversationApplication::instance()->images()->getNickIcon(nickPrivilege, true));
+ }
+ // Remove channel if nick no longer in it.
+ QListViewItem* child = nickRoot->firstChild();
+ while (child)
+ {
+ QListViewItem* nextChild = child->nextSibling();
+ if (channelList.find(child->text(nlvcNick)) == channelList.end())
+ delete child;
+ child = nextChild;
+ }
+ }
+ else
+ {
+ // Nick is offline.
+ // Remove from online nicks, if present.
+ QListViewItem* item = findItemChild(networkRoot, nickname, NicksOnlineItem::NicknameItem);
+ if (item) delete item;
+ // Add to offline list if not already listed.
+ QListViewItem* nickRoot = findItemChild(offlineRoot, nickname, NicksOnlineItem::NicknameItem);
+ if (!nickRoot) nickRoot = new NicksOnlineItem(NicksOnlineItem::NicknameItem,offlineRoot, nickname);
+ nickRoot->setText(nlvcServerName, serverName);
+ // Get addressbook entry for the nick.
+ KABC::Addressee addressee = servr->getOfflineNickAddressee(nickname);
+ // Format additional information for the nick.
+ bool needWhois = false;
+ QString nickAdditionalInfo = getNickAdditionalInfo(0, addressee, needWhois);
+ nickRoot->setText(nlvcAdditionalInfo, nickAdditionalInfo);
+ // Set Kabc icon if the nick is associated with an addressbook entry.
+ if (!addressee.isEmpty())
+ nickRoot->setPixmap(nlvcKabc, m_kabcIconSet.pixmap(
+ QIconSet::Small, QIconSet::Normal, QIconSet::On));
+ else
+ nickRoot->setPixmap(nlvcKabc, m_kabcIconSet.pixmap(
+ QIconSet::Small, QIconSet::Disabled, QIconSet::Off));
+ }
+ }
+ // Erase nicks no longer being watched.
+ QListViewItem* item = networkRoot->firstChild();
+ while (item)
+ {
+ QListViewItem* nextItem = item->nextSibling();
+ if (static_cast<NicksOnlineItem*>(item)->type() != NicksOnlineItem::OfflineItem)
+ {
+ QString nickname = item->text(nlvcNick);
+ if ((watchList.find(nickname) == watchList.end()) &&
+ (serverName == item->text(nlvcServerName))) delete item;
+ }
+ item = nextItem;
+ }
+ item = offlineRoot->firstChild();
+
+ if(item) {
+ while (item)
+ {
+ QListViewItem* nextItem = item->nextSibling();
+ QString nickname = item->text(nlvcNick);
+ if ((watchList.find(nickname) == watchList.end()) &&
+ (serverName == item->text(nlvcServerName))) delete item;
+ item = nextItem;
+ }
+ }
+ else
+ {
+ delete offlineRoot;
+ }
+ // Expand server if newly added to list.
+ if (newNetworkRoot)
+ {
+ networkRoot->setOpen(true);
+ // Connect server NickInfo updates.
+ connect (servr, SIGNAL(nickInfoChanged(Server*, const NickInfoPtr)),
+ this, SLOT(slotNickInfoChanged(Server*, const NickInfoPtr)));
+ }
+}
+
+/**
+ * Determines if a nick is online in any of the servers in a network and returns
+ * a NickInfo if found, otherwise 0.
+ * @param networkName Server network name.
+ * @param nickname Nick name.
+ * @return NickInfo if nick is online in any server, otherwise 0.
+ */
+NickInfoPtr NicksOnline::getOnlineNickInfo(QString& networkName, QString& nickname)
+{
+ // Get list of pointers to all servers.
+ KonversationApplication* konvApp = static_cast<KonversationApplication*>(kapp);
+ QPtrList<Server> serverList = konvApp->getConnectionManager()->getServerList();
+ for (Server* server = serverList.first(); server; server = serverList.next())
+ {
+ if (server->getDisplayName() == networkName)
+ {
+ NickInfoPtr nickInfo = server->getNickInfo(nickname);
+ if (nickInfo) return nickInfo;
+ }
+ }
+ return 0;
+}
+
+/**
+ * Requests a WHOIS for a specified server network and nickname.
+ * The request is sent to the first server found in the network.
+ * @param groupName Server group name.
+ * @param nickname Nick name.
+ */
+void NicksOnline::requestWhois(QString& networkName, QString& nickname)
+{
+ KonversationApplication* konvApp = static_cast<KonversationApplication*>(kapp);
+ QPtrList<Server> serverList = konvApp->getConnectionManager()->getServerList();
+ for (Server* server = serverList.first(); server; server = serverList.next())
+ {
+ if (server->getDisplayName() == networkName)
+ {
+ server->requestWhois(nickname);
+ return;
+ }
+ }
+}
+
+/**
+ * Refresh the nicklistview for all servers.
+ */
+void NicksOnline::refreshAllServerOnlineLists()
+{
+ KonversationApplication* konvApp = static_cast<KonversationApplication*>(kapp);
+ QPtrList<Server> serverList = konvApp->getConnectionManager()->getServerList();
+ Server* server;
+ // Remove servers no longer connected.
+ QListViewItem* child = m_nickListView->firstChild();
+ while (child)
+ {
+ QListViewItem* nextChild = child->nextSibling();
+ QString networkName = child->text(nlvcNetwork);
+ QStringList serverNameList = QStringList::split(",", child->text(nlvcAdditionalInfo));
+ QStringList::Iterator itEnd = serverNameList.end();
+ QStringList::Iterator it = serverNameList.begin();
+ while (it != itEnd)
+ {
+ QString serverName = *it;
+ // Locate server in server list.
+ bool found = false;
+ for (server = serverList.first(); server; server = serverList.next())
+ {
+ if ((server->getServerName() == serverName) &&
+ (server->getDisplayName() == networkName)) found = true;
+ }
+ if (!found)
+ it = serverNameList.remove(it);
+ else
+ ++it;
+ }
+ // Remove Networks with no servers connected, otherwise update list of connected
+ // servers.
+ if (serverNameList.empty())
+ delete child;
+ else
+ child->setText(nlvcAdditionalInfo, serverNameList.join(","));
+ child = nextChild;
+ }
+ // Display info for all currently-connected servers.
+ for (server = serverList.first(); server; server = serverList.next())
+ {
+ updateServerOnlineList(server);
+ }
+ // Refresh addressbook buttons.
+ slotNickListView_SelectionChanged();
+}
+
+void NicksOnline::timerFired()
+{
+ // Allow one WHOIS request per cycle.
+ m_whoisRequested = false;
+ refreshAllServerOnlineLists();
+}
+
+/**
+ * When a user double-clicks a nickname in the nicklistview, let server know so that
+ * it can perform the user's chosen default action for that.
+ */
+void NicksOnline::processDoubleClick(QListViewItem* item)
+{
+ // Only emit signal when the user double clicked a nickname rather than
+ // a server name or channel name.
+ QString serverName;
+ QString nickname;
+ if (getItemServerAndNick(item, serverName, nickname))
+ emit doubleClicked(serverName, nickname);
+}
+
+/**
+ * Returns the server name and nickname of the specified nicklistview item.
+ * @param item The nicklistview item.
+ * @return serverName Name of the server for the nick at the item, or Null if not a nick.
+ * @return nickname The nickname at the item.
+ */
+bool NicksOnline::getItemServerAndNick(const QListViewItem* item, QString& serverName, QString& nickname)
+{
+ if (!item) return false;
+ // convert into NicksOnlineItem
+ const NicksOnlineItem* nlItem=static_cast<const NicksOnlineItem*>(item);
+ // If on a network, return false;
+ if (nlItem->type() == NicksOnlineItem::NetworkRootItem) return false;
+ // get server name
+ serverName = item->text(nlvcServerName);
+ // If on a channel, move up to the nickname.
+ if (nlItem->type() == NicksOnlineItem::ChannelItem)
+ {
+ item = item->parent();
+ serverName = item->text(nlvcServerName);
+ }
+ nickname = item->text(nlvcNick);
+ // offline columns are not nick names
+ if (nlItem->type() == NicksOnlineItem::OfflineItem) return false;
+ return true;
+}
+
+NickInfoPtr NicksOnline::getNickInfo(const QListViewItem* item)
+{
+ QString serverName;
+ QString nickname;
+
+ getItemServerAndNick(item, serverName, nickname);
+
+ if (!serverName || !nickname)
+ return 0;
+
+ Server* server = KonversationApplication::instance()->getConnectionManager()->getServerByName(serverName);
+
+ if (server) return server->getNickInfo(nickname);
+
+ return 0;
+}
+
+/**
+ * Given a server name and nickname, returns the item in the Nick List View displaying
+ * the nick.
+ * @param serverName Name of server.
+ * @param nickname Nick name.
+ * @return Pointer to QListViewItem displaying the nick, or 0 if not found.
+ *
+ * @see getItemServerAndNick
+ */
+QListViewItem* NicksOnline::getServerAndNickItem(const QString& serverName,
+const QString& nickname)
+{
+ Server* server = KonversationApplication::instance()->getConnectionManager()->getServerByName(serverName);
+ if (!server) return 0;
+ QString networkName = server->getDisplayName();
+ QListViewItem* networkRoot = m_nickListView->findItem(networkName, nlvcNetwork);
+ if (!networkRoot) return 0;
+ QListViewItem* nickRoot = findItemChild(networkRoot, nickname, NicksOnlineItem::NicknameItem);
+ return nickRoot;
+}
+
+/**
+ * Perform an addressbook command (edit contact, create new contact,
+ * change/delete association.)
+ * @param id The command id. @ref CommandIDs.
+ *
+ * The operation is performed on the nickname at the currently-selected item in
+ * the nicklistview.
+ *
+ * Also refreshes the nicklistview display to reflect the new addressbook state
+ * for the nick.
+ */
+void NicksOnline::doCommand(int id)
+{
+ if(id < 0)
+ {
+ return;
+ }
+
+ QString serverName;
+ QString nickname;
+ QListViewItem* item = m_nickListView->selectedItem();
+
+ if(!getItemServerAndNick(item, serverName, nickname))
+ {
+ return;
+ }
+
+ // Get the server object corresponding to the server name.
+ Server* server = KonversationApplication::instance()->getConnectionManager()->getServerByName(serverName);
+
+ if (!server) return;
+
+ // Get NickInfo object corresponding to the nickname.
+ NickInfoPtr nickInfo = server->getNickInfo(nickname);
+ // Get addressbook entry for the nick.
+ KABC::Addressee addressee;
+
+ if(nickInfo)
+ {
+ addressee = nickInfo->getAddressee();
+ }
+ else
+ {
+ addressee = server->getOfflineNickAddressee(nickname);
+ }
+
+ switch(id)
+ {
+ case ciSendEmail:
+ Konversation::Addressbook::self()->sendEmail(addressee);
+ return; //no need to refresh item
+ case ciAddressbookEdit:
+ Konversation::Addressbook::self()->editAddressee(addressee.uid());
+ return; //no need to refresh item - nickinfo changed will be called anyway.
+ case ciAddressbookChange:
+ if(nickInfo)
+ {
+ nickInfo->showLinkAddressbookUI();
+ }
+ else
+ {
+ LinkAddressbookUI *linkaddressbookui = new LinkAddressbookUI(server->getViewContainer()->getWindow(), NULL, nickname, server->getServerName(), server->getDisplayName(), addressee.realName());
+ linkaddressbookui->show();
+ }
+ break;
+ case ciAddressbookNew:
+ case ciAddressbookDelete:
+ {
+ Konversation::Addressbook *addressbook = Konversation::Addressbook::self();
+
+ if(addressbook && addressbook->getAndCheckTicket())
+ {
+ if(id == ciAddressbookDelete)
+ {
+ if (addressee.isEmpty())
+ {
+ return;
+ }
+
+ addressbook->unassociateNick(addressee, nickname, server->getServerName(), server->getDisplayName());
+ }
+ else
+ {
+ addressee.setGivenName(nickname);
+ addressee.setNickName(nickname);
+ addressbook->associateNickAndUnassociateFromEveryoneElse(addressee, nickname, server->getServerName(), server->getDisplayName());
+ }
+ if(addressbook->saveTicket())
+ {
+ //saveTicket will refresh the addressees for us.
+ if(id == ciAddressbookNew)
+ {
+ Konversation::Addressbook::self()->editAddressee(addressee.uid());
+ }
+ }
+ }
+ break;
+ }
+ case ciJoinChannel:
+ {
+ // only join real channels
+ if (static_cast<NicksOnlineItem*>(m_nickListView->selectedItem())->type() == NicksOnlineItem::ChannelItem)
+ {
+ QString contactChannel = m_nickListView->selectedItem()->text(nlvcChannel);
+ server->queue( "JOIN "+contactChannel );
+ }
+ break;
+ }
+ case ciWhois:
+ server->queue("WHOIS "+nickname);
+ return;
+ case ciOpenQuery:
+ NickInfoPtr nickInfo = server->obtainNickInfo(nickname);
+ class Query* query = server->addQuery(nickInfo, true /*we initiated*/);
+ emit showView(query);
+ return;
+ }
+
+ refreshItem(item);
+}
+
+/**
+ * Get the addressbook state of the nickname at the specified nicklistview item.
+ * @param item Item of the nicklistview.
+ * @return Addressbook state.
+ * 0 = not a nick, 1 = nick has no addressbook association, 2 = nick has association
+ */
+int NicksOnline::getNickAddressbookState(QListViewItem* item)
+{
+ int nickState = nsNotANick;
+ QString serverName;
+ QString nickname;
+ if (getItemServerAndNick(item, serverName, nickname))
+ {
+ Server *server = KonversationApplication::instance()->getConnectionManager()->getServerByName(serverName);
+ if (!server) return nsNotANick;
+ NickInfoPtr nickInfo = server->getNickInfo(nickname);
+ if (nickInfo)
+ {
+ if (nickInfo->getAddressee().isEmpty())
+ nickState = nsNoAddress;
+ else
+ nickState = nsHasAddress;
+ }
+ else
+ {
+ if (server->getOfflineNickAddressee(nickname).isEmpty())
+ nickState = nsNoAddress;
+ else
+ nickState = nsHasAddress;
+ }
+ }
+ return nickState;
+}
+
+/**
+ * Sets the enabled/disabled state and labels of the addressbook buttons
+ * based on the given nick addressbook state.
+ * @param nickState The state of the nick. 1 = not associated with addressbook,
+ * 2 = associated with addressbook. @ref getNickAddressbookState.
+ */
+void NicksOnline::setupAddressbookButtons(int nickState)
+{
+ switch (nickState)
+ {
+ case nsNotANick:
+ {
+ m_editContactButton->setEnabled(false);
+ m_changeAssociationButton->setEnabled(false);
+ m_deleteAssociationButton->setEnabled(false);
+ break;
+ }
+ case nsNoAddress:
+ {
+ m_editContactButton->setText(i18n("Create New C&ontact..."));
+ m_editContactButton->setEnabled(true);
+ m_changeAssociationButton->setText(i18n("&Choose Association..."));
+ m_changeAssociationButton->setEnabled(true);
+ m_deleteAssociationButton->setEnabled(false);
+ break;
+ }
+ case nsHasAddress:
+ {
+ m_editContactButton->setText(i18n("Edit C&ontact..."));
+ m_editContactButton->setEnabled(true);
+ m_changeAssociationButton->setText(i18n("&Change Association..."));
+ m_changeAssociationButton->setEnabled(true);
+ m_deleteAssociationButton->setEnabled(true);
+ break;
+ }
+ }
+}
+
+/**
+ * Received when user clicks the Edit Contact (or New Contact) button.
+ */
+void NicksOnline::slotEditContactButton_Clicked()
+{
+ switch (getNickAddressbookState(m_nickListView->selectedItem()))
+ {
+ case nsNotANick: break;
+ case nsNoAddress: { doCommand(ciAddressbookNew); break; }
+ case nsHasAddress: { doCommand(ciAddressbookEdit); break; }
+ }
+}
+
+/**
+ * Received when user clicks the Change Association button.
+ */
+void NicksOnline::slotChangeAssociationButton_Clicked() { doCommand(ciAddressbookChange); }
+/**
+ * Received when user clicks the Delete Association button.
+ */
+void NicksOnline::slotDeleteAssociationButton_Clicked() { doCommand(ciAddressbookDelete); }
+/**
+ * Received when user selects a different item in the nicklistview.
+ */
+void NicksOnline::slotNickListView_SelectionChanged()
+{
+ QListViewItem* item = m_nickListView->selectedItem();
+ int nickState = getNickAddressbookState(item);
+ setupAddressbookButtons(nickState);
+}
+
+/**
+ * Received when right-clicking an item in the NickListView.
+ */
+void NicksOnline::slotNickListView_RightButtonClicked(QListViewItem* item, const QPoint& pt)
+{
+ if (!item) return;
+ m_popupMenu->clear();
+ int nickState = getNickAddressbookState(item);
+ switch (nickState)
+ {
+ case nsNotANick:
+ {
+ break;
+ }
+ case nsNoAddress:
+ {
+ m_popupMenu->insertItem(i18n("&Choose Association..."), ciAddressbookChange);
+ m_popupMenu->insertItem(i18n("Create New C&ontact..."), ciAddressbookNew);
+ m_popupMenu->insertSeparator();
+ m_popupMenu->insertItem(i18n("&Whois"), ciWhois);
+ m_popupMenu->insertItem(i18n("Open &Query"), ciOpenQuery);
+ if (item->text(nlvcServerName).isEmpty())
+ m_popupMenu->insertItem(i18n("&Join Channel"), ciJoinChannel);
+ break;
+ }
+ case nsHasAddress:
+ {
+ m_popupMenu->insertItem(SmallIcon("mail_generic"), i18n("&Send Email..."), ciSendEmail);
+ m_popupMenu->insertSeparator();
+ m_popupMenu->insertItem(SmallIcon("contents"), i18n("Edit C&ontact..."), ciAddressbookEdit);
+ m_popupMenu->insertSeparator();
+ m_popupMenu->insertItem(i18n("&Change Association..."), ciAddressbookChange);
+ m_popupMenu->insertItem(SmallIconSet("editdelete"), i18n("&Delete Association"), ciAddressbookDelete);
+ m_popupMenu->insertSeparator();
+ m_popupMenu->insertItem(i18n("&Whois"), ciWhois);
+ m_popupMenu->insertItem(i18n("Open &Query"), ciOpenQuery);
+ if (item->text(nlvcServerName).isEmpty())
+ m_popupMenu->insertItem(i18n("&Join Channel"), ciJoinChannel);
+ break;
+ }
+ }
+ if (nickState != nsNotANick)
+ m_popupMenu->popup(pt);
+}
+
+/**
+ * Received from popup menu when user chooses something.
+ */
+void NicksOnline::slotPopupMenu_Activated(int id)
+{
+ doCommand(id);
+}
+
+/**
+ * Received from server when a NickInfo changes its information.
+ */
+void NicksOnline::slotNickInfoChanged(Server* server, const NickInfoPtr nickInfo)
+{
+ if (!nickInfo) return;
+ QString nickname = nickInfo->getNickname();
+
+ if (!server) return;
+ QString serverName = server->getServerName();
+ QListViewItem* item = getServerAndNickItem(serverName, nickname);
+ refreshItem(item);
+}
+
+/**
+ * Refreshes the information for the given item in the list.
+ * @param item Pointer to listview item.
+ */
+void NicksOnline::refreshItem(QListViewItem* item)
+{
+ if (!item) return;
+ QString serverName;
+ QString nickname;
+ if (getItemServerAndNick(item, serverName, nickname))
+ {
+ Server *server = KonversationApplication::instance()->getConnectionManager()->getServerByName(serverName);
+ if (server)
+ {
+ NickInfoPtr nickInfo = server->getNickInfo(nickname);
+ KABC::Addressee addressee;
+ if (nickInfo)
+ addressee = nickInfo->getAddressee();
+ else
+ addressee = server->getOfflineNickAddressee(nickname);
+ int nickState = 2;
+ if (addressee.isEmpty()) nickState = 1;
+ switch (nickState)
+ {
+ case nsNotANick:
+ break;
+ case nsNoAddress:
+ {
+ item->setPixmap(nlvcKabc, m_kabcIconSet.pixmap(
+ QIconSet::Small, QIconSet::Disabled, QIconSet::Off)); break;
+ }
+ case nsHasAddress:
+ {
+ item->setPixmap(nlvcKabc, m_kabcIconSet.pixmap(
+ QIconSet::Small, QIconSet::Normal, QIconSet::On)); break;
+ }
+ }
+ QString nickAdditionalInfo;
+ bool needWhois = false;
+ if (nickInfo) nickAdditionalInfo = getNickAdditionalInfo(nickInfo, addressee,
+ needWhois);
+ item->setText(nlvcAdditionalInfo, nickAdditionalInfo);
+ if (item == m_nickListView->selectedItem()) setupAddressbookButtons(nickState);
+ }
+ }
+}
+
+void NicksOnline::childAdjustFocus() {}
+
+#include "nicksonline.moc"
+
+// kate: space-indent on; tab-width 4; indent-width 4; mixed-indent off; replace-tabs on;
+// vim: set et sw=4 ts=4 cino=l1,cs,U1: