From f662db526c93bd3411509317d665b4f69c6832a0 Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Tue, 25 Aug 2009 17:30:35 +0200 Subject: [PATCH] Introduce Clickable::activate() to put handling clicks in a single place Moved out of ChatItem. --- src/client/buffermodel.cpp | 11 +++++++++++ src/client/buffermodel.h | 9 +++++---- src/qtui/chatitem.cpp | 38 +++++++------------------------------ src/uisupport/clickable.cpp | 34 +++++++++++++++++++++++++++++++++ src/uisupport/clickable.h | 8 ++++++++ 5 files changed, 65 insertions(+), 35 deletions(-) diff --git a/src/client/buffermodel.cpp b/src/client/buffermodel.cpp index 21141ca2..1ae0c2e9 100644 --- a/src/client/buffermodel.cpp +++ b/src/client/buffermodel.cpp @@ -102,6 +102,17 @@ void BufferModel::switchToBufferIndex(const QModelIndex &bufferIdx) { qWarning() << "BufferModel::switchToBufferIndex(const QModelIndex &):" << bufferIdx << "does not belong to BufferModel or NetworkModel"; } +void BufferModel::switchToOrJoinBuffer(NetworkId networkId, const QString &name) { + BufferId bufId = Client::networkModel()->bufferId(networkId, name); + if(bufId.isValid()) { + QModelIndex targetIdx = Client::networkModel()->bufferIndex(bufId); + switchToBuffer(bufId); + if(!targetIdx.data(NetworkModel::ItemActiveRole).toBool()) + Client::userInput(BufferInfo::fakeStatusBuffer(networkId), QString("/JOIN %1").arg(name)); + } else + Client::userInput(BufferInfo::fakeStatusBuffer(networkId), QString("/JOIN %1").arg(name)); +} + void BufferModel::debug_currentChanged(QModelIndex current, QModelIndex previous) { Q_UNUSED(previous); qDebug() << "Switched current Buffer: " << current << current.data().toString() << "Buffer:" << current.data(NetworkModel::BufferIdRole).value(); diff --git a/src/client/buffermodel.h b/src/client/buffermodel.h index 578481b8..9a94fbe4 100644 --- a/src/client/buffermodel.h +++ b/src/client/buffermodel.h @@ -38,10 +38,10 @@ public: BufferModel(NetworkModel *parent = 0); bool filterAcceptsRow(int sourceRow, const QModelIndex &parent) const; - + inline const SelectionModelSynchronizer *selectionModelSynchronizer() const { return &_selectionModelSynchronizer; } inline QItemSelectionModel *standardSelectionModel() const { return _selectionModelSynchronizer.selectionModel(); } - + inline void synchronizeSelectionModel(QItemSelectionModel *selectionModel) { _selectionModelSynchronizer.synchronizeSelectionModel(selectionModel); } void synchronizeView(QAbstractItemView *view); @@ -51,12 +51,13 @@ public slots: void setCurrentIndex(const QModelIndex &newCurrent); void switchToBuffer(const BufferId &bufferId); void switchToBufferIndex(const QModelIndex &bufferIdx); - + void switchToOrJoinBuffer(NetworkId network, const QString &bufferName); + private slots: void debug_currentChanged(QModelIndex current, QModelIndex previous); void newNetwork(NetworkId id); void networkConnectionChanged(Network::ConnectionState state); - + private: SelectionModelSynchronizer _selectionModelSynchronizer; }; diff --git a/src/qtui/chatitem.cpp b/src/qtui/chatitem.cpp index 499ae774..8ff441c2 100644 --- a/src/qtui/chatitem.cpp +++ b/src/qtui/chatitem.cpp @@ -458,13 +458,7 @@ void ContentsChatItem::doLayout(QTextLayout *layout) const { } 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(); + return privateData()->clickables.atCursorPos(posToCursor(pos)); } UiStyle::FormatList ContentsChatItem::formatList() const { @@ -505,30 +499,12 @@ void ContentsChatItem::endHoverMode() { void ContentsChatItem::handleClick(const QPointF &pos, ChatScene::ClickMode clickMode) { if(clickMode == ChatScene::SingleClick) { - 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.toUtf8(), QUrl::TolerantMode)); - break; - case Clickable::Channel: { - NetworkId networkId = Client::networkModel()->networkId(data(MessageModel::BufferIdRole).value()); - 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; - } + qint16 idx = posToCursor(pos); + Clickable foo = privateData()->clickables.atCursorPos(idx); + if(foo.isValid()) { + NetworkId networkId = Client::networkModel()->networkId(data(MessageModel::BufferIdRole).value()); + QString text = data(ChatLineModel::DisplayRole).toString(); + foo.activate(networkId, text); } } else if(clickMode == ChatScene::DoubleClick) { chatScene()->setSelectingItem(this); diff --git a/src/uisupport/clickable.cpp b/src/uisupport/clickable.cpp index d19083c8..54fa9b82 100644 --- a/src/uisupport/clickable.cpp +++ b/src/uisupport/clickable.cpp @@ -18,7 +18,33 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +#include +#include +#include + +#include "buffermodel.h" #include "clickable.h" +#include "client.h" + +void Clickable::activate(NetworkId networkId, const QString &text) const { + if(!isValid()) + return; + + QString str = text.mid(start(), length()); + + switch(type()) { + case Clickable::Url: + if(!str.contains("://")) + str = "http://" + str; + QDesktopServices::openUrl(QUrl::fromEncoded(str.toUtf8(), QUrl::TolerantMode)); + break; + case Clickable::Channel: + Client::bufferModel()->switchToOrJoinBuffer(networkId, str); + break; + default: + break; + } +} // NOTE: This method is not threadsafe and not reentrant! // (RegExps are not constant while matching, and they are static here for efficiency) @@ -84,3 +110,11 @@ ClickableList ClickableList::fromString(const QString &str) { } while(type >= 0); return result; } + +Clickable ClickableList::atCursorPos(int idx) { + foreach(const Clickable &click, *this) { + if(idx >= click.start() && idx < click.start() + click.length()) + return click; + } + return Clickable(); +} diff --git a/src/uisupport/clickable.h b/src/uisupport/clickable.h index ce8d9a6d..eb89a36c 100644 --- a/src/uisupport/clickable.h +++ b/src/uisupport/clickable.h @@ -23,6 +23,10 @@ #include +#include "types.h" + +class QModelIndex; + class Clickable { public: @@ -44,6 +48,8 @@ public: inline bool isValid() const { return _type != Invalid; } + void activate(NetworkId networkId, const QString &bufferName) const; + private: Type _type; quint16 _start; @@ -55,6 +61,8 @@ class ClickableList : public QList { public: static ClickableList fromString(const QString &); + Clickable atCursorPos(int idx); + }; #endif // CLICKABLE_H_ -- 2.20.1