ircchatadapter.cpp
1 //------------------------------------------------------------------------------
2 // ircchatadapter.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 "ircchatadapter.h"
24 
25 #include "irc/ircnetworkadapter.h"
26 #include "utf8splitter.h"
27 
28 IRCChatAdapter::IRCChatAdapter(IRCNetworkAdapter *pNetwork, const QString &recipient)
29 {
30  this->pNetwork = pNetwork;
31  this->recipientName = recipient;
32 }
33 
34 IRCChatAdapter::~IRCChatAdapter()
35 {
36  if (this->pNetwork != nullptr)
37  {
38  // Prevent the situation where this->pNetwork is
39  // NULLified while we still may need it.
40  IRCNetworkAdapter *pTmpNetwork = this->pNetwork;
41 
42  pTmpNetwork->detachChatWindow(this);
43  }
44 }
45 
46 void IRCChatAdapter::doSendMessage(const QString &message, IRCAdapterBase *pOrigin)
47 {
48  Q_UNUSED(pOrigin);
49  // If network is null and we can still send messages this might be a bug
50  // in the application.
51  if (pNetwork == nullptr)
52  {
53  emit error("This chat window is not attached to any network. This is probably a bug in Doomseeker.");
54  return;
55  }
56 
57  // Trim whitespaces to make sure the '/' character gets detected properly.
58  QString messageTrimmed = message.trimmed();
59 
60  if (messageTrimmed.startsWith("/"))
61  {
62  // This is a IRC comand. Send it as is to the network.
63  pNetwork->doSendMessage(messageTrimmed, this);
64  }
65  else
66  {
67  // This is a chat message. We need to process this before
68  // sending.
69  sendChatMessage(messageTrimmed);
70  }
71 }
72 
73 void IRCChatAdapter::emitChatMessage(const QString &sender, const QString &content)
74 {
75  emit message(QString("<%1>: %2").arg(sender, content));
76 }
77 
78 QString IRCChatAdapter::extractMessageLine(QStringList &words, int maxLength)
79 {
80  QByteArray sentence = "";
81  while (!words.isEmpty())
82  {
83  QByteArray word = words.takeFirst().toUtf8();
84 
85  // Remember to add the spacebar into the equation.
86  if (sentence.length() + word.length() + 1 > maxLength)
87  {
88  // If there is no valid way of splitting the sentence; if
89  // the word itself is longer than maxLength we have to split
90  // the word. Dash will be appended to the end of such word.
91  if (sentence.isEmpty())
92  {
93  // We need to split the word.
94  QList<QByteArray> splitWordTokens = Utf8Splitter().split(word, maxLength);
95 
96  sentence = splitWordTokens.takeFirst();
97  sentence += '-';
98 
99  QString wordRemainder = "";
100  for (const QByteArray &wordToken : splitWordTokens)
101  {
102  wordRemainder += QString::fromUtf8(wordToken.constData(), wordToken.size());
103  }
104  words.prepend(wordRemainder);
105  }
106  else
107  {
108  // Put the word back on the list, we'll come back to it
109  // in the next line of the message.
110  words.prepend(QString::fromUtf8(word.constData(), word.size()));
111  }
112 
113  break;
114  }
115 
116  sentence += word + " ";
117  }
118  return QString::fromUtf8(sentence.constData(), sentence.size()).trimmed();
119 }
120 
121 void IRCChatAdapter::sendChatMessage(const QString &message)
122 {
123  // Here we will split too long messages to make sure they don't
124  // exceed the 512 character limit as stated in RFC 1459.
125 
126  // NOTE: Messages are echoed back through IRCRequestParser
127 
128  QString ircCall = QString("/PRIVMSG %1 ").arg(recipientName);
129  int maxLength = IRCClient::SAFE_MESSAGE_LENGTH - ircCall.toUtf8().length();
130  QStringList wordLines = message.split("\n");
131 
132  for (QString line : wordLines)
133  {
134  QStringList words = line.split(" ");
135 
136  while (!words.isEmpty())
137  {
138  QString sentence = extractMessageLine(words, maxLength);
139  pNetwork->doSendMessage(ircCall + sentence, this);
140  }
141  }
142 }
143 
145 {
146  this->pNetwork = pNetwork;
147 }
148 
149 void IRCChatAdapter::setRecipient(const QString &name)
150 {
151  this->recipientName = name;
152  emit titleChange();
153 }
154 
155 QString IRCChatAdapter::title() const
156 {
157  return recipientName;
158 }
Interprets communication between the client and the IRC server.
void setNetwork(IRCNetworkAdapter *pNetwork)
Sets IRCNetworkAdapter for this chat window. This adapter is not detached from the old network...
Provides an unified communication interface between a client and IRC network entities.
virtual void emitChatMessage(const QString &sender, const QString &content)
Emits message() signal formatting it to present sender&#39;s message.
QString title() const override
For chat adapters this will return recipientName.
void doSendMessage(const QString &message, IRCAdapterBase *pOrigin) override
Implemented to support direct communication between client and server.
void titleChange()
Can be called when the variable returned by title() might have changed and the application should be ...
IRCChatAdapter(IRCNetworkAdapter *pNetwork, const QString &recipient)
void detachChatWindow(const IRCChatAdapter *pAdapter)
Detaches the specified IRCChatAdapter instance from this network without deleting it...
QString extractMessageLine(QStringList &words, int maxLength)
void doSendMessage(const QString &message, IRCAdapterBase *pOrigin) override
Splits valid arrays of UTF-8 characters into smaller arrays without splitting in-between chars...
Definition: utf8splitter.h:33