15 * You should have received a copy of the GNU General Public License |
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 |
16 * along with this program; if not, write to the Free Software |
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
18 */ |
18 */ |
19 |
19 |
|
20 #include <QDesktopServices> |
20 #include <QTextBrowser> |
21 #include <QTextBrowser> |
21 #include <QLineEdit> |
22 #include <QLineEdit> |
22 #include <QAction> |
23 #include <QAction> |
23 #include <QApplication> |
24 #include <QApplication> |
24 #include <QTextDocument> |
25 #include <QTextDocument> |
25 #include <QDir> |
26 #include <QDir> |
26 #include <QSettings> |
27 #include <QSettings> |
27 #include <QFile> |
28 #include <QFile> |
28 #include <QTextStream> |
29 #include <QTextStream> |
|
30 #include <QMenu> |
|
31 #include <QCursor> |
29 #include <QScrollBar> |
32 #include <QScrollBar> |
|
33 #include <QItemSelectionModel> |
30 |
34 |
31 #include "hwconsts.h" |
35 #include "hwconsts.h" |
32 #include "SDLs.h" |
36 #include "SDLs.h" |
33 #include "gameuiconfig.h" |
37 #include "gameuiconfig.h" |
34 #include "chatwidget.h" |
38 #include "chatwidget.h" |
122 connect(chatEditLine, SIGNAL(returnPressed()), this, SLOT(returnPressed())); |
128 connect(chatEditLine, SIGNAL(returnPressed()), this, SLOT(returnPressed())); |
123 |
129 |
124 mainLayout.addWidget(chatEditLine, 1, 0); |
130 mainLayout.addWidget(chatEditLine, 1, 0); |
125 |
131 |
126 chatText = new QTextBrowser(this); |
132 chatText = new QTextBrowser(this); |
|
133 chatText->document()->setDefaultStyleSheet(STYLE); |
127 chatText->setMinimumHeight(20); |
134 chatText->setMinimumHeight(20); |
128 chatText->setMinimumWidth(10); |
135 chatText->setMinimumWidth(10); |
129 chatText->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); |
136 chatText->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); |
130 chatText->setOpenExternalLinks(true); |
137 chatText->setOpenLinks(false); |
|
138 connect(chatText, SIGNAL(anchorClicked(const QUrl&)), |
|
139 this, SLOT(linkClicked(const QUrl&))); |
131 mainLayout.addWidget(chatText, 0, 0); |
140 mainLayout.addWidget(chatText, 0, 0); |
132 |
141 |
133 chatNicks = new QListWidget(this); |
142 chatNicks = new QListWidget(this); |
134 chatNicks->setMinimumHeight(10); |
143 chatNicks->setMinimumHeight(10); |
135 chatNicks->setMinimumWidth(10); |
144 chatNicks->setMinimumWidth(10); |
168 |
177 |
169 showReady = false; |
178 showReady = false; |
170 setShowFollow(true); |
179 setShowFollow(true); |
171 } |
180 } |
172 |
181 |
|
182 void HWChatWidget::linkClicked(const QUrl & link) |
|
183 { |
|
184 if (link.scheme() == "http") |
|
185 QDesktopServices::openUrl(link); |
|
186 if (link.scheme() == "hwnick") |
|
187 { |
|
188 // decode nick |
|
189 const QString& nick = QString::fromUtf8(QByteArray::fromBase64(link.encodedQuery())); |
|
190 QList<QListWidgetItem *> items = chatNicks->findItems(nick, Qt::MatchExactly); |
|
191 if (items.size() < 1) |
|
192 return; |
|
193 QMenu * popup = new QMenu(); |
|
194 // selecting an item will automatically scroll there, so let's save old position |
|
195 QScrollBar * scrollBar = chatNicks->verticalScrollBar(); |
|
196 int oldScrollPos = scrollBar->sliderPosition(); |
|
197 // select the nick which we want to see the actions for |
|
198 chatNicks->setCurrentItem(items[0], QItemSelectionModel::Clear); |
|
199 // selecting an item will automatically scroll there, so let's save old position |
|
200 scrollBar->setSliderPosition(oldScrollPos); |
|
201 // load actions |
|
202 popup->addActions(chatNicks->actions()); |
|
203 // display menu popup at mouse cursor position |
|
204 popup->popup(QCursor::pos()); |
|
205 } |
|
206 } |
|
207 |
173 void HWChatWidget::setShowFollow(bool enabled) |
208 void HWChatWidget::setShowFollow(bool enabled) |
174 { |
209 { |
175 if (enabled) { |
210 if (enabled) { |
176 if (!(chatNicks->actions().contains(acFollow))) |
211 if (!(chatNicks->actions().contains(acFollow))) |
177 chatNicks->insertAction(acFriend, acFollow); |
212 chatNicks->insertAction(acFriend, acFollow); |
267 { |
302 { |
268 emit chatLine(chatEditLine->text()); |
303 emit chatLine(chatEditLine->text()); |
269 chatEditLine->clear(); |
304 chatEditLine->clear(); |
270 } |
305 } |
271 |
306 |
|
307 |
272 void HWChatWidget::onChatString(const QString& str) |
308 void HWChatWidget::onChatString(const QString& str) |
273 { |
309 { |
|
310 onChatString("", str); |
|
311 } |
|
312 |
|
313 void HWChatWidget::onChatString(const QString& nick, const QString& str) |
|
314 { |
|
315 bool isFriend = false; |
|
316 |
|
317 if (!nick.isEmpty()) { |
|
318 // don't show chat lines that are from ignored nicks |
|
319 if (ignoreList.contains(nick, Qt::CaseInsensitive)) |
|
320 return; |
|
321 // friends will get special treatment, of course |
|
322 isFriend = friendsList.contains(nick, Qt::CaseInsensitive); |
|
323 } |
|
324 |
274 if (chatStrings.size() > 250) |
325 if (chatStrings.size() > 250) |
275 chatStrings.removeFirst(); |
326 chatStrings.removeFirst(); |
276 |
327 |
277 QString formattedStr = Qt::escape(str.mid(1)); |
328 QString formattedStr = Qt::escape(str.mid(1)); |
278 QStringList parts = formattedStr.split(QRegExp("\\W+"), QString::SkipEmptyParts); |
329 |
279 |
330 // "link" nick, but before that encode it in base64 to make sure it can't intefere with html/url syntax |
280 if (!formattedStr.startsWith(" ***")) // don't ignore status messages |
331 // the nick is put as querystring as putting it as host would convert it to it's lower case variant |
281 { |
332 if(!nick.isEmpty()) |
282 if (formattedStr.startsWith(" *")) // emote |
333 formattedStr.replace("|nick|",QString("<a href=\"hwnick://?%1\" class=\"nick\">%2</a>").arg(QString(nick.toUtf8().toBase64())).arg(nick)); |
283 parts[0] = parts[1]; |
|
284 if(parts.size() > 0 && ignoreList.contains(parts[0], Qt::CaseInsensitive)) |
|
285 return; |
|
286 } |
|
287 |
334 |
288 QString color(""); |
335 QString color(""); |
289 bool isFriend = friendsList.contains(parts[0], Qt::CaseInsensitive); |
336 |
290 |
337 // check first character for color code and set color properly |
291 if (str.startsWith("\x03")) |
338 switch (str[0].toAscii()) { |
292 color = QString("#c0c0c0"); |
339 case 3: |
293 else if (str.startsWith("\x02")) |
340 color = QString("#c0c0c0"); |
294 color = QString(isFriend ? "#00ff00" : "#ff00ff"); |
341 break; |
295 else if (isFriend) |
342 case 2: |
296 color = QString("#00c000"); |
343 color = QString(isFriend ? "#00ff00" : "#ff00ff"); |
297 |
344 break; |
298 if(color.compare("") != 0) |
345 default: |
|
346 if (isFriend) |
|
347 color = QString("#00c000"); |
|
348 } |
|
349 |
|
350 if (!color.isEmpty()) |
299 formattedStr = QString("<font color=\"%2\">%1</font>").arg(formattedStr).arg(color); |
351 formattedStr = QString("<font color=\"%2\">%1</font>").arg(formattedStr).arg(color); |
300 |
352 |
301 chatStrings.append(formattedStr); |
353 chatStrings.append(formattedStr); |
302 |
354 |
303 chatText->setHtml(chatStrings.join("<br>")); |
355 chatText->setHtml(chatStrings.join("<br>")); |
389 if(friendsList.contains(curritem->text(), Qt::CaseInsensitive)) |
441 if(friendsList.contains(curritem->text(), Qt::CaseInsensitive)) |
390 emit onFriend(); |
442 emit onFriend(); |
391 |
443 |
392 // scroll down on first ignore added so that people see where that nick went to |
444 // scroll down on first ignore added so that people see where that nick went to |
393 if (ignoreList.isEmpty()) |
445 if (ignoreList.isEmpty()) |
394 emit chatNicks->verticalScrollBar()->setValue(chatNicks->verticalScrollBar()->maximum()); |
446 chatNicks->scrollToBottom(); |
395 |
447 |
396 ignoreList << curritem->text().toLower(); |
448 ignoreList << curritem->text().toLower(); |
397 onChatString(HWChatWidget::tr("%1 *** %2 has been added to your ignore list").arg('\x03').arg(curritem->text())); |
449 onChatString(HWChatWidget::tr("%1 *** %2 has been added to your ignore list").arg('\x03').arg(curritem->text())); |
398 } |
450 } |
399 updateNickItem(curritem); // update icon/sort order/etc |
451 updateNickItem(curritem); // update icon/sort order/etc |
418 if(ignoreList.contains(curritem->text(), Qt::CaseInsensitive)) |
470 if(ignoreList.contains(curritem->text(), Qt::CaseInsensitive)) |
419 emit onIgnore(); |
471 emit onIgnore(); |
420 |
472 |
421 // scroll up on first friend added so that people see where that nick went to |
473 // scroll up on first friend added so that people see where that nick went to |
422 if (friendsList.isEmpty()) |
474 if (friendsList.isEmpty()) |
423 emit chatNicks->verticalScrollBar()->setValue(chatNicks->verticalScrollBar()->minimum()); |
475 chatNicks->scrollToTop(); |
424 |
476 |
425 friendsList << curritem->text().toLower(); |
477 friendsList << curritem->text().toLower(); |
426 onChatString(HWChatWidget::tr("%1 *** %2 has been added to your friends list").arg('\x03').arg(curritem->text())); |
478 onChatString(HWChatWidget::tr("%1 *** %2 has been added to your friends list").arg('\x03').arg(curritem->text())); |
427 } |
479 } |
428 updateNickItem(curritem); // update icon/sort order/etc |
480 updateNickItem(curritem); // update icon/sort order/etc |