ircdock.cpp
1 //------------------------------------------------------------------------------
2 // ircdock.cpp
3 //------------------------------------------------------------------------------
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 // 02110-1301 USA
19 //
20 //------------------------------------------------------------------------------
21 // Copyright (C) 2010 "Zalewa" <zalewapl@gmail.com>
22 //------------------------------------------------------------------------------
23 #include "ircdock.h"
24 #include "ui_ircdock.h"
25 #include "gui/irc/ircdocktabcontents.h"
26 #include "gui/irc/ircnetworkselectionbox.h"
27 #include "gui/irc/ircsounds.h"
28 #include "irc/configuration/chatnetworkscfg.h"
29 #include "irc/configuration/ircconfig.h"
30 #include "irc/ircnetworkadapter.h"
31 
32 #include <QInputDialog>
33 #include <QMessageBox>
34 #include <QTabBar>
35 #include <QToolBar>
36 
37 DClass<IRCDock> : public Ui::IRCDock
38 {
39 public:
40  IRCSounds pSounds;
41  QAction* toolBarConnect;
42  QAction* toolBarOpenChatWindow;
43 };
44 
45 DPointered(IRCDock)
46 
47 IRCDock::IRCDock(QWidget* parent)
48 : QDockWidget(parent)
49 {
50  d->setupUi(this);
51  toggleViewAction()->setIcon(QIcon(":/icons/chat.png"));
52 
53  d->pSounds.loadFromConfig();
54 
55  setupToolbar();
56 
57  connect(d->tabWidget, SIGNAL( currentChanged(int) ),
58  SLOT( tabCurrentChanged(int) ));
59 
60  connect(d->tabWidget, SIGNAL( tabCloseRequested(int) ),
61  SLOT( tabCloseRequestedSlot(int) ));
62 }
63 
64 IRCDock::~IRCDock()
65 {
66 }
67 
68 IRCDockTabContents* IRCDock::addIRCAdapter(IRCAdapterBase* pIRCAdapter)
69 {
70  IRCDockTabContents* pNewAdapterWidget = new IRCDockTabContents(this);
71 
72  connect(pNewAdapterWidget, SIGNAL( chatWindowCloseRequest(IRCDockTabContents*) ), SLOT( chatWindowCloseRequestSlot(IRCDockTabContents*) ) );
73  connect(pNewAdapterWidget, SIGNAL( focusRequest(IRCDockTabContents*) ), SLOT( tabFocusRequest(IRCDockTabContents*) ) );
74  connect(pNewAdapterWidget, SIGNAL( titleChange(IRCDockTabContents*) ), SLOT( titleChange(IRCDockTabContents*) ) );
75  connect(pNewAdapterWidget, SIGNAL(newMessagePrinted()),
76  SLOT(titleChangeWithColorOfSenderIfNotFocused()));
77  connect(pNewAdapterWidget, SIGNAL(titleBlinkRequested()),
78  SLOT(titleChangeWithColorOfSenderIfNotFocused()));
79 
80  pNewAdapterWidget->setIRCAdapter(pIRCAdapter);
81  d->tabWidget->addTab(pNewAdapterWidget, pNewAdapterWidget->icon(), pNewAdapterWidget->title());
82  this->titleChange(pNewAdapterWidget);
83 
84  return pNewAdapterWidget;
85 }
86 
88 {
89  for (int i = 0; i < d->tabWidget->count(); ++i)
90  {
91  IRCDockTabContents* pWidget = (IRCDockTabContents*)d->tabWidget->widget(i);
92  pWidget->applyAppearanceSettings();
93  }
94 }
95 
96 void IRCDock::chatWindowCloseRequestSlot(IRCDockTabContents* pCaller)
97 {
98  int tabIndex = d->tabWidget->indexOf(pCaller);
99  if (tabIndex >= 0)
100  {
101  tabCloseRequestedSlot(tabIndex);
102  }
103 }
104 
105 void IRCDock::connectToNewNetwork(const IRCNetworkConnectionInfo &connectionInfo, bool bFocusOnNewTab)
106 {
107  IRCNetworkAdapter* pIRCNetworkAdapter = new IRCNetworkAdapter(connectionInfo);
108 
109  // Switch this to true only for debug.
110  pIRCNetworkAdapter->setEmitAllIRCMessagesEnabled(false);
111 
112  // Setup the UI tab for the new network.
113  IRCDockTabContents* pTab = addIRCAdapter(pIRCNetworkAdapter);
114 
115  // Connect to the network.
116  pIRCNetworkAdapter->connect();
117 
118  if (bFocusOnNewTab)
119  {
120  tabFocusRequest(pTab);
121  }
122 }
123 
124 bool IRCDock::hasTabFocus(const IRCDockTabContents* pTab) const
125 {
126  return (this->d->tabWidget->currentWidget() == pTab);
127 }
128 
129 IRCNetworkAdapter* IRCDock::networkWithUiFocus()
130 {
131  IRCDockTabContents* pWidget = (IRCDockTabContents*)d->tabWidget->currentWidget();
132  if (pWidget == NULL)
133  {
134  return NULL;
135  }
136 
137  return pWidget->ircAdapter()->network();
138 }
139 
140 void IRCDock::performNetworkAutojoins()
141 {
142  IRCNetworkConnectionInfo connectionInfo;
143  connectionInfo.alternateNick = gIRCConfig.personal.alternativeNickname;
144  connectionInfo.nick = gIRCConfig.personal.nickname;
145  connectionInfo.realName = gIRCConfig.personal.fullName;
146  connectionInfo.userName = gIRCConfig.personal.userName;
147 
148  QList<IRCNetworkEntity> autojoinNetworks = ChatNetworksCfg().autoJoinNetworks();
149  foreach (const IRCNetworkEntity& network, autojoinNetworks)
150  {
151  connectionInfo.networkEntity = network;
152 
153  connectToNewNetwork(connectionInfo.autoFilled(), false);
154  }
155 }
156 
157 QString IRCDock::prefixMessage(IRCAdapterBase* pTargetChatWindow, IRCAdapterBase* pMessageSender, const QString& message)
158 {
159  if (pMessageSender != NULL)
160  {
161  IRCNetworkAdapter* pTargetNetwork = pTargetChatWindow->network();
162  if (pTargetNetwork != pMessageSender)
163  {
164  return QString("%1: %2").arg(pMessageSender->title(), message);
165  }
166  }
167 
168  return message;
169 }
170 
171 void IRCDock::setupToolbar()
172 {
173  QToolBar* pToolBar = new QToolBar(this);
174  pToolBar->setMovable(false);
175  pToolBar->setOrientation(Qt::Vertical);
176 
177  d->toolBarConnect = new QAction(QIcon(":/icons/network-connect-3.png"), tr("Connect"), pToolBar);
178  d->toolBarOpenChatWindow = new QAction(QIcon(":/icons/irc_channel.png"), tr("Open chat window"), pToolBar);
179 
180  pToolBar->addAction(d->toolBarConnect);
181  pToolBar->addAction(d->toolBarOpenChatWindow);
182 
183  d->horizontalLayout->insertWidget(0, pToolBar);
184  connect(pToolBar, SIGNAL( actionTriggered(QAction*) ), this, SLOT( toolBarAction(QAction*) ) );
185 }
186 
187 IRCSounds& IRCDock::sounds()
188 {
189  return d->pSounds;
190 }
191 
192 void IRCDock::tabCloseRequestedSlot(int index)
193 {
194  QWidget* pPageWidget = d->tabWidget->widget(index);
195  d->tabWidget->removeTab(index);
196 
197  delete pPageWidget;
198 }
199 
200 void IRCDock::tabCurrentChanged(int index)
201 {
202  if (index >= 0)
203  {
204  d->tabWidget->tabBarPublic()->setTabTextColor(index, "");
205  IRCDockTabContents* pTab = (IRCDockTabContents*) d->tabWidget->widget(index);
206  pTab->grabFocus();
207  }
208 }
209 
210 void IRCDock::tabFocusRequest(IRCDockTabContents* pCaller)
211 {
212  d->tabWidget->setCurrentWidget(pCaller);
213 }
214 
215 IRCDockTabContents *IRCDock::tabWithFocus()
216 {
217  if (d->tabWidget->currentWidget() != NULL)
218  {
219  return static_cast<IRCDockTabContents*>(d->tabWidget->currentWidget());
220  }
221  return NULL;
222 }
223 
224 void IRCDock::titleChange(IRCDockTabContents* caller)
225 {
226  int tabIndex = d->tabWidget->indexOf(caller);
227  if (tabIndex >= 0)
228  {
229  d->tabWidget->setTabText(tabIndex, caller->title());
230  }
231 }
232 
233 void IRCDock::titleChangeWithColorOfSenderIfNotFocused()
234 {
235  IRCDockTabContents* caller = static_cast<IRCDockTabContents*>(sender());
236  int tabIndex = d->tabWidget->indexOf(caller);
237  if (tabIndex >= 0)
238  {
239  d->tabWidget->setTabText(tabIndex, caller->title());
240  d->tabWidget->tabBarPublic()->setTabTextColor(tabIndex, caller->titleColor());
241  }
242 }
243 
244 void IRCDock::toolBarAction(QAction* pAction)
245 {
246  if (pAction == d->toolBarConnect)
247  {
248  IRCNetworkSelectionBox networkSelection(this);
249  if (networkSelection.exec() == QDialog::Accepted)
250  {
251  IRCNetworkConnectionInfo connectionInfo = networkSelection.networkConnectionInfo();
252  ChatNetworksCfg().setLastUsedNetwork(connectionInfo.networkEntity);
253 
254  // We will attempt to remember user credentials for further use.
255  gIRCConfig.personal.alternativeNickname = connectionInfo.alternateNick;
256  gIRCConfig.personal.nickname = connectionInfo.nick;
257  gIRCConfig.personal.fullName = connectionInfo.realName;
258  gIRCConfig.personal.userName = connectionInfo.userName;
259 
260  connectToNewNetwork(connectionInfo.autoFilled(), true);
261  }
262  }
263  else if (pAction == d->toolBarOpenChatWindow)
264  {
265  IRCNetworkAdapter* pNetwork = networkWithUiFocus();
266  if (pNetwork == NULL)
267  {
268  QMessageBox::warning(NULL, tr("Doomseeker IRC - Open chat window"), tr("Cannot obtain network connection adapter."));
269  }
270  else if (!pNetwork->isConnected())
271  {
272  QMessageBox::warning(NULL, tr("Doomseeker IRC - Open chat window"), tr("You are not connected to this network."));
273  }
274  else
275  {
276  QString recipientName = QInputDialog::getText(NULL, tr("Open chat window"), tr("Specify a channel or user name:"));
277  if (!recipientName.isEmpty())
278  {
279  pNetwork->openNewAdapter(recipientName);
280  }
281  }
282  }
283 }
Interprets communication between the client and the IRC server.
void setIRCAdapter(IRCAdapterBase *pAdapter)
Calling this multiple times on the same object will cause memory leaks.
QString userName
User name sent in /user command.
Dockable widget designed for IRC communication.
Definition: ircdock.h:39
QString alternateNick
Alternate nickname in case if &#39; nick &#39; is taken when connecting.
IRCNetworkConnectionInfo autoFilled() const
Fills missing data with presets.
void openNewAdapter(const QString &recipientName)
Opens a new chat adapter for specified recipient.
void grabFocus()
Called when tab becomes active.
Provides an unified communication interface between a client and IRC network entities.
void setEmitAllIRCMessagesEnabled(bool b)
QString nick
Original nickname. This variable will always store the current nickname of the client.
Struct containing information about client&#39;s connection to the IRC server.
Dockable widget designed for IRC communication.
virtual QString title() const =0
Gets title for this adapter.
QString realName
User&#39;s real name. Optional.
IRCNetworkEntity networkEntity
Information about the network to which we will connect.
void applyAppearanceSettings()
Applies IRC appearance settings to all open tabs.
Definition: ircdock.cpp:87
Part of IRC UI package. Plays IRC related sounds.
Definition: ircsounds.h:36
virtual IRCNetworkAdapter * network()=0
The idea of the adapter system is that each adapter is either a network or is a child of a network...
Data structure that describes and defines a connection to an IRC network or server.
void applyAppearanceSettings()
Applies current appearance settings from the IRC config.