#include <QTextLayout>
#include <QMenu>
-
+#include "buffermodel.h"
+#include "bufferview.h"
#include "chatitem.h"
#include "chatlinemodel.h"
+#include "iconloader.h"
+#include "mainwin.h"
#include "qtui.h"
#include "qtuistyle.h"
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.
return result;
}
+ContentsChatItem::Clickable ContentsChatItem::clickableAt(const QPointF &pos) const {
+ qint16 idx = posToCursor(pos);
+ for(int i = 0; i < privateData()->clickables.count(); i++) {
+ Clickable click = privateData()->clickables.at(i);
+ if(idx >= click.start && idx < click.start + click.length)
+ return click;
+ }
+ return Clickable();
+}
+
QVector<QTextLayout::FormatRange> ContentsChatItem::additionalFormats() const {
// mark a clickable if hovered upon
QVector<QTextLayout::FormatRange> fmt;
void ContentsChatItem::handleClick(const QPointF &pos, ChatScene::ClickMode clickMode) {
if(clickMode == ChatScene::SingleClick) {
- Clickable click = privateData()->currentClickable;
+ Clickable click = clickableAt(pos);
if(click.isValid()) {
QString str = data(ChatLineModel::DisplayRole).toString().mid(click.start, click.length);
switch(click.type) {
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...
+ case Clickable::Channel: {
+ NetworkId networkId = Client::networkModel()->networkId(data(MessageModel::BufferIdRole).value<BufferId>());
+ BufferId bufId = Client::networkModel()->bufferId(networkId, str);
+ if(bufId.isValid()) {
+ QModelIndex targetIdx = Client::networkModel()->bufferIndex(bufId);
+ Client::bufferModel()->switchToBuffer(bufId);
+ if(!targetIdx.data(NetworkModel::ItemActiveRole).toBool())
+ Client::userInput(BufferInfo::fakeStatusBuffer(networkId), QString("/JOIN %1").arg(str));
+ } else
+ Client::userInput(BufferInfo::fakeStatusBuffer(networkId), QString("/JOIN %1").arg(str));
break;
+ }
default:
break;
}
} else if(clickMode == ChatScene::DoubleClick) {
chatScene()->setSelectingItem(this);
setSelectionMode(PartialSelection);
- Clickable click = privateData()->currentClickable;
+ Clickable click = clickableAt(pos);
if(click.isValid()) {
setSelectionStart(click.start);
setSelectionEnd(click.start + click.length);
void ContentsChatItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) {
bool onClickable = false;
- qint16 idx = posToCursor(event->pos());
- for(int i = 0; i < privateData()->clickables.count(); i++) {
- Clickable click = privateData()->clickables.at(i);
- if(idx >= click.start && idx < click.start + click.length) {
- if(click.type == Clickable::Url) {
+ Clickable click = clickableAt(event->pos());
+ if(click.isValid()) {
+ if(click.type == Clickable::Url) {
+ onClickable = true;
+ showWebPreview(click);
+ } else if(click.type == Clickable::Channel) {
+ // 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;
- 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
- }
- if(onClickable) {
- setCursor(Qt::PointingHandCursor);
- privateData()->currentClickable = click;
- update();
- break;
- }
+ }
+ if(onClickable) {
+ setCursor(Qt::PointingHandCursor);
+ privateData()->currentClickable = click;
+ update();
+ return;
}
}
if(!onClickable) endHoverMode();
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>());
}
}