1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

feat(UI): Add 'Copy link' context menu item

Fixes #927
This commit is contained in:
tux3 2016-12-07 01:59:07 +01:00
parent 584b2d85f1
commit a7de2680d9
No known key found for this signature in database
GPG Key ID: 7E086DD661263264
6 changed files with 57 additions and 1 deletions

View File

@ -558,6 +558,16 @@ ChatLine::Ptr ChatLog::getLatestLine() const
return nullptr; return nullptr;
} }
/**
* @brief Finds the chat line object at a position on screen
* @param pos Position on screen in global coordinates
* @sa getContentFromPos()
*/
ChatLineContent *ChatLog::getContentFromGlobalPos(QPoint pos) const
{
return getContentFromPos(mapToScene(mapFromGlobal(pos)));
}
void ChatLog::clear() void ChatLog::clear()
{ {
clearSelection(); clearSelection();

View File

@ -61,6 +61,7 @@ public:
ChatLine::Ptr getTypingNotification() const; ChatLine::Ptr getTypingNotification() const;
QVector<ChatLine::Ptr> getLines(); QVector<ChatLine::Ptr> getLines();
ChatLine::Ptr getLatestLine() const; ChatLine::Ptr getLatestLine() const;
ChatLineContent* getContentFromGlobalPos(QPoint pos) const;
const uint repNameAfter = 5*60; const uint repNameAfter = 5*60;
signals: signals:

View File

@ -231,6 +231,18 @@ QString Text::getText() const
return rawText; return rawText;
} }
/**
* @brief Extracts the target of a link from the text at a given coordinate
* @param scenePos Position in scene coordinates
* @return The link target URL, or an empty string if there is no link there
*/
QString Text::getLinkAt(QPointF scenePos) const
{
QTextCursor cursor(doc);
cursor.setPosition(cursorFromPos(scenePos));
return cursor.charFormat().anchorHref();
}
void Text::regenerate() void Text::regenerate()
{ {
if (!doc) if (!doc)

View File

@ -28,6 +28,8 @@ class QTextDocument;
class Text : public ChatLineContent class Text : public ChatLineContent
{ {
Q_OBJECT
public: public:
Text(const QString& txt = "", const QFont& font = QFont(), bool enableElide = false, const QString& rawText = QString(), const QColor c = Qt::black); Text(const QString& txt = "", const QFont& font = QFont(), bool enableElide = false, const QString& rawText = QString(), const QColor c = Qt::black);
virtual ~Text(); virtual ~Text();
@ -55,6 +57,7 @@ public:
void hoverMoveEvent(QGraphicsSceneHoverEvent* event) final override; void hoverMoveEvent(QGraphicsSceneHoverEvent* event) final override;
virtual QString getText() const final; virtual QString getText() const final;
QString getLinkAt(QPointF scenePos) const;
protected: protected:
// dynamic resource management // dynamic resource management

View File

@ -26,6 +26,7 @@
#include <QPushButton> #include <QPushButton>
#include <QShortcut> #include <QShortcut>
#include <QSplitter> #include <QSplitter>
#include <QClipboard>
#include "chatlog/chatlog.h" #include "chatlog/chatlog.h"
#include "chatlog/content/timestamp.h" #include "chatlog/content/timestamp.h"
@ -198,6 +199,9 @@ GenericChatForm::GenericChatForm(QWidget *parent)
quoteAction = menu.addAction(QIcon(), quoteAction = menu.addAction(QIcon(),
QString(), this, SLOT(quoteSelectedText())); QString(), this, SLOT(quoteSelectedText()));
copyLinkAction = menu.addAction(QIcon(),
QString(), this, SLOT(copyLink()));
menu.addSeparator(); menu.addSeparator();
connect(emoteButton, &QPushButton::clicked, connect(emoteButton, &QPushButton::clicked,
@ -313,6 +317,21 @@ void GenericChatForm::onChatContextMenuRequested(QPoint pos)
QWidget* sender = static_cast<QWidget*>(QObject::sender()); QWidget* sender = static_cast<QWidget*>(QObject::sender());
pos = sender->mapToGlobal(pos); pos = sender->mapToGlobal(pos);
// If we right-clicked on a link, give the option to copy it
bool clickedOnLink = false;
Text* clickedText = qobject_cast<Text*>(chatWidget->getContentFromGlobalPos(pos));
if (clickedText)
{
QPointF scenePos = chatWidget->mapToScene(chatWidget->mapFromGlobal(pos));
QString linkTarget = clickedText->getLinkAt(scenePos);
if (!linkTarget.isEmpty())
{
clickedOnLink = true;
copyLinkAction->setData(linkTarget);
}
}
copyLinkAction->setVisible(clickedOnLink);
menu.exec(pos); menu.exec(pos);
} }
@ -598,6 +617,15 @@ void GenericChatForm::quoteSelectedText()
msgEdit->append(quote); msgEdit->append(quote);
} }
/**
* @brief Callback of GenericChatForm::copyLinkAction
*/
void GenericChatForm::copyLink()
{
QString linkText = copyLinkAction->data().toString();
QApplication::clipboard()->setText(linkText);
}
void GenericChatForm::retranslateUi() void GenericChatForm::retranslateUi()
{ {
QString callObjectName = callButton->objectName(); QString callObjectName = callButton->objectName();
@ -624,6 +652,7 @@ void GenericChatForm::retranslateUi()
saveChatAction->setText(tr("Save chat log")); saveChatAction->setText(tr("Save chat log"));
clearAction->setText(tr("Clear displayed messages")); clearAction->setText(tr("Clear displayed messages"));
quoteAction->setText(tr("Quote selected text")); quoteAction->setText(tr("Quote selected text"));
copyLinkAction->setText(tr("Copy link address"));
} }
void GenericChatForm::showNetcam() void GenericChatForm::showNetcam()

View File

@ -95,6 +95,7 @@ protected slots:
void onShowMessagesClicked(); void onShowMessagesClicked();
void onSplitterMoved(int pos, int index); void onSplitterMoved(int pos, int index);
void quoteSelectedText(); void quoteSelectedText();
void copyLink();
private: private:
void retranslateUi(); void retranslateUi();
@ -113,7 +114,7 @@ protected:
virtual bool eventFilter(QObject* object, QEvent* event) final override; virtual bool eventFilter(QObject* object, QEvent* event) final override;
protected: protected:
QAction* saveChatAction, *clearAction, *quoteAction; QAction* saveChatAction, *clearAction, *quoteAction, *copyLinkAction;
ToxId previousId; ToxId previousId;
QDateTime prevMsgDateTime; QDateTime prevMsgDateTime;
Widget *parent; Widget *parent;