Guest User

Untitled

a guest
Jun 22nd, 2018
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 42.45 KB | None | 0 0
  1. #include "channeltab.h"
  2. #include "channelview.h"
  3. #include "chatinput.h"
  4. #include "chatview.h"
  5. #include "dialogs/messagelog.h"
  6. #include "identityconfig.h"
  7. #include "nickview.h"
  8. #include "settings.h"
  9. #include <Aki/Irc/Channel>
  10. #include <Aki/Irc/Color>
  11. #include <Aki/Irc/Rfc2812>
  12. #include <Aki/Irc/Socket>
  13. #include <Aki/Irc/User>
  14. #include <KAction>
  15. #include <KComboBox>
  16. #include <KDebug>
  17. #include <KLineEdit>
  18. #include <KLocale>
  19. #include <KMenu>
  20. #include <QGridLayout>
  21. #include <QListView>
  22. #include <QSplitter>
  23. #include <QTimer>
  24. #include "nicklistmodel.h"
  25.  
  26. class ChannelTabPrivate
  27. {
  28. public:
  29. QGridLayout *mainLayout;
  30. QSplitter *mainSplitter;
  31. NickView *userList;
  32. ChatView *channelOutput;
  33. KComboBox *nickSelector;
  34. ChatInput *channelInput;
  35. KLineEdit *topic;
  36. QTimer *whoTimer;
  37. Aki::Irc::Channel *channel;
  38. Aki::Irc::Socket *socket;
  39. IdentityConfig *config;
  40. ChannelView *view;
  41. QStringList autoRequest;
  42. bool isCurrent;
  43. bool whoWaiting;
  44. }; // End of class ChannelTabPrivate.
  45.  
  46. ChannelTab::ChannelTab(const QString &name, IdentityConfig *identity, Aki::Irc::Socket *socket, QWidget *parent)
  47. : Aki::ChannelInterface(parent),
  48. d(new ChannelTabPrivate)
  49. {
  50. qsrand(std::time(0));
  51. d->socket = socket;
  52. d->config = identity;
  53.  
  54. setName(name);
  55. setSocket(socket);
  56.  
  57. d->mainLayout = new QGridLayout(this);
  58. d->mainSplitter = new QSplitter(this);
  59. d->mainSplitter->setOrientation(Qt::Horizontal);
  60. d->mainSplitter->setChildrenCollapsible(false);
  61.  
  62. d->channelOutput = new ChatView(d->mainSplitter);
  63. d->channelOutput->setNotifyClick(false);
  64.  
  65. QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
  66. sizePolicy.setHorizontalStretch(1);
  67. sizePolicy.setVerticalStretch(0);
  68. sizePolicy.setHeightForWidth(d->channelOutput->sizePolicy().hasHeightForWidth());
  69. d->channelOutput->setSizePolicy(sizePolicy);
  70.  
  71. d->topic = new KLineEdit(this);
  72.  
  73. d->mainSplitter->addWidget(d->channelOutput);
  74. d->userList = new NickView(d->mainSplitter);
  75. d->userList->setContextMenuPolicy(Qt::CustomContextMenu);
  76. d->userList->setFocusPolicy(Qt::NoFocus);
  77. connect(d->userList, SIGNAL(customContextMenuRequested(QPoint)),
  78. this, SLOT(slotCustomContextMenuRequested(QPoint)));
  79.  
  80. d->mainSplitter->addWidget(d->userList);
  81.  
  82. d->mainLayout->addWidget(d->topic, 0, 0, 1, 2);
  83. d->mainLayout->addWidget(d->mainSplitter, 1, 0, 1, 2);
  84.  
  85. d->nickSelector = new KComboBox(false, this);
  86. d->nickSelector->setEditable(false);
  87. d->nickSelector->setDuplicatesEnabled(false);
  88. d->mainLayout->addWidget(d->nickSelector, 2, 0, 1, 1);
  89.  
  90. d->channelInput = new ChatInput(this);
  91. d->mainLayout->addWidget(d->channelInput, 2, 1, 1, 1);
  92.  
  93. d->channel = new Aki::Irc::Channel(name, this);
  94. setLayout(d->mainLayout);
  95.  
  96. d->whoWaiting = false;
  97.  
  98. d->view = qobject_cast<ChannelView*>(parent);
  99.  
  100. QWidget::setTabOrder(d->topic, d->channelOutput);
  101. QWidget::setTabOrder(d->channelOutput, d->nickSelector);
  102. QWidget::setTabOrder(d->nickSelector, d->channelInput);
  103. QWidget::setTabOrder(d->channelInput, d->userList);
  104. QWidget::setTabOrder(d->userList, d->topic);
  105.  
  106. connect(d->socket, SIGNAL(onTopic(QString,QString)),
  107. this, SLOT(slotOnTopic(QString,QString)));
  108. connect(d->socket, SIGNAL(onPrivmsg(QString,QString,QString,QString)),
  109. this, SLOT(slotOnPrivmsg(QString,QString,QString,QString)));
  110. connect(d->socket, SIGNAL(onUserJoin(QString,QString)),
  111. this, SLOT(slotOnUserJoin(QString,QString)));
  112. connect(d->socket, SIGNAL(onUserPart(QString,QString,QString)),
  113. this, SLOT(slotOnUserPart(QString,QString,QString)));
  114. connect(d->socket, SIGNAL(onNoticeAuth(QString)),
  115. this, SLOT(slotOnNoticeAuth(QString)));
  116. connect(d->socket, SIGNAL(onNotice(QString)),
  117. this, SLOT(slotOnNotice(QString)));
  118. connect(d->socket, SIGNAL(onNotice(QString,QString)),
  119. this, SLOT(slotOnNotice(QString,QString)));
  120. connect(d->socket, SIGNAL(onNameReply(QString,QString)),
  121. this, SLOT(slotOnNameReply(QString,QString)));
  122. connect(d->socket, SIGNAL(onCreated(QString)),
  123. this, SLOT(slotOnWelcome(QString)));
  124. connect(d->socket, SIGNAL(onYourHost(QString)),
  125. this, SLOT(slotOnWelcome(QString)));
  126. connect(d->socket, SIGNAL(onWelcome(QString)),
  127. this, SLOT(slotOnWelcome(QString)));
  128. connect(d->socket, SIGNAL(onMyInfo(QString)),
  129. this, SLOT(slotOnWelcome(QString)));
  130. connect(d->socket, SIGNAL(onBounce(QString)),
  131. this, SLOT(slotOnSupport(QString)));
  132. connect(d->socket, SIGNAL(onMotd(QString)),
  133. this, SLOT(slotOnMotd(QString)));
  134. connect(d->socket, SIGNAL(onWho(QString,QString,QString,QString,QString,QString,int,QString)),
  135. this, SLOT(slotOnWho(QString,QString,QString,QString,QString,QString,int,QString)));
  136. connect(d->socket, SIGNAL(onNick(QString,QString)),
  137. this, SLOT(slotOnNick(QString,QString)));
  138. connect(d->socket, SIGNAL(onKick(QString,QString,QString)),
  139. this, SLOT(slotOnKick(QString,QString,QString)));
  140. connect(d->socket, SIGNAL(onMode(QString,QString,QString,QString)),
  141. this, SLOT(slotOnMode(QString,QString,QString,QString)));
  142. connect(d->socket, SIGNAL(onUserQuit(QString,QString)),
  143. this, SLOT(slotOnUserQuit(QString,QString)));
  144. connect(d->nickSelector, SIGNAL(activated(QString)),
  145. this, SLOT(slotNickIndexChanged(QString)));
  146. connect(d->channelInput, SIGNAL(textSubmitted()),
  147. this, SLOT(slotTextSubmitted()));
  148. connect(d->socket, SIGNAL(onCtcpAction(QString,QString,QString)),
  149. this, SLOT(slotOnCtcpAction(QString,QString,QString)));
  150. connect(d->socket, SIGNAL(onNoticeCtcpVersion(QString,QString)),
  151. this, SLOT(slotOnNoticeCtcpVersion(QString,QString)));
  152. connect(d->socket, SIGNAL(onNicknameInUseError(QString,QString)),
  153. this, SLOT(slotOnNicknameInUseError(QString,QString)));
  154. connect(d->socket, SIGNAL(onTopicSetBy(QString,QString,QString)),
  155. this, SLOT(slotOnTopicSetBy(QString,QString,QString)));
  156. connect(d->socket, SIGNAL(onChannelCreated(QString,QString)),
  157. this, SLOT(slotOnChannelCreated(QString,QString)));
  158. connect(d->socket, SIGNAL(onRawMessage(QString)),
  159. this, SLOT(slotOnRawMessage(QString)));
  160. connect(d->channelInput, SIGNAL(showCompletion()),
  161. this, SLOT(slotShowCompletion()));
  162. connect(d->socket, SIGNAL(onChannelPrivilegesNeededError(QString,QString)),
  163. this, SLOT(slotOnChannelPrivilegesNeededError(QString,QString)));
  164. connect(d->socket, SIGNAL(onModeUnknownFlagError(QString)),
  165. this, SLOT(slotOnModeUnknownFlagError(QString)));
  166. connect(d->socket, SIGNAL(onUsersDontMatchError(QString)),
  167. this, SLOT(slotOnUsersDontMatchError(QString)));
  168. connect(d->socket, SIGNAL(onEndOfWho(QString,QString)),
  169. this, SLOT(slotOnEndOfWho(QString,QString)));
  170.  
  171. if (name != d->socket->name()) {
  172. d->whoTimer = new QTimer(this);
  173. d->whoTimer->start(90000);
  174. connect(d->whoTimer, SIGNAL(timeout()), this, SLOT(slotPerformWho()));
  175. d->socket->rfcMode(name);
  176. d->socket->rfcWho(name);
  177. } else {
  178. QTimer::singleShot(10000, this, SLOT(slotPerformJoin()));
  179. setHideNickList(true);
  180. d->topic->setHidden(true);
  181. }
  182. }
  183.  
  184. ChannelTab::~ChannelTab()
  185. {
  186. delete d;
  187. }
  188.  
  189. void
  190. ChannelTab::addNick(const QString &nick)
  191. {
  192. if (!d->nickSelector->contains(nick)) {
  193. d->nickSelector->insertItem(d->nickSelector->count(), nick);
  194. emit nickAdded(nick);
  195. }
  196. }
  197.  
  198. ChatView*
  199. ChannelTab::channelOutput()
  200. {
  201. return d->channelOutput;
  202. }
  203.  
  204. void
  205. ChannelTab::clearNickList()
  206. {
  207. foreach (Aki::Irc::User *user, d->userList->users()) {
  208. d->userList->removeItem(user);
  209. }
  210. }
  211.  
  212. bool
  213. ChannelTab::isNickListHidden() const
  214. {
  215. return d->userList->isHidden();
  216. }
  217.  
  218. void
  219. ChannelTab::setCurrent(bool current)
  220. {
  221. ChannelInterface::setCurrent(current);
  222. if (isCurrent()) {
  223. d->channelInput->setFocus();
  224. }
  225. }
  226.  
  227. void
  228. ChannelTab::setNickList(const QStringList &nicks)
  229. {
  230. d->nickSelector->clear();
  231. d->nickSelector->addItems(nicks);
  232. d->nickSelector->setCurrentIndex(d->nickSelector->findText(d->socket->currentNick()));
  233. }
  234.  
  235. void
  236. ChannelTab::setHideNickList(bool hide)
  237. {
  238. d->userList->setHidden(hide);
  239. }
  240.  
  241. void
  242. ChannelTab::setTabColor(ChannelTab::TabColor color)
  243. {
  244. const int currentIndex = view()->indexOf(this);
  245. const QColor currentColour = view()->tabTextColor(currentIndex);
  246.  
  247. if (color == ChannelTab::Default) {
  248. view()->setTabTextColor(currentIndex, Aki::Settings::defaultTabColor());
  249. } else if (color == ChannelTab::Highlight) {
  250. view()->setTabTextColor(currentIndex, Aki::Settings::highlightTabColor());
  251. } else if (color == ChannelTab::NewData) {
  252. if (currentColour != Aki::Settings::newMessageTabColor() ||
  253. currentColour != Aki::Settings::highlightTabColor()) {
  254. view()->setTabTextColor(currentIndex, Aki::Settings::newDataTabColor());
  255. }
  256. } else if (color == ChannelTab::NewMessage) {
  257. if (currentColour != Aki::Settings::highlightTabColor()) {
  258. view()->setTabTextColor(currentIndex, Aki::Settings::newMessageTabColor());
  259. }
  260. }
  261. }
  262.  
  263. void
  264. ChannelTab::slotBanNicknameTriggered()
  265. {
  266. NickListModel *model = static_cast<NickListModel*>(d->userList->model());
  267. Aki::Irc::User *user = model->data(d->userList->currentIndex(), NickListModel::IrcUserRole)
  268. .value<Aki::Irc::User*>();
  269. d->socket->rfcMode(name(), QString("+b *!%1@%2").arg(user->user(), user->host()));
  270. }
  271.  
  272. void
  273. ChannelTab::slotCustomContextMenuRequested(const QPoint &pos)
  274. {
  275. Q_UNUSED(pos);
  276.  
  277. KMenu *ctx = new KMenu(this);
  278. KMenu *modesMenu = new KMenu(i18n("Modes"), ctx);
  279. KMenu *kickBanMenu = new KMenu(i18n("Kick / Ban"), ctx);
  280.  
  281. KAction *giveOpAction = new KAction(modesMenu);
  282. giveOpAction->setText(i18n("Give Ops"));
  283. giveOpAction->setIcon(KIcon("irc-operator"));
  284. connect(giveOpAction, SIGNAL(triggered(bool)),
  285. this, SLOT(slotGiveOpTriggered()));
  286.  
  287. KAction *takeOpAction = new KAction(modesMenu);
  288. takeOpAction->setText(i18n("Take Ops"));
  289. takeOpAction->setIcon(KIcon("irc-remove-operator"));
  290. connect(takeOpAction, SIGNAL(triggered(bool)),
  291. this, SLOT(slotTakeOpTriggered()));
  292.  
  293. KAction *giveHalfOpAction = new KAction(modesMenu);
  294. giveHalfOpAction->setText(i18n("Give Half-Ops"));
  295. connect(giveHalfOpAction, SIGNAL(triggered(bool)),
  296. this, SLOT(slotGiveHalfOpTriggered()));
  297.  
  298. KAction *takeHalfOpAction = new KAction(modesMenu);
  299. takeHalfOpAction->setText(i18n("Take Half-Ops"));
  300. connect(takeHalfOpAction, SIGNAL(triggered(bool)),
  301. this, SLOT(slotTakeHalfOpTriggered()));
  302.  
  303. KAction *giveVoiceAction = new KAction(modesMenu);
  304. giveVoiceAction->setText(i18n("Give Voice"));
  305. giveVoiceAction->setIcon(KIcon("irc-voice"));
  306. connect(giveVoiceAction, SIGNAL(triggered(bool)),
  307. this, SLOT(slotGiveVoiceTriggered()));
  308.  
  309. KAction *takeVoiceAction = new KAction(modesMenu);
  310. takeVoiceAction->setText(i18n("Take Voice"));
  311. takeVoiceAction->setIcon(KIcon("irc-unvoice"));
  312. connect(takeVoiceAction, SIGNAL(triggered(bool)),
  313. this, SLOT(slotTakeVoiceTriggered()));
  314.  
  315. modesMenu->addAction(giveOpAction);
  316. modesMenu->addAction(takeOpAction);
  317. modesMenu->addSeparator();
  318. modesMenu->addAction(giveHalfOpAction);
  319. modesMenu->addAction(takeHalfOpAction);
  320. modesMenu->addSeparator();
  321. modesMenu->addAction(giveVoiceAction);
  322. modesMenu->addAction(takeVoiceAction);
  323.  
  324. KAction *kickUserAction = new KAction(kickBanMenu);
  325. kickUserAction->setText(i18n("Kick"));
  326. connect(kickUserAction, SIGNAL(triggered(bool)),
  327. this, SLOT(slotKickUserTriggered()));
  328.  
  329. KAction *banNicknameAction = new KAction(kickBanMenu);
  330. banNicknameAction->setText(i18n("Ban"));
  331. connect(banNicknameAction, SIGNAL(triggered(bool)),
  332. this, SLOT(slotBanNicknameTriggered()));
  333.  
  334. KAction *kickBanUserAction = new KAction(kickBanMenu);
  335. kickBanUserAction->setText(i18n("KickBan"));
  336.  
  337. KAction *banHostAction = new KAction(kickBanMenu);
  338. banHostAction->setText(i18n("Ban *!*@!.host"));
  339.  
  340. KAction *banDomainAction = new KAction(kickBanMenu);
  341. banDomainAction->setText(i18n("Ban *!*@domain"));
  342.  
  343. KAction *banUserHostAction = new KAction(kickBanMenu);
  344. banUserHostAction->setText(i18n("Ban *!user@*.host"));
  345.  
  346. KAction *banUserDomainAction = new KAction(kickBanMenu);
  347. banUserDomainAction->setText(i18n("Ban *!user@domain"));
  348.  
  349. KAction *kickBanHostAction = new KAction(kickBanMenu);
  350. kickBanHostAction->setText(i18n("KickBan *!*@*.host"));
  351.  
  352. KAction *kickBanDomainAction = new KAction(kickBanMenu);
  353. kickBanDomainAction->setText(i18n("KickBan *!*@domain"));
  354.  
  355. KAction *kickBanUserHostAction = new KAction(kickBanMenu);
  356. kickBanUserHostAction->setText(i18n("KickBan *!user@*.host"));
  357.  
  358. KAction *kickBanUserDomainAction = new KAction(kickBanMenu);
  359. kickBanUserDomainAction->setText(i18n("KickBan *!user@domain"));
  360.  
  361. kickBanMenu->addAction(kickUserAction);
  362. kickBanMenu->addAction(banNicknameAction);
  363. kickBanMenu->addAction(kickBanUserAction);
  364. kickBanMenu->addSeparator();
  365. kickBanMenu->addAction(banHostAction);
  366. kickBanMenu->addAction(banDomainAction);
  367. kickBanMenu->addAction(banUserHostAction);
  368. kickBanMenu->addAction(banUserDomainAction);
  369. kickBanMenu->addSeparator();
  370. kickBanMenu->addAction(kickBanHostAction);
  371. kickBanMenu->addAction(kickBanDomainAction);
  372. kickBanMenu->addAction(kickBanUserHostAction);
  373. kickBanMenu->addAction(kickBanUserDomainAction);
  374.  
  375. QModelIndex current = d->userList->currentIndex();
  376. if (current.isValid()) {
  377. ctx->addMenu(modesMenu);
  378. ctx->addMenu(kickBanMenu);
  379. ctx->exec(QCursor::pos());
  380. }
  381. }
  382.  
  383. void
  384. ChannelTab::slotGiveHalfOpTriggered()
  385. {
  386. NickListModel *model = static_cast<NickListModel*>(d->userList->model());
  387. Aki::Irc::User *user = model->data(d->userList->currentIndex(), NickListModel::IrcUserRole)
  388. .value<Aki::Irc::User*>();
  389. d->socket->rfcMode(name(), QString("+h %1").arg(user->nick()));
  390. }
  391.  
  392. void
  393. ChannelTab::slotGiveOpTriggered()
  394. {
  395. NickListModel *model = static_cast<NickListModel*>(d->userList->model());
  396. Aki::Irc::User *user = model->data(d->userList->currentIndex(), NickListModel::IrcUserRole)
  397. .value<Aki::Irc::User*>();
  398. d->socket->rfcMode(name(), QString("+o %1").arg(user->nick()));
  399. }
  400.  
  401. void
  402. ChannelTab::slotGiveVoiceTriggered()
  403. {
  404. NickListModel *model = static_cast<NickListModel*>(d->userList->model());
  405. Aki::Irc::User *user = model->data(d->userList->currentIndex(), NickListModel::IrcUserRole)
  406. .value<Aki::Irc::User*>();
  407. d->socket->rfcMode(name(), QString("+v %1").arg(user->nick()));
  408. }
  409.  
  410. void
  411. ChannelTab::slotKickUserTriggered()
  412. {
  413. NickListModel *model = static_cast<NickListModel*>(d->userList->model());
  414. Aki::Irc::User *user = model->data(d->userList->currentIndex(), NickListModel::IrcUserRole)
  415. .value<Aki::Irc::User*>();
  416. if (d->config->kickMessage().isEmpty()) {
  417. d->socket->rfcKick(name(), user->nick());
  418. } else {
  419. d->socket->rfcKick(name(), user->nick(), d->config->kickMessage());
  420. }
  421. }
  422.  
  423. void
  424. ChannelTab::slotNickIndexChanged(const QString &nick)
  425. {
  426. d->socket->rfcNick(nick.trimmed());
  427. d->channelInput->setFocus();
  428. }
  429.  
  430. void
  431. ChannelTab::slotOnChannelCreated(const QString &channel, const QString &time)
  432. {
  433. if (channel.toLower() == name()) {
  434. d->channelOutput->addChannelCreated(time);
  435. }
  436. }
  437.  
  438. void
  439. ChannelTab::slotOnChannelPrivilegesNeededError(const QString &channel, const QString &errorMessage)
  440. {
  441. if (channel.toLower() == name().toLower()) {
  442. d->channelOutput->addError(channel, errorMessage);
  443. }
  444. }
  445.  
  446. void
  447. ChannelTab::slotOnCtcpAction(const QString &from, const QString &to, const QString &message)
  448. {
  449. if (name() == to) {
  450. d->channelOutput->addCtcpAction(from, message);
  451.  
  452. if (!isCurrent()) {
  453. setTabColor(ChannelTab::NewData);
  454. }
  455. }
  456. }
  457.  
  458. void
  459. ChannelTab::slotOnEndOfWho(const QString &channel, const QString &message)
  460. {
  461. if (d->autoRequest.contains("WHO")) {
  462. d->channelOutput->addWho(channel, message);
  463. d->autoRequest.removeAt(d->autoRequest.indexOf("WHO"));
  464. return;
  465. }
  466.  
  467. if (channel.toLower() == name().toLower()) {
  468. d->whoTimer->stop();
  469. d->whoTimer->start(90000);
  470. }
  471. }
  472.  
  473. void
  474. ChannelTab::slotOnKick(const QString &channel, const QString &nick, const QString &message)
  475. {
  476. Q_UNUSED(message);
  477. if (name() == channel) {
  478. foreach (Aki::Irc::User *user, d->userList->users()) {
  479. if (user->nick() == nick) {
  480. d->userList->removeItem(user);
  481. }
  482. }
  483.  
  484. if (!isCurrent()) {
  485. if (nick == d->socket->currentNick()) {
  486. setTabColor(ChannelTab::Highlight);
  487. } else {
  488. setTabColor(ChannelTab::NewData);
  489. }
  490. }
  491. }
  492. }
  493.  
  494. void
  495. ChannelTab::slotOnMode(const QString &from, const QString &channel, const QString &mode, const QString &nick)
  496. {
  497. if (name().toLower() != channel.toLower()) {
  498. return;
  499. }
  500.  
  501. enum {
  502. None,
  503. Give,
  504. Take
  505. };
  506. int state = None;
  507.  
  508. QModelIndex index;
  509. Aki::Irc::User *user = 0;
  510.  
  511. for (int i = 0; i < d->userList->count(); ++i) {
  512. index = d->userList->model()->index(i, 0);
  513. user = d->userList->model()->data(index, NickListModel::IrcUserRole).value<Aki::Irc::User*>();
  514. if (user->nick() == nick) {
  515. break;
  516. }
  517. }
  518.  
  519. if (!user) {
  520. return;
  521. }
  522.  
  523. QString modes = user->modes();
  524. bool fromYou = (from == d->nickSelector->currentText());
  525. bool toYou = (nick == d->nickSelector->currentText());
  526.  
  527. foreach (QChar c, mode) {
  528. if (c == QChar('+')) {
  529. state = Give;
  530. } else if (c == QChar('-')) {
  531. state = Take;
  532. } else if (c == QChar('o')) {
  533. if (state == Give) {
  534. user->setModes(modes + c);
  535. d->userList->model()->setData(index,
  536. QVariant::fromValue<Aki::Irc::User*>(user),
  537. NickListModel::IrcUserRole);
  538. d->channelOutput->addMode(from, nick, c, toYou, fromYou);
  539. } else if (state == Take) {
  540. user->removeModes(c);
  541. d->userList->model()->setData(index,
  542. QVariant::fromValue<Aki::Irc::User*>(user),
  543. NickListModel::IrcUserRole);
  544. d->channelOutput->addRemoveMode(from, nick, c, toYou, fromYou);
  545. }
  546. } else if (c == QChar('v')) {
  547. if (state == Give) {
  548. user->setModes(modes + c);
  549. d->userList->model()->setData(index,
  550. QVariant::fromValue<Aki::Irc::User*>(user),
  551. NickListModel::IrcUserRole);
  552. d->channelOutput->addMode(from, nick, c, toYou, fromYou);
  553. } else if (state == Take) {
  554. user->removeModes(c);
  555. d->userList->model()->setData(index,
  556. QVariant::fromValue<Aki::Irc::User*>(user),
  557. NickListModel::IrcUserRole);
  558. d->channelOutput->addRemoveMode(from, nick, c, toYou, fromYou);
  559. }
  560. } else if (c == QChar('h')) {
  561. if (state == Give) {
  562. user->setModes(modes + c);
  563. d->userList->model()->setData(index,
  564. QVariant::fromValue<Aki::Irc::User*>(user),
  565. NickListModel::IrcUserRole);
  566. d->channelOutput->addMode(from, nick, c, toYou, fromYou);
  567. } else if (state == Take) {
  568. user->removeModes(c);
  569. d->userList->model()->setData(index,
  570. QVariant::fromValue<Aki::Irc::User*>(user),
  571. NickListModel::IrcUserRole);
  572. d->channelOutput->addRemoveMode(from, nick, c, toYou, fromYou);
  573. }
  574. }
  575. }
  576.  
  577. d->userList->update(index);
  578.  
  579. if (!isCurrent()) {
  580. setTabColor(ChannelTab::NewData);
  581. }
  582. }
  583.  
  584. void
  585. ChannelTab::slotOnModeUnknownFlagError(const QString &errorMessage)
  586. {
  587. if (isCurrent()) {
  588. d->channelOutput->addError(errorMessage);
  589. }
  590. }
  591.  
  592. void
  593. ChannelTab::slotOnMotd(const QString &message)
  594. {
  595. if (name().toLower() == d->socket->name().toLower()) {
  596. d->channelOutput->addMotd(Aki::Irc::Color::toHtml(message));
  597. }
  598. }
  599.  
  600. void
  601. ChannelTab::slotOnNameReply(const QString &channel, const QString &names)
  602. {
  603. if (name().toLower() == channel.toLower()) {
  604. QStringList tmp = names.split(QChar(' '), QString::SkipEmptyParts);
  605. QStringListIterator namesIter(tmp);
  606.  
  607. while (namesIter.hasNext()) {
  608. QString name = namesIter.next();
  609.  
  610. Aki::Irc::User *user = new Aki::Irc::User("", this);
  611.  
  612. switch (qrand() % 7) {
  613. case 0:
  614. user->setColor(Aki::Settings::userColor0());
  615. break;
  616. case 1:
  617. user->setColor(Aki::Settings::userColor1());
  618. break;
  619. case 2:
  620. user->setColor(Aki::Settings::userColor2());
  621. break;
  622. case 3:
  623. user->setColor(Aki::Settings::userColor3());
  624. break;
  625. case 4:
  626. user->setColor(Aki::Settings::userColor4());
  627. break;
  628. case 5:
  629. user->setColor(Aki::Settings::userColor5());
  630. break;
  631. case 6:
  632. user->setColor(Aki::Settings::userColor6());
  633. break;
  634. default:
  635. break;
  636. }
  637.  
  638. if (name.left(1) == QChar('@')) {
  639. user->setNick(name.remove(QChar('@')));
  640. user->setModes("+o");
  641. d->userList->addItem(user);
  642. } else if (name.left(1) == QChar('+')) {
  643. user->setNick(name.remove(QChar('+')));
  644. user->setModes("+v");
  645. d->userList->addItem(user);
  646. } else {
  647. user->setNick(name);
  648. d->userList->addItem(user);
  649. }
  650. }
  651. }
  652. }
  653.  
  654. void
  655. ChannelTab::slotOnNick(const QString &oldNick, const QString &newNick)
  656. {
  657. foreach (Aki::Irc::User *user, d->userList->users()) {
  658. if (user->nick() == oldNick) {
  659. if (oldNick == d->socket->currentNick() ||
  660. newNick == d->socket->currentNick()) {
  661. d->socket->appendNick(newNick);
  662. d->socket->setCurrentNick(newNick);
  663. if (!d->nickSelector->contains(newNick)) {
  664. d->nickSelector->addItem(newNick);
  665. }
  666.  
  667. int index = d->nickSelector->findText(newNick, Qt::MatchExactly);
  668. d->nickSelector->setCurrentIndex(index);
  669. }
  670.  
  671. int index = d->userList->users().indexOf(user);
  672. user->setNick(newNick);
  673. d->userList->users().replace(index, user);
  674. d->channelOutput->addNick(oldNick, newNick);
  675. return;
  676. }
  677. }
  678.  
  679. if (name() == d->socket->name() &&
  680. (oldNick == d->socket->currentNick() ||
  681. newNick == d->socket->currentNick())) {
  682. if (!d->nickSelector->contains(newNick)) {
  683. d->nickSelector->addItem(newNick);
  684. }
  685. int index = d->nickSelector->findText(newNick, Qt::MatchExactly);
  686. d->nickSelector->setCurrentIndex(index);
  687. d->channelOutput->addNick(oldNick, newNick);
  688. }
  689. }
  690.  
  691. void
  692. ChannelTab::slotOnNicknameInUseError(const QString &attemptedNickname, const QString &errorMessage)
  693. {
  694. const int currentIndex = d->nickSelector->currentIndex();
  695. const int count = d->nickSelector->count();
  696.  
  697. if (currentIndex == (count - 1)) {
  698. return;
  699. }
  700.  
  701. d->nickSelector->setCurrentIndex(currentIndex + 1);
  702. const QString currentNick = d->nickSelector->currentText();
  703.  
  704. d->socket->setCurrentNick(currentNick);
  705. d->socket->rfcNick(currentNick);
  706.  
  707. if (isCurrent()) {
  708. d->channelOutput->append(QString("<span style='color: %1;'>** %2 :%3</span>")
  709. .arg(Aki::Settings::errorColor().name(), attemptedNickname, errorMessage));
  710. }
  711. }
  712.  
  713. void
  714. ChannelTab::slotOnNotice(const QString &message)
  715. {
  716. if (name().toLower() == d->socket->name().toLower()) {
  717. d->channelOutput->addNotice(Aki::Irc::Color::toHtml(message));
  718.  
  719. if (!isCurrent()) {
  720. setTabColor(ChannelTab::NewData);
  721. }
  722. }
  723. }
  724.  
  725. void
  726. ChannelTab::slotOnNotice(const QString &from, const QString &message)
  727. {
  728. if (name().toLower() == d->socket->name().toLower()) {
  729. d->channelOutput->addNotice(from, Aki::Irc::Color::toHtml(message));
  730.  
  731. QString nick = Aki::Irc::Rfc2812::nickFromMask(from);
  732. if (Aki::Irc::Rfc2812::isValidNickname(nick)) {
  733. if (nick == "NickServ" && message.contains("This nickname is registered", Qt::CaseInsensitive)) {
  734. if (d->socket->serviceName().toLower().trimmed() == "nickserv" &&
  735. !d->socket->servicePassword().isEmpty() && d->socket->isAutoIdentifyEnabled()) {
  736. d->socket->rfcPrivmsg("NickServ", QString("identify %1").arg(d->socket->servicePassword()));
  737. }
  738. } else {
  739. // TODO: This should be filled with other nick services. But I don't know what others there
  740. // are so if anyone know send patch or me a list.
  741. }
  742. }
  743. }
  744. }
  745.  
  746. void
  747. ChannelTab::slotOnNoticeAuth(const QString &message)
  748. {
  749. if (name().toLower() == d->socket->name().toLower()) {
  750. d->channelOutput->addNoticeAuth(Aki::Irc::Color::toHtml(message));
  751. }
  752. }
  753.  
  754. void
  755. ChannelTab::slotOnNoticeCtcpVersion(const QString &from, const QString &version)
  756. {
  757. if (isCurrent()) {
  758. d->channelOutput->addCtcp(from, Aki::Irc::Color::toHtml(version));
  759. }
  760. }
  761.  
  762. void
  763. ChannelTab::slotOnPrivmsg(const QString &channel, const QString &from, const QString &to,
  764. const QString &message)
  765. {
  766. if (channel.toLower() == name().toLower()) {
  767. foreach (Aki::Irc::User *user, d->userList->users()) {
  768. if (user->nick() == from) {
  769. QString matchString = "\\s*" + d->socket->currentNick() + ":*\\s*";
  770. if (message.contains(QRegExp(matchString))) {
  771. QString colour =
  772. QString("<font color='%1'>%2</font>").arg(
  773. user->color().name(), user->nick());
  774. d->channelOutput->addPrivmsgHighlight(colour, Aki::Irc::Color::toHtml(message));
  775.  
  776. if (!isCurrent()) {
  777. setTabColor(ChannelTab::Highlight);
  778. }
  779. } else {
  780. QString colour =
  781. QString("<font color='%1'>%2</font>").arg(
  782. user->color().name(), user->nick());
  783. d->channelOutput->addPrivmsg(colour, Aki::Irc::Color::toHtml(message));
  784.  
  785. if (!isCurrent()) {
  786. setTabColor(ChannelTab::NewMessage);
  787. }
  788. }
  789. return;
  790. }
  791. }
  792. } else if(to == d->socket->currentNick()) {
  793. #ifdef Q_CC_GNU
  794. #warning "Add support for Private messaging"
  795. #endif
  796. Q_UNUSED(from);
  797. }
  798. }
  799.  
  800. void
  801. ChannelTab::slotOnRawMessage(const QString &message)
  802. {
  803. if (name().toLower() == d->socket->name().toLower()) {
  804. MessageLog::self()->addMessage(true, QString(), message);
  805. }
  806. }
  807.  
  808. void
  809. ChannelTab::slotOnSupport(const QString &message)
  810. {
  811. if (name().toLower() == d->socket->name().toLower()) {
  812. d->channelOutput->addSupport(Aki::Irc::Color::toHtml(message));
  813. }
  814. }
  815.  
  816. void
  817. ChannelTab::slotOnTopic(const QString &channel, const QString &topic)
  818. {
  819. if (channel.toLower() == name().toLower()) {
  820. d->channelOutput->addTopic(Aki::Irc::Color::toHtml(topic));
  821. d->topic->setText(topic);
  822. }
  823. }
  824.  
  825. void
  826. ChannelTab::slotOnTopicSetBy(const QString &nick, const QString &channel,
  827. const QString &time)
  828. {
  829. if (channel.toLower() == name()) {
  830. d->channelOutput->addTopicSetBy(nick, time);
  831. }
  832. }
  833.  
  834. void
  835. ChannelTab::slotOnUserJoin(const QString &hostMask, const QString &channel)
  836. {
  837. if (channel.toLower() == name().toLower()) {
  838. QString nick = Aki::Irc::Rfc2812::nickFromMask(hostMask);
  839. QString user = Aki::Irc::Rfc2812::userFromMask(hostMask);
  840. QString host = Aki::Irc::Rfc2812::hostFromMask(hostMask);
  841.  
  842. d->channelOutput->addUserJoin(channel, nick, user + QChar('@') + host);
  843.  
  844. Aki::Irc::User *ircUser = new Aki::Irc::User(hostMask, this);
  845. d->userList->addItem(ircUser);
  846. }
  847. }
  848.  
  849. void
  850. ChannelTab::slotOnUserPart(const QString &hostMask, const QString &channel,
  851. const QString &partMessage)
  852. {
  853. if (channel.toLower() == name().toLower()) {
  854. QString nick = Aki::Irc::Rfc2812::nickFromMask(hostMask);
  855. QString userMask = Aki::Irc::Rfc2812::userFromMask(hostMask);
  856. QString host = Aki::Irc::Rfc2812::hostFromMask(hostMask);
  857.  
  858. QModelIndex index;
  859. Aki::Irc::User *user = 0;
  860.  
  861. for (int i = 0; i < d->userList->count(); ++i) {
  862. index = d->userList->model()->index(i, 0);
  863. user = d->userList->model()->data(index, NickListModel::IrcUserRole).value<Aki::Irc::User*>();
  864. if (user->nick() == nick) {
  865. break;
  866. }
  867. }
  868.  
  869. if (!user) {
  870. return;
  871. }
  872.  
  873. d->userList->removeItem(user);
  874. d->channelOutput->addUserPart(channel, nick, userMask + QChar('@') + host, partMessage);
  875. }
  876. }
  877.  
  878. void
  879. ChannelTab::slotOnUserQuit(const QString &hostMask, const QString &quitMessage)
  880. {
  881. QString nick = Aki::Irc::Rfc2812::nickFromMask(hostMask);
  882. QString userMask = Aki::Irc::Rfc2812::userFromMask(hostMask);
  883. QString host = Aki::Irc::Rfc2812::hostFromMask(hostMask);
  884.  
  885. QModelIndex index;
  886. Aki::Irc::User *user = 0;
  887.  
  888. for (int i = 0; i < d->userList->count(); ++i) {
  889. index = d->userList->model()->index(i, 0);
  890. user = d->userList->model()->data(index, NickListModel::IrcUserRole).value<Aki::Irc::User*>();
  891. if (user->nick() == nick) {
  892. break;
  893. }
  894. }
  895.  
  896. if (!user) {
  897. return;
  898. }
  899.  
  900. d->userList->removeItem(user);
  901. d->channelOutput->addUserQuit(nick, userMask + QChar('@') + host, quitMessage);
  902. }
  903.  
  904. void
  905. ChannelTab::slotOnUsersDontMatchError(const QString &errorMessage)
  906. {
  907. if (isCurrent()) {
  908. d->channelOutput->addError(errorMessage);
  909. }
  910. }
  911.  
  912. void
  913. ChannelTab::slotOnWelcome(const QString &message)
  914. {
  915. if (name().toLower() == d->socket->name().toLower()) {
  916. d->channelOutput->addWelcome(Aki::Irc::Color::toHtml(message));
  917. }
  918. }
  919.  
  920. void
  921. ChannelTab::slotOnWho(const QString &channel, const QString &userName, const QString &address,
  922. const QString &server, const QString &nick, const QString &flags, int hops,
  923. const QString &realName)
  924. {
  925. if (d->autoRequest.contains("WHO")) {
  926. d->channelOutput->addWho(channel, userName, address, server, nick, flags, hops, realName);
  927. return;
  928. }
  929.  
  930. if (d->userList->count() == 0) {
  931. return;
  932. }
  933.  
  934. if (channel.toLower() != name().toLower()) {
  935. return;
  936. }
  937.  
  938. d->whoWaiting = false;
  939.  
  940. QModelIndex index;
  941. Aki::Irc::User *user = 0;
  942.  
  943. QAbstractItemModel *model = d->userList->model();
  944.  
  945. for (int i = 0; i < d->userList->count(); ++i) {
  946. index = model->index(i, 0);
  947. user = model->data(index, NickListModel::IrcUserRole).value<Aki::Irc::User*>();
  948.  
  949. if (user->nick() == nick) {
  950. break;
  951. }
  952. }
  953.  
  954. /*for (int i = 0; i < d->userList->count(); ++i) {
  955. index = d->userList->model()->index(i, 0);
  956. user = d->userList->model()->data(index, NickListModel::IrcUserRole).value<Aki::Irc::User*>();
  957. if (user->nick() == nick) {
  958. break;
  959. }
  960. }*/
  961.  
  962. user->setUser(userName);
  963. user->setNick(nick);
  964. user->setHost(address);
  965. user->setRealName(realName);
  966.  
  967. foreach (QChar c, flags) {
  968. if (c == QChar('@')) {
  969. if (!user->containsMode(QChar('o'))) {
  970. user->setModes(user->modes() + QChar('o'));
  971. }
  972. } else if (c == QChar('+')) {
  973. if (!user->containsMode(QChar('+'))) {
  974. user->setModes(user->modes() + QChar('v'));
  975. }
  976. } else if (c == QChar('H')) {
  977. user->setAway(false);
  978. } else if (c == QChar('G')) {
  979. user->setAway(true);
  980. } else {
  981. kDebug() << "Unsupported flag: " << c;
  982. }
  983. }
  984.  
  985. model->setData(index, QVariant::fromValue<Aki::Irc::User*>(user), NickListModel::IrcUserRole);
  986. }
  987.  
  988. void
  989. ChannelTab::slotPerformJoin()
  990. {
  991. if (d->socket->isAutoJoinChannelsEnabled()) {
  992. QStringList chans;
  993. QStringListIterator chanIter(d->socket->channelList());
  994.  
  995. while (chanIter.hasNext()) {
  996. QString channel = chanIter.next();
  997. chans << channel;
  998. }
  999. d->socket->rfcJoin(chans);
  1000. }
  1001. }
  1002.  
  1003. void
  1004. ChannelTab::slotPerformWho()
  1005. {
  1006. if (d->whoWaiting) {
  1007. d->whoTimer->stop();
  1008. d->whoTimer->start(90000);
  1009. return;
  1010. }
  1011.  
  1012. kDebug() << KDateTime::currentLocalTime() << " Who: " << name();
  1013. d->socket->rfcWho(name());
  1014. d->whoTimer->start(90000);
  1015. d->whoWaiting = true;
  1016. }
  1017.  
  1018. void
  1019. ChannelTab::slotShowCompletion()
  1020. {
  1021. if (d->channelInput->text().isEmpty()) {
  1022. return;
  1023. }
  1024.  
  1025. int oldPosition;
  1026. int position;
  1027.  
  1028. QString line = d->channelInput->text();
  1029. oldPosition = position = line.length();
  1030.  
  1031. QString attemptedNick;
  1032.  
  1033. while (position && line[position - 1] != ' ') {
  1034. position--;
  1035. }
  1036.  
  1037. attemptedNick = line.mid(position, oldPosition + position);
  1038.  
  1039. QStringList list;
  1040.  
  1041. foreach (Aki::Irc::User *user, d->userList->users()) {
  1042. if (attemptedNick.isEmpty() || user->nick().startsWith(attemptedNick)) {
  1043. list << user->nick();
  1044. }
  1045. }
  1046.  
  1047. qSort(list);
  1048. d->channelInput->setNickCompletionList(list);
  1049. }
  1050.  
  1051. void
  1052. ChannelTab::slotTakeHalfOpTriggered()
  1053. {
  1054. NickListModel *model = static_cast<NickListModel*>(d->userList->model());
  1055. Aki::Irc::User *user = model->data(d->userList->currentIndex(), NickListModel::IrcUserRole)
  1056. .value<Aki::Irc::User*>();
  1057. d->socket->rfcMode(name(), QString("-h %1").arg(user->nick()));
  1058. }
  1059.  
  1060. void
  1061. ChannelTab::slotTakeOpTriggered()
  1062. {
  1063. NickListModel *model = static_cast<NickListModel*>(d->userList->model());
  1064. Aki::Irc::User *user = model->data(d->userList->currentIndex(), NickListModel::IrcUserRole)
  1065. .value<Aki::Irc::User*>();
  1066. d->socket->rfcMode(name(), QString("-o %1").arg(user->nick()));
  1067. }
  1068.  
  1069. void
  1070. ChannelTab::slotTakeVoiceTriggered()
  1071. {
  1072. NickListModel *model = static_cast<NickListModel*>(d->userList->model());
  1073. Aki::Irc::User *user = model->data(d->userList->currentIndex(), NickListModel::IrcUserRole)
  1074. .value<Aki::Irc::User*>();
  1075. d->socket->rfcMode(name(), QString("-v %1").arg(user->nick()));
  1076. }
  1077.  
  1078. void
  1079. ChannelTab::slotTextSubmitted()
  1080. {
  1081. QString text = d->channelInput->text();
  1082. d->channelInput->clear();
  1083.  
  1084. if (text.startsWith(QChar('/'))) {
  1085. text.remove(0, 1);
  1086.  
  1087. QString command = text.mid(0, text.indexOf(QChar(' '))).toLower();
  1088. text.remove(0, command.length() + 1);
  1089.  
  1090. if (command == QChar('j') || command == "join") {
  1091. QString channel = text.mid(0, text.indexOf(QChar(' ')));
  1092. channel = channel.trimmed();
  1093. if (Aki::Irc::Rfc2812::isValidChannel(channel)) {
  1094. d->socket->rfcJoin(channel);
  1095. }
  1096. } else if (command == "clear") {
  1097. d->channelOutput->clear();
  1098. } else if (command == "invite") {
  1099. QString nick = text.mid(0, text.indexOf(QChar(' ')));
  1100. text.remove(0, nick.length() + 1);
  1101. QString channel = text.trimmed();
  1102. d->socket->rfcInvite(nick, channel);
  1103. } else if (command == "ns" || command == "nickserv") {
  1104. d->socket->rfcPrivmsg("nickserv", text);
  1105. } else if (command == "ghost") {
  1106. QString nick = text.mid(0, text.indexOf(QChar(' ')));
  1107. text.remove(0, nick.length() + 1);
  1108. QString password = text.trimmed();
  1109. d->socket->rfcPrivmsg("nickserv", "GHOST " + nick + ' ' + password);
  1110. } else if (command == "nick") {
  1111. if (!text.isEmpty()) {
  1112. if (text.contains(QChar(' '))) {
  1113. // TODO : Fix ChatView to handle errors.
  1114. } else {
  1115. if (Aki::Irc::Rfc2812::isValidNickname(text.trimmed())) {
  1116. d->socket->rfcNick(text.trimmed());
  1117. } else {
  1118. // TODO: Fix ChatView to handle errors.
  1119. }
  1120. }
  1121. } else {
  1122. // TODO : Fix ChatView to handle errors.
  1123. }
  1124. } else if (command == "me") {
  1125. if (!text.isEmpty()) {
  1126. d->socket->rfcCtcpAction(name(), text);
  1127. d->channelOutput->addCtcpAction(d->nickSelector->currentText(), text);
  1128. } else {
  1129. // TODO : Fix ChatView to handle errors.
  1130. }
  1131. } else if (command == "cs" || command == "chanserv") {
  1132. d->socket->rfcPrivmsg("chanserv", text);
  1133. } else if (command == "mode") {
  1134. if (Aki::Irc::Rfc2812::isValidChannel(name())) {
  1135. QString mode = text.mid(0, text.indexOf(QChar(' ')));
  1136. text.remove(0, mode.length() + 1);
  1137.  
  1138. if (Aki::Irc::Rfc2812::isValidNickname(text)) {
  1139. d->socket->rfcMode(name(), QString("%1 %2").arg(mode, text));
  1140. } else {
  1141. // TODO: Fix ChatView to handle errors.
  1142. }
  1143. } else {
  1144. // TODO: Fix ChatView to handle errors.
  1145. }
  1146. } else if (command == "kick") {
  1147. if (Aki::Irc::Rfc2812::isValidChannel(name())) {
  1148. QString nick = text.mid(0, text.indexOf(QChar(' ')));
  1149. if (Aki::Irc::Rfc2812::isValidNickname(nick)) {
  1150. text.remove(0, nick.length() + 1);
  1151.  
  1152. if (!text.isEmpty()) {
  1153. d->socket->rfcKick(name(), nick, text);
  1154. } else {
  1155. if (!d->config->kickMessage().isEmpty()) {
  1156. d->socket->rfcKick(name(), nick, d->config->kickMessage());
  1157. } else {
  1158. d->socket->rfcKick(name(), nick);
  1159. }
  1160. }
  1161. } else {
  1162. // TODO: Fix the ChatView to handle error messages.
  1163. }
  1164. } else {
  1165. // TODO: Fix the ChatView to handle error messages.
  1166. }
  1167. } else if (command == "ban") {
  1168. } else if (command == "ctcp") {
  1169. if (!text.isEmpty()) {
  1170. QString nick = text.mid(0, text.indexOf(QChar(' ')));
  1171. if (Aki::Irc::Rfc2812::isValidNickname(nick)) {
  1172. text.remove(0, nick.length() + 1);
  1173. if (!text.isEmpty()) {
  1174. d->socket->rfcPrivmsg(nick, QString("\x01%1\x01").arg(text.trimmed()));
  1175. } else {
  1176. // TODO: Fix the ChatView to handle error messages.
  1177. }
  1178. } else {
  1179. // TODO: Fix the ChatView to handle error messages.
  1180. }
  1181. } else {
  1182. // TODO: Fix the ChatView to handle error messages.
  1183. }
  1184. } else if (command == "umode") {
  1185. if (!text.isEmpty()) {
  1186. QString nickname = text.mid(0, text.indexOf(QChar(' ')));
  1187. if (Aki::Irc::Rfc2812::isValidNickname(nickname)) {
  1188. text.remove(0, nickname.length() + 1);
  1189.  
  1190. if (text.isEmpty()) {
  1191. d->socket->rfcMode(nickname);
  1192. } else {
  1193. d->socket->rfcMode(nickname, text.trimmed());
  1194. }
  1195. } else {
  1196. d->socket->rfcMode(d->socket->currentNick(), text.trimmed());
  1197. }
  1198. } else {
  1199. // TODO: Fix the ChatView to handle error messages.
  1200. }
  1201. } else if (command == "who") {
  1202. if (!text.trimmed().isEmpty()) {
  1203. QString channel = text.mid(0, text.indexOf(QChar(' ')));
  1204. if (Aki::Irc::Rfc2812::isValidChannel(channel)) {
  1205. d->socket->rfcWho(channel);
  1206. d->autoRequest << "WHO";
  1207. } else {
  1208.  
  1209. }
  1210. } else {
  1211. d->socket->rfcWho(name());
  1212. }
  1213. }
  1214. } else {
  1215. foreach (Aki::Irc::User *user, d->userList->users()) {
  1216. if (user->nick() == d->socket->currentNick()) {
  1217. QString colour =
  1218. QString("<font color=\"%1\">%2</font>").arg(user->color().name(), user->nick());
  1219. d->channelOutput->addPrivmsg(colour, Aki::Irc::Color::toHtml(text));
  1220. d->socket->rfcPrivmsg(name(), text);
  1221. return;
  1222. }
  1223. }
  1224. }
  1225. }
  1226.  
  1227. ChannelView*
  1228. ChannelTab::view()
  1229. {
  1230. return d->view;
  1231. }
Add Comment
Please, Sign In to add comment