Making channel names clickable
[quassel.git] / src / qtui / chatitem.cpp
index 9785325..be792c9 100644 (file)
 #include <QTextLayout>
 #include <QMenu>
 
-
+#include "bufferview.h"
 #include "chatitem.h"
 #include "chatlinemodel.h"
+#include "iconloader.h"
+#include "mainwin.h"
 #include "qtui.h"
 #include "qtuistyle.h"
 
@@ -410,7 +412,7 @@ QList<ContentsChatItem::Clickable> ContentsChatItem::findClickables() const {
   static QRegExp regExp[] = {
     // URL
     // QRegExp(QString("((?:https?://|s?ftp://|irc://|mailto:|www\\.)%1+|%1+\\.[a-z]{2,4}(?:?=/%1+|\\b))%2").arg(urlChars, urlEnd)),
-    QRegExp(QString("((?:(?:https?://|s?ftp://|irc://|mailto:)|www)%1+)%2").arg(urlChars, urlEnd), Qt::CaseInsensitive),
+    QRegExp(QString("((?:(?:https?://|s?ftp://|irc://|gopher://|mailto:)|www)%1+)%2").arg(urlChars, urlEnd), Qt::CaseInsensitive),
 
     // Channel name
     // We don't match for channel names starting with + or &, because that gives us a lot of false positives.
@@ -507,7 +509,7 @@ void ContentsChatItem::handleClick(const QPointF &pos, ChatScene::ClickMode clic
         case Clickable::Url:
           if(!str.contains("://"))
             str = "http://" + str;
-          QDesktopServices::openUrl(QUrl::fromEncoded(str.toAscii()));
+          QDesktopServices::openUrl(QUrl::fromEncoded(str.toUtf8(), QUrl::TolerantMode));
           break;
         case Clickable::Channel:
           // TODO join or whatever...
@@ -559,8 +561,11 @@ void ContentsChatItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) {
       onClickable = true;
       showWebPreview(click);
     } else if(click.type == Clickable::Channel) {
-      // TODO: don't make clickable if it's our own name
-      // onClickable = true; //FIXME disabled for now
+      // don't make clickable if it's our own name
+      QString name = data(ChatLineModel::DisplayRole).toString().mid(click.start, click.length);
+      BufferId myId = data(MessageModel::BufferIdRole).value<BufferId>();
+      if(Client::networkModel()->bufferName(myId) != name)
+        onClickable = true;
     }
     if(onClickable) {
       setCursor(Qt::PointingHandCursor);
@@ -577,15 +582,28 @@ void ContentsChatItem::addActionsToMenu(QMenu *menu, const QPointF &pos) {
   Q_UNUSED(pos); // we assume that the current mouse cursor pos is the point of invocation
 
   if(privateData()->currentClickable.isValid()) {
-    switch(privateData()->currentClickable.type) {
+    Clickable click = privateData()->currentClickable;
+    switch(click.type) {
       case Clickable::Url:
-        privateData()->activeClickable = privateData()->currentClickable;
-        menu->addAction(tr("Copy Link Address"), &_actionProxy, SLOT(copyLinkToClipboard()))->setData(QVariant::fromValue<void *>(this));
+        privateData()->activeClickable = click;
+        menu->addAction(SmallIcon("edit-copy"), tr("Copy Link Address"),
+                         &_actionProxy, SLOT(copyLinkToClipboard()))->setData(QVariant::fromValue<void *>(this));
         break;
-
+      case Clickable::Channel: {
+        // Hide existing menu actions, they confuse us when right-clicking on a clickable
+        foreach(QAction *action, menu->actions())
+          action->setVisible(false);
+        QString name = data(ChatLineModel::DisplayRole).toString().mid(click.start, click.length);
+        Client::mainUi()->actionProvider()->addActions(menu, chatScene()->filter(), data(MessageModel::BufferIdRole).value<BufferId>(), name);
+        break;
+      }
       default:
         break;
     }
+  } else {
+
+    // Buffer-specific actions
+    Client::mainUi()->actionProvider()->addActions(menu, chatScene()->filter(), data(MessageModel::BufferIdRole).value<BufferId>());
   }
 }