273 connect(chatNicks, SIGNAL(currentRowChanged(int)), |
274 connect(chatNicks, SIGNAL(currentRowChanged(int)), |
274 this, SLOT(chatNickSelected(int))); |
275 this, SLOT(chatNickSelected(int))); |
275 |
276 |
276 mainLayout.addWidget(chatNicks, 0, 1, 3, 1); |
277 mainLayout.addWidget(chatNicks, 0, 1, 3, 1); |
277 |
278 |
|
279 // the userData is used to flag things that are even available when user |
|
280 // is offline |
278 acInfo = new QAction(QAction::tr("Info"), chatNicks); |
281 acInfo = new QAction(QAction::tr("Info"), chatNicks); |
279 acInfo->setIcon(QIcon(":/res/info.png")); |
282 acInfo->setIcon(QIcon(":/res/info.png")); |
|
283 acInfo->setData(QVariant(false)); |
280 connect(acInfo, SIGNAL(triggered(bool)), this, SLOT(onInfo())); |
284 connect(acInfo, SIGNAL(triggered(bool)), this, SLOT(onInfo())); |
281 acKick = new QAction(QAction::tr("Kick"), chatNicks); |
285 acKick = new QAction(QAction::tr("Kick"), chatNicks); |
282 acKick->setIcon(QIcon(":/res/kick.png")); |
286 acKick->setIcon(QIcon(":/res/kick.png")); |
|
287 acKick->setData(QVariant(false)); |
283 connect(acKick, SIGNAL(triggered(bool)), this, SLOT(onKick())); |
288 connect(acKick, SIGNAL(triggered(bool)), this, SLOT(onKick())); |
284 acBan = new QAction(QAction::tr("Ban"), chatNicks); |
289 acBan = new QAction(QAction::tr("Ban"), chatNicks); |
285 acBan->setIcon(QIcon(":/res/ban.png")); |
290 acBan->setIcon(QIcon(":/res/ban.png")); |
|
291 acBan->setData(QVariant(true)); |
286 connect(acBan, SIGNAL(triggered(bool)), this, SLOT(onBan())); |
292 connect(acBan, SIGNAL(triggered(bool)), this, SLOT(onBan())); |
287 acFollow = new QAction(QAction::tr("Follow"), chatNicks); |
293 acFollow = new QAction(QAction::tr("Follow"), chatNicks); |
288 acFollow->setIcon(QIcon(":/res/follow.png")); |
294 acFollow->setIcon(QIcon(":/res/follow.png")); |
|
295 acFollow->setData(QVariant(false)); |
289 connect(acFollow, SIGNAL(triggered(bool)), this, SLOT(onFollow())); |
296 connect(acFollow, SIGNAL(triggered(bool)), this, SLOT(onFollow())); |
290 acIgnore = new QAction(QAction::tr("Ignore"), chatNicks); |
297 acIgnore = new QAction(QAction::tr("Ignore"), chatNicks); |
291 acIgnore->setIcon(QIcon(":/res/ignore.png")); |
298 acIgnore->setIcon(QIcon(":/res/ignore.png")); |
|
299 acIgnore->setData(QVariant(true)); |
292 connect(acIgnore, SIGNAL(triggered(bool)), this, SLOT(onIgnore())); |
300 connect(acIgnore, SIGNAL(triggered(bool)), this, SLOT(onIgnore())); |
293 acFriend = new QAction(QAction::tr("Add friend"), chatNicks); |
301 acFriend = new QAction(QAction::tr("Add friend"), chatNicks); |
294 acFriend->setIcon(QIcon(":/res/addfriend.png")); |
302 acFriend->setIcon(QIcon(":/res/addfriend.png")); |
|
303 acFriend->setData(QVariant(true)); |
295 connect(acFriend, SIGNAL(triggered(bool)), this, SLOT(onFriend())); |
304 connect(acFriend, SIGNAL(triggered(bool)), this, SLOT(onFriend())); |
296 |
305 |
297 chatNicks->insertAction(0, acFriend); |
306 chatNicks->insertAction(0, acFriend); |
298 chatNicks->insertAction(0, acInfo); |
307 chatNicks->insertAction(0, acInfo); |
299 chatNicks->insertAction(0, acIgnore); |
308 chatNicks->insertAction(0, acIgnore); |
311 if (link.scheme() == "http") |
320 if (link.scheme() == "http") |
312 QDesktopServices::openUrl(link); |
321 QDesktopServices::openUrl(link); |
313 if (link.scheme() == "hwnick") |
322 if (link.scheme() == "hwnick") |
314 { |
323 { |
315 // decode nick |
324 // decode nick |
316 const QString& nick = QString::fromUtf8(QByteArray::fromBase64(link.encodedQuery())); |
325 QString nick = QString::fromUtf8(QByteArray::fromBase64(link.encodedQuery())); |
317 QList<QListWidgetItem *> items = chatNicks->findItems(nick, Qt::MatchExactly); |
326 QList<QListWidgetItem *> items = chatNicks->findItems(nick, Qt::MatchExactly); |
318 if (items.size() < 1) |
327 |
319 return; |
328 bool isOffline = (items.size() < 1); |
|
329 |
320 QMenu * popup = new QMenu(this); |
330 QMenu * popup = new QMenu(this); |
321 // selecting an item will automatically scroll there, so let's save old position |
331 |
322 QScrollBar * scrollBar = chatNicks->verticalScrollBar(); |
332 if (isOffline) |
323 int oldScrollPos = scrollBar->sliderPosition(); |
333 { |
324 // select the nick which we want to see the actions for |
334 m_clickedNick = nick; |
325 chatNicks->setCurrentItem(items[0], QItemSelectionModel::Clear); |
335 chatNickSelected(0); // update friend and ignore entry |
326 // selecting an item will automatically scroll there, so let's save old position |
336 chatNicks->setCurrentItem(NULL, QItemSelectionModel::Clear); |
327 scrollBar->setSliderPosition(oldScrollPos); |
337 } |
|
338 else |
|
339 { |
|
340 // selecting an item will automatically scroll there, so let's save old position |
|
341 QScrollBar * scrollBar = chatNicks->verticalScrollBar(); |
|
342 int oldScrollPos = scrollBar->sliderPosition(); |
|
343 // select the nick which we want to see the actions for |
|
344 chatNicks->setCurrentItem(items[0], QItemSelectionModel::Clear); |
|
345 // selecting an item will automatically scroll there, so let's save old position |
|
346 scrollBar->setSliderPosition(oldScrollPos); |
|
347 } |
|
348 |
328 // load actions |
349 // load actions |
329 popup->addActions(chatNicks->actions()); |
350 QList<QAction *> actions = chatNicks->actions(); |
|
351 |
|
352 foreach(QAction * action, actions) |
|
353 { |
|
354 if ((!isOffline) || (action->data().toBool())) |
|
355 popup->addAction(action); |
|
356 } |
|
357 |
330 // display menu popup at mouse cursor position |
358 // display menu popup at mouse cursor position |
331 popup->popup(QCursor::pos()); |
359 popup->popup(QCursor::pos()); |
332 } |
360 } |
333 } |
361 } |
334 |
362 |
474 |
514 |
475 QString formattedStr = Qt::escape(str.mid(1)); |
515 QString formattedStr = Qt::escape(str.mid(1)); |
476 // make hedgewars.org urls actual links |
516 // make hedgewars.org urls actual links |
477 formattedStr = formattedStr.replace(URLREGEXP, "<a href=\"http://\\3\">\\3</a>"); |
517 formattedStr = formattedStr.replace(URLREGEXP, "<a href=\"http://\\3\">\\3</a>"); |
478 |
518 |
479 // "link" nick, but before that encode it in base64 to make sure it can't intefere with html/url syntax |
519 // link the nick |
480 // the nick is put as querystring as putting it as host would convert it to it's lower case variant |
|
481 if(!nick.isEmpty()) |
520 if(!nick.isEmpty()) |
482 { |
521 formattedStr.replace("|nick|", linkedNick(nick)); |
483 if (nick != m_userNick) |
|
484 formattedStr.replace("|nick|",QString("<a href=\"hwnick://?%1\" class=\"nick\">%2</a>").arg(QString(nick.toUtf8().toBase64())).arg(nick)); |
|
485 else |
|
486 formattedStr.replace("|nick|", QString("<span class=\"nick\">%1</span>").arg(nick)); |
|
487 } |
|
488 |
522 |
489 QString cssClass("msg_UserChat"); |
523 QString cssClass("msg_UserChat"); |
490 |
524 |
491 // check first character for color code and set color properly |
525 // check first character for color code and set color properly |
492 char c = str[0].toAscii(); |
526 char c = str[0].toAscii(); |
677 } |
711 } |
678 |
712 |
679 void HWChatWidget::onIgnore() |
713 void HWChatWidget::onIgnore() |
680 { |
714 { |
681 QListWidgetItem * curritem = chatNicks->currentItem(); |
715 QListWidgetItem * curritem = chatNicks->currentItem(); |
682 if(!curritem) |
716 QString nick = ""; |
683 return; |
717 if(curritem != NULL) |
684 |
718 nick = curritem->text(); |
685 if(ignoreList.contains(curritem->text(), Qt::CaseInsensitive)) // already on list - remove him |
719 else |
686 { |
720 nick = m_clickedNick; |
687 ignoreList.removeAll(curritem->text().toLower()); |
721 |
688 chatEditLine->addNickname(curritem->text()); |
722 if(ignoreList.contains(nick, Qt::CaseInsensitive)) // already on list - remove him |
689 displayNotice(tr("%1 has been removed from your ignore list").arg(curritem->text())); |
723 { |
|
724 ignoreList.removeAll(nick.toLower()); |
|
725 chatEditLine->addNickname(nick); |
|
726 displayNotice(tr("%1 has been removed from your ignore list").arg(linkedNick(nick))); |
690 } |
727 } |
691 else // not on list - add |
728 else // not on list - add |
692 { |
729 { |
693 // don't consider ignored people friends |
730 // don't consider ignored people friends |
694 if(friendsList.contains(curritem->text(), Qt::CaseInsensitive)) |
731 if(friendsList.contains(nick, Qt::CaseInsensitive)) |
695 emit onFriend(); |
732 emit onFriend(); |
696 |
733 |
697 // scroll down on first ignore added so that people see where that nick went to |
734 // scroll down on first ignore added so that people see where that nick went to |
698 if (ignoreList.isEmpty()) |
735 if (ignoreList.isEmpty()) |
699 chatNicks->scrollToBottom(); |
736 chatNicks->scrollToBottom(); |
700 |
737 |
701 ignoreList << curritem->text().toLower(); |
738 ignoreList << nick.toLower(); |
702 chatEditLine->removeNickname(curritem->text()); |
739 chatEditLine->removeNickname(nick); |
703 displayNotice(tr("%1 has been added to your ignore list").arg(curritem->text())); |
740 displayNotice(tr("%1 has been added to your ignore list").arg(linkedNick(nick))); |
704 } |
741 } |
705 updateNickItem(curritem); // update icon/sort order/etc |
742 |
706 chatNicks->sortItems(); |
743 if(curritem != NULL) |
707 chatNickSelected(0); // update context menu |
744 { |
|
745 updateNickItem(curritem); // update icon/sort order/etc |
|
746 chatNicks->sortItems(); |
|
747 chatNickSelected(0); // update context menu |
|
748 } |
708 } |
749 } |
709 |
750 |
710 void HWChatWidget::onFriend() |
751 void HWChatWidget::onFriend() |
711 { |
752 { |
712 QListWidgetItem * curritem = chatNicks->currentItem(); |
753 QListWidgetItem * curritem = chatNicks->currentItem(); |
713 if(!curritem) |
754 QString nick = ""; |
714 return; |
755 if(curritem != NULL) |
715 |
756 nick = curritem->text(); |
716 if(friendsList.contains(curritem->text(), Qt::CaseInsensitive)) // already on list - remove him |
757 else |
717 { |
758 nick = m_clickedNick; |
718 friendsList.removeAll(curritem->text().toLower()); |
759 |
719 displayNotice(tr("%1 has been removed from your friends list").arg(curritem->text())); |
760 if(friendsList.contains(nick, Qt::CaseInsensitive)) // already on list - remove him |
|
761 { |
|
762 friendsList.removeAll(nick.toLower()); |
|
763 displayNotice(tr("%1 has been removed from your friends list").arg(linkedNick(nick))); |
720 } |
764 } |
721 else // not on list - add |
765 else // not on list - add |
722 { |
766 { |
723 // don't ignore the new friend |
767 // don't ignore the new friend |
724 if(ignoreList.contains(curritem->text(), Qt::CaseInsensitive)) |
768 if(ignoreList.contains(nick, Qt::CaseInsensitive)) |
725 emit onIgnore(); |
769 emit onIgnore(); |
726 |
770 |
727 // scroll up on first friend added so that people see where that nick went to |
771 // scroll up on first friend added so that people see where that nick went to |
728 if (friendsList.isEmpty()) |
772 if (friendsList.isEmpty()) |
729 chatNicks->scrollToTop(); |
773 chatNicks->scrollToTop(); |
730 |
774 |
731 friendsList << curritem->text().toLower(); |
775 friendsList << nick.toLower(); |
732 displayNotice(tr("%1 has been added to your friends list").arg(curritem->text())); |
776 displayNotice(tr("%1 has been added to your friends list").arg(linkedNick(nick))); |
733 } |
777 } |
734 updateNickItem(curritem); // update icon/sort order/etc |
778 |
735 chatNicks->sortItems(); |
779 if(curritem != NULL) |
736 chatNickSelected(0); // update context menu |
780 { |
|
781 updateNickItem(curritem); // update icon/sort order/etc |
|
782 chatNicks->sortItems(); |
|
783 chatNickSelected(0); // update context menu |
|
784 } |
737 } |
785 } |
738 |
786 |
739 void HWChatWidget::chatNickDoubleClicked(QListWidgetItem * item) |
787 void HWChatWidget::chatNickDoubleClicked(QListWidgetItem * item) |
740 { |
788 { |
741 Q_UNUSED(item); |
789 if (item != NULL) |
742 |
790 m_clickedNick = item->text(); |
|
791 else |
|
792 m_clickedNick = ""; |
743 QList<QAction *> actions = chatNicks->actions(); |
793 QList<QAction *> actions = chatNicks->actions(); |
744 actions.first()->activate(QAction::Trigger); |
794 actions.first()->activate(QAction::Trigger); |
745 } |
795 } |
746 |
796 |
747 void HWChatWidget::chatNickSelected(int index) |
797 void HWChatWidget::chatNickSelected(int index) |
748 { |
798 { |
749 Q_UNUSED(index); |
799 Q_UNUSED(index); |
750 |
800 |
751 QListWidgetItem* item = chatNicks->currentItem(); |
801 QListWidgetItem* item = chatNicks->currentItem(); |
752 if (!item) |
802 QString nick = ""; |
753 return; |
803 if (item != NULL) |
|
804 nick = item->text(); |
|
805 else |
|
806 nick = m_clickedNick; |
754 |
807 |
755 // update context menu labels according to possible action |
808 // update context menu labels according to possible action |
756 if(ignoreList.contains(item->text(), Qt::CaseInsensitive)) |
809 if(ignoreList.contains(nick, Qt::CaseInsensitive)) |
757 { |
810 { |
758 acIgnore->setText(QAction::tr("Unignore")); |
811 acIgnore->setText(QAction::tr("Unignore")); |
759 acIgnore->setIcon(QIcon(":/res/unignore.png")); |
812 acIgnore->setIcon(QIcon(":/res/unignore.png")); |
760 } |
813 } |
761 else |
814 else |
762 { |
815 { |
763 acIgnore->setText(QAction::tr("Ignore")); |
816 acIgnore->setText(QAction::tr("Ignore")); |
764 acIgnore->setIcon(QIcon(":/res/ignore.png")); |
817 acIgnore->setIcon(QIcon(":/res/ignore.png")); |
765 } |
818 } |
766 |
819 |
767 if(friendsList.contains(item->text(), Qt::CaseInsensitive)) |
820 if(friendsList.contains(nick, Qt::CaseInsensitive)) |
768 { |
821 { |
769 acFriend->setText(QAction::tr("Remove friend")); |
822 acFriend->setText(QAction::tr("Remove friend")); |
770 acFriend->setIcon(QIcon(":/res/remfriend.png")); |
823 acFriend->setIcon(QIcon(":/res/remfriend.png")); |
771 } |
824 } |
772 else |
825 else |