ircchatadapter.cpp
1 //------------------------------------------------------------------------------
2 // ircchatadapter.cpp
3 //------------------------------------------------------------------------------
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9 //
10 // This program 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
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; 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 != NULL)
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  // If network is null and we can still send messages this might be a bug
49  // in the application.
50  if (pNetwork == NULL)
51  {
52  emit error("This chat window is not attached to any network. This is probably a bug in Doomseeker.");
53  return;
54  }
55 
56  // Trim whitespaces to make sure the '/' character gets detected properly.
57  QString messageTrimmed = message.trimmed();
58 
59  if (messageTrimmed.startsWith("/"))
60  {
61  // This is a IRC comand. Send it as is to the network.
62  pNetwork->doSendMessage(messageTrimmed, this);
63  }
64  else
65  {
66  // This is a chat message. We need to process this before
67  // sending.
68  sendChatMessage(messageTrimmed);
69  }
70 }
71 
72 void IRCChatAdapter::emitChatMessage(const QString& sender, const QString& content)
73 {
74  emit message(QString("<%1>: %2").arg(sender, content));
75 }
76 
77 QString IRCChatAdapter::extractMessageLine(QStringList& words, int maxLength)
78 {
79  QByteArray sentence = "";
80  while(!words.isEmpty())
81  {
82  QByteArray word = words.takeFirst().toUtf8();
83 
84  // Remember to add the spacebar into the equation.
85  if (sentence.length() + word.length() + 1 > maxLength)
86  {
87  // If there is no valid way of splitting the sentence; if
88  // the word itself is longer than maxLength we have to split
89  // the word. Dash will be appened to the end of such word.
90  if (sentence.isEmpty())
91  {
92  // We need to split the word.
93  QList<QByteArray> splitWordTokens = Utf8Splitter().split(word, maxLength);
94 
95  sentence = splitWordTokens.takeFirst();
96  sentence += '-';
97 
98  QString wordRemainder = "";
99  foreach (const QByteArray &wordToken, splitWordTokens)
100  {
101  wordRemainder += QString::fromUtf8(wordToken.constData(), wordToken.size());
102  }
103  words.prepend(wordRemainder);
104  }
105  else
106  {
107  // Put the word back on the list, we'll come back to it
108  // in the next line of the message.
109  words.prepend(QString::fromUtf8(word.constData(), word.size()));
110  }
111 
112  break;
113  }
114 
115  sentence += word + " ";
116  }
117  return QString::fromUtf8(sentence.constData(), sentence.size()).trimmed();
118 }
119 
120 void IRCChatAdapter::sendChatMessage(const QString& message)
121 {
122  // Here we will split too long messages to make sure they don't
123  // exceed the 512 character limit as stated in RFC 1459.
124 
125  // NOTE: Messages are echoed back through IRCRequestParser
126 
127  QString ircCall = QString("/PRIVMSG %1 ").arg(recipientName);
128  int maxLength = IRCClient::SAFE_MESSAGE_LENGTH - ircCall.toUtf8().length();
129  QStringList wordLines = message.split("\n");
130 
131  foreach(QString line, wordLines)
132  {
133  QStringList words = line.split(" ");
134 
135  while (!words.isEmpty())
136  {
137  QString sentence = extractMessageLine(words, maxLength);
138  pNetwork->doSendMessage(ircCall + sentence, this);
139  }
140  }
141 }
142 
144 {
145  this->pNetwork = pNetwork;
146 }
147 
148 void IRCChatAdapter::setRecipient(const QString& name)
149 {
150  this->recipientName = name;
151  emit titleChange();
152 }
153 
154 QString IRCChatAdapter::title() const
155 {
156  return recipientName;
157 }
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.
void doSendMessage(const QString &message, IRCAdapterBase *pOrigin)
Implemented to support direct communication between client and server.
virtual void emitChatMessage(const QString &sender, const QString &content)
Emits message() signal formatting it to present sender&#39;s message.
void titleChange()
Can be called when the variable returned by title() might have changed and the application should be ...
QString title() const
For chat adapters this will return recipientName.
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)
Splits valid arrays of UTF-8 characters into smaller arrays without splitting in-between chars...
Definition: utf8splitter.h:33