Merge pull request #1245 from PhenomRetroShare/AddContextMenuForGxsIdInTextChatBrowser

Add Context Menu for GxsId in lobby textBrowser.
This commit is contained in:
csoler 2018-05-06 23:53:45 +02:00 committed by GitHub
commit 5b607ada26
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 234 additions and 190 deletions

View File

@ -33,6 +33,7 @@
#include "gui/ChatLobbyWidget.h" #include "gui/ChatLobbyWidget.h"
#include "gui/FriendsDialog.h" #include "gui/FriendsDialog.h"
#include "gui/MainWindow.h" #include "gui/MainWindow.h"
#include "gui/chat/ChatWidget.h"
#include "gui/common/html.h" #include "gui/common/html.h"
#include "gui/common/FriendSelectionDialog.h" #include "gui/common/FriendSelectionDialog.h"
#include "gui/common/RSTreeWidgetItem.h" #include "gui/common/RSTreeWidgetItem.h"
@ -97,7 +98,7 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
votePositiveAct = new QAction(QIcon(":/icons/png/thumbs-up.png"), tr("Give positive opinion"), this); votePositiveAct = new QAction(QIcon(":/icons/png/thumbs-up.png"), tr("Give positive opinion"), this);
distantChatAct = new QAction(QIcon(":/images/chat_24.png"), tr("Start private chat"), this); distantChatAct = new QAction(QIcon(":/images/chat_24.png"), tr("Start private chat"), this);
sendMessageAct = new QAction(QIcon(":/images/mail_new.png"), tr("Send Message"), this); sendMessageAct = new QAction(QIcon(":/images/mail_new.png"), tr("Send Message"), this);
showinpeopleAct = new QAction(QIcon(), tr("Show author in people tab"), this); showInPeopleAct = new QAction(QIcon(), tr("Show author in people tab"), this);
QActionGroup *sortgrp = new QActionGroup(this); QActionGroup *sortgrp = new QActionGroup(this);
actionSortByName = new QAction(QIcon(), tr("Sort by Name"), this); actionSortByName = new QAction(QIcon(), tr("Sort by Name"), this);
@ -111,17 +112,13 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
actionSortByActivity->setActionGroup(sortgrp); actionSortByActivity->setActionGroup(sortgrp);
connect(muteAct, SIGNAL(triggered()), this, SLOT(changePartipationState())); connect(muteAct, SIGNAL(triggered()), this, SLOT(changeParticipationState()));
connect(distantChatAct, SIGNAL(triggered()), this, SLOT(distantChatParticipant())); connect(distantChatAct, SIGNAL(triggered()), this, SLOT(distantChatParticipant()));
connect(sendMessageAct, SIGNAL(triggered()), this, SLOT(sendMessage())); connect(sendMessageAct, SIGNAL(triggered()), this, SLOT(sendMessage()));
connect(votePositiveAct, SIGNAL(triggered()), this, SLOT(voteParticipant())); connect(votePositiveAct, SIGNAL(triggered()), this, SLOT(voteParticipant()));
connect(voteNeutralAct, SIGNAL(triggered()), this, SLOT(voteParticipant())); connect(voteNeutralAct, SIGNAL(triggered()), this, SLOT(voteParticipant()));
connect(voteNegativeAct, SIGNAL(triggered()), this, SLOT(voteParticipant())); connect(voteNegativeAct, SIGNAL(triggered()), this, SLOT(voteParticipant()));
connect(showinpeopleAct, SIGNAL(triggered()), this, SLOT(showInPeopleTab())); connect(showInPeopleAct, SIGNAL(triggered()), this, SLOT(showInPeopleTab()));
votePositiveAct->setData(RsReputations::OPINION_POSITIVE);
voteNeutralAct->setData(RsReputations::OPINION_NEUTRAL);
voteNegativeAct->setData(RsReputations::OPINION_NEGATIVE);
connect(actionSortByName, SIGNAL(triggered()), this, SLOT(sortParcipants())); connect(actionSortByName, SIGNAL(triggered()), this, SLOT(sortParcipants()));
connect(actionSortByActivity, SIGNAL(triggered()), this, SLOT(sortParcipants())); connect(actionSortByActivity, SIGNAL(triggered()), this, SLOT(sortParcipants()));
@ -172,7 +169,8 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
ui.chatWidget->addToolsAction(checkableAction); ui.chatWidget->addToolsAction(checkableAction);
//getChatWidget()->addChatBarWidget(ownIdChooser); //getChatWidget()->addChatBarWidget(ownIdChooser);
connect(ui.chatWidget, SIGNAL(textBrowserAskContextMenu(QMenu*,QString,QPoint)), this, SLOT(textBrowserAskContextMenu(QMenu*,QString,QPoint)));
connect(ownIdChooser,SIGNAL(currentIndexChanged(int)),this,SLOT(changeNickname())) ; connect(ownIdChooser,SIGNAL(currentIndexChanged(int)),this,SLOT(changeNickname())) ;
@ -226,33 +224,76 @@ void ChatLobbyDialog::inviteFriends()
void ChatLobbyDialog::participantsTreeWidgetCustomPopupMenu(QPoint) void ChatLobbyDialog::participantsTreeWidgetCustomPopupMenu(QPoint)
{ {
QList<QTreeWidgetItem*> selectedItems = ui.participantsList->selectedItems(); QList<QTreeWidgetItem*> selectedItems = ui.participantsList->selectedItems();
QList<RsGxsId> idList;
QList<QTreeWidgetItem*>::iterator item;
for (item = selectedItems.begin(); item != selectedItems.end(); ++item)
{
RsGxsId gxs_id ;
dynamic_cast<GxsIdRSTreeWidgetItem*>(*item)->getId(gxs_id) ;
idList.append(gxs_id);
}
QMenu contextMnu(this); QMenu contextMnu(this);
contextMnu.addAction(actionSortByActivity);
contextMnu.addAction(actionSortByName);
contextMnu.addAction(distantChatAct); contextMnu.addSeparator();
contextMnu.addAction(sendMessageAct);
contextMnu.addSeparator(); initParticipantsContextMenu(&contextMnu, idList);
contextMnu.addAction(actionSortByActivity);
contextMnu.addAction(actionSortByName); contextMnu.exec(QCursor::pos());
contextMnu.addSeparator(); }
contextMnu.addAction(muteAct);
contextMnu.addAction(votePositiveAct); void ChatLobbyDialog::textBrowserAskContextMenu(QMenu* contextMnu, QString anchorForPosition, const QPoint /*point*/)
contextMnu.addAction(voteNeutralAct); {
contextMnu.addAction(voteNegativeAct); if (anchorForPosition.startsWith(PERSONID)){
contextMnu.addAction(showinpeopleAct); QString strId = anchorForPosition.replace(PERSONID,"");
if (strId.contains(" "))
strId.truncate(strId.indexOf(" "));
contextMnu->addSeparator();
QList<RsGxsId> idList;
idList.append(RsGxsId(strId.toStdString()));
initParticipantsContextMenu(contextMnu, idList);
}
}
void ChatLobbyDialog::initParticipantsContextMenu(QMenu *contextMnu, QList<RsGxsId> idList)
{
if (!contextMnu)
return;
contextMnu->addAction(distantChatAct);
contextMnu->addAction(sendMessageAct);
contextMnu->addSeparator();
contextMnu->addAction(muteAct);
contextMnu->addAction(votePositiveAct);
contextMnu->addAction(voteNeutralAct);
contextMnu->addAction(voteNegativeAct);
contextMnu->addAction(showInPeopleAct);
distantChatAct->setEnabled(false); distantChatAct->setEnabled(false);
sendMessageAct->setEnabled(selectedItems.count()==1); sendMessageAct->setEnabled(true);
muteAct->setEnabled(false);
muteAct->setCheckable(true); muteAct->setCheckable(true);
muteAct->setEnabled(false); muteAct->setChecked(false);
muteAct->setChecked(false); votePositiveAct->setEnabled(false);
votePositiveAct->setEnabled(false); voteNeutralAct->setEnabled(false);
voteNeutralAct->setEnabled(false); voteNegativeAct->setEnabled(false);
voteNegativeAct->setEnabled(false); showInPeopleAct->setEnabled(idList.count()==1);
showinpeopleAct->setEnabled(selectedItems.count()==1);
if(selectedItems.count()==1) distantChatAct->setData(QVariant::fromValue(idList));
{ sendMessageAct->setData(QVariant::fromValue(idList));
RsGxsId gxsid(selectedItems.at(0)->text(COLUMN_ID).toStdString()); muteAct->setData(QVariant::fromValue(idList));
votePositiveAct->setData(QVariant::fromValue(idList));
voteNeutralAct->setData(QVariant::fromValue(idList));
voteNegativeAct->setData(QVariant::fromValue(idList));
showInPeopleAct->setData(QVariant::fromValue(idList));
if(idList.count()==1)
{
RsGxsId gxsid = idList.at(0);
if(!gxsid.isNull() && !rsIdentity->isOwnId(gxsid)) if(!gxsid.isNull() && !rsIdentity->isOwnId(gxsid))
{ {
@ -263,49 +304,56 @@ void ChatLobbyDialog::participantsTreeWidgetCustomPopupMenu(QPoint)
muteAct->setEnabled(true); muteAct->setEnabled(true);
muteAct->setChecked(isParticipantMuted(gxsid)); muteAct->setChecked(isParticipantMuted(gxsid));
} }
} }
contextMnu.exec(QCursor::pos());
} }
void ChatLobbyDialog::voteParticipant() void ChatLobbyDialog::voteParticipant()
{ {
QList<QTreeWidgetItem*> selectedItems = ui.participantsList->selectedItems(); QAction *act = dynamic_cast<QAction*>(sender()) ;
if (selectedItems.isEmpty()) if(!act)
return;
QList<QTreeWidgetItem*>::iterator item;
QAction *act = dynamic_cast<QAction*>(sender()) ;
if(!act)
{
std::cerr << "No sender! Some bug in the code." << std::endl;
return ;
}
RsReputations::Opinion op = RsReputations::Opinion(act->data().toUInt()) ;
for (item = selectedItems.begin(); item != selectedItems.end(); ++item)
{ {
RsGxsId nickname; std::cerr << "No sender! Some bug in the code." << std::endl;
dynamic_cast<GxsIdRSTreeWidgetItem*>(*item)->getId(nickname) ; return ;
}
rsReputations->setOwnOpinion(nickname, op); QList<RsGxsId> idList = act->data().value<QList<RsGxsId>>();
std::cerr << "Giving opinion to GXS id " << nickname << " to " << op<< std::endl;
dynamic_cast<GxsIdRSTreeWidgetItem*>(*item)->forceUpdate(); RsReputations::Opinion op = RsReputations::OPINION_NEUTRAL ;
} if (act == votePositiveAct)
op = RsReputations::OPINION_POSITIVE;
if (act == voteNegativeAct)
op = RsReputations::OPINION_NEGATIVE;
for (QList<RsGxsId>::iterator item = idList.begin(); item != idList.end(); ++item)
{
rsReputations->setOwnOpinion(*item, op);
std::cerr << "Giving opinion to GXS id " << *item << " to " << op << std::endl;
}
updateParticipantsList();
} }
void ChatLobbyDialog::showInPeopleTab() void ChatLobbyDialog::showInPeopleTab()
{ {
QList<QTreeWidgetItem*> selectedItems = ui.participantsList->selectedItems(); QAction *act = dynamic_cast<QAction*>(sender()) ;
if (selectedItems.count()!=1) if(!act)
return; {
RsGxsId nickname; std::cerr << "No sender! Some bug in the code." << std::endl;
dynamic_cast<GxsIdRSTreeWidgetItem*>(*selectedItems.begin())->getId(nickname); return ;
IdDialog *idDialog = dynamic_cast<IdDialog*>(MainWindow::getPage(MainWindow::People)); }
if (!idDialog)
return ; QList<RsGxsId> idList = act->data().value<QList<RsGxsId>>();
MainWindow::showWindow(MainWindow::People); if (idList.count() != 1)
idDialog->navigate(nickname); return;
RsGxsId nickname = idList.at(0);
IdDialog *idDialog = dynamic_cast<IdDialog*>(MainWindow::getPage(MainWindow::People));
if (!idDialog)
return ;
MainWindow::showWindow(MainWindow::People);
idDialog->navigate(nickname);
} }
void ChatLobbyDialog::init(const ChatId &/*id*/, const QString &/*title*/) void ChatLobbyDialog::init(const ChatId &/*id*/, const QString &/*title*/)
@ -586,34 +634,28 @@ void ChatLobbyDialog::updateParticipantsList()
} }
/** /**
* Called when a Participant in QTree get Clicked / Changed * Called when a Participant get Clicked / Changed
* *
* Check if the Checkbox altered and Mute User * Check if the Checkbox altered and Mute User
*
* @todo auf rsid
*
* @param QTreeWidgetItem Participant to check
*/ */
void ChatLobbyDialog::changePartipationState() void ChatLobbyDialog::changeParticipationState()
{ {
QList<QTreeWidgetItem*> selectedItems = ui.participantsList->selectedItems(); QAction *act = dynamic_cast<QAction*>(sender()) ;
if(!act)
if (selectedItems.isEmpty()) { {
return; std::cerr << "No sender! Some bug in the code." << std::endl;
return ;
} }
QList<QTreeWidgetItem*>::iterator item; QList<RsGxsId> idList = act->data().value<QList<RsGxsId>>();
for (item = selectedItems.begin(); item != selectedItems.end(); ++item) {
RsGxsId gxs_id ; for (QList<RsGxsId>::iterator item = idList.begin(); item != idList.end(); ++item)
dynamic_cast<GxsIdRSTreeWidgetItem*>(*item)->getId(gxs_id) ; {
std::cerr << "check Partipation status for '" << *item << std::endl;
std::cerr << "check Partipation status for '" << gxs_id << std::endl; if (act->isChecked()) {
muteParticipant(*item);
if (muteAct->isChecked()) {
muteParticipant(gxs_id);
} else { } else {
unMuteParticipant(gxs_id); unMuteParticipant(*item);
} }
} }
@ -650,75 +692,68 @@ void ChatLobbyDialog::participantsTreeWidgetDoubleClicked(QTreeWidgetItem *item,
void ChatLobbyDialog::distantChatParticipant() void ChatLobbyDialog::distantChatParticipant()
{ {
std::cerr << " initiating distant chat" << std::endl; QAction *act = dynamic_cast<QAction*>(sender()) ;
if(!act)
{
std::cerr << "No sender! Some bug in the code." << std::endl;
return ;
}
QList<QTreeWidgetItem*> selectedItems = ui.participantsList->selectedItems(); std::cerr << " initiating distant chat" << std::endl;
if (selectedItems.isEmpty()) QList<RsGxsId> idList = act->data().value<QList<RsGxsId>>();
return; if (idList.count() != 1)
return;
if(selectedItems.size() != 1) RsGxsId gxs_id = idList.at(0);
return ; if (gxs_id.isNull())
return;
GxsIdRSTreeWidgetItem *item = dynamic_cast<GxsIdRSTreeWidgetItem*>(selectedItems.front()); RsGxsId own_id;
rsMsgs->getIdentityForChatLobby(lobbyId, own_id);
if(!item) DistantChatPeerId tunnel_id;
return ; uint32_t error_code ;
RsGxsId gxs_id ; if(! rsMsgs->initiateDistantChatConnexion(gxs_id,own_id,tunnel_id,error_code))
item->getId(gxs_id) ; {
RsGxsId own_id; QString error_str ;
switch(error_code)
rsMsgs->getIdentityForChatLobby(lobbyId, own_id); {
case RS_DISTANT_CHAT_ERROR_DECRYPTION_FAILED : error_str = tr("Decryption failed.") ; break ;
uint32_t error_code ; case RS_DISTANT_CHAT_ERROR_SIGNATURE_MISMATCH : error_str = tr("Signature mismatch") ; break ;
DistantChatPeerId tunnel_id; case RS_DISTANT_CHAT_ERROR_UNKNOWN_KEY : error_str = tr("Unknown key") ; break ;
case RS_DISTANT_CHAT_ERROR_UNKNOWN_HASH : error_str = tr("Unknown hash") ; break ;
if(! rsMsgs->initiateDistantChatConnexion(gxs_id,own_id,tunnel_id,error_code)) default:
{ error_str = tr("Unknown error.") ;
QString error_str ; }
switch(error_code) QMessageBox::warning(NULL,tr("Cannot start distant chat"),tr("Distant chat cannot be initiated:")+" "+error_str
{ +QString::number(error_code)) ;
case RS_DISTANT_CHAT_ERROR_DECRYPTION_FAILED : error_str = tr("Decryption failed.") ; break ; }
case RS_DISTANT_CHAT_ERROR_SIGNATURE_MISMATCH : error_str = tr("Signature mismatch") ; break ;
case RS_DISTANT_CHAT_ERROR_UNKNOWN_KEY : error_str = tr("Unknown key") ; break ;
case RS_DISTANT_CHAT_ERROR_UNKNOWN_HASH : error_str = tr("Unknown hash") ; break ;
default:
error_str = tr("Unknown error.") ;
}
QMessageBox::warning(NULL,tr("Cannot start distant chat"),tr("Distant chat cannot be initiated:")+" "+error_str
+QString::number(error_code)) ;
}
} }
void ChatLobbyDialog::sendMessage() void ChatLobbyDialog::sendMessage()
{ {
QAction *act = dynamic_cast<QAction*>(sender()) ;
if(!act)
{
std::cerr << "No sender! Some bug in the code." << std::endl;
return ;
}
QList<QTreeWidgetItem*> selectedItems = ui.participantsList->selectedItems(); QList<RsGxsId> idList = act->data().value<QList<RsGxsId>>();
if (selectedItems.isEmpty()) MessageComposer *nMsgDialog = MessageComposer::newMsg();
return; if (nMsgDialog == NULL)
return;
QList<QTreeWidgetItem*>::iterator item; for (QList<RsGxsId>::iterator item = idList.begin(); item != idList.end(); ++item)
for (item = selectedItems.begin(); item != selectedItems.end(); ++item) { nMsgDialog->addRecipient(MessageComposer::TO, *item);
RsGxsId gxs_id ; nMsgDialog->show();
dynamic_cast<GxsIdRSTreeWidgetItem*>(*item)->getId(gxs_id) ; nMsgDialog->activateWindow();
MessageComposer *nMsgDialog = MessageComposer::newMsg();
if (nMsgDialog == NULL) {
return;
}
nMsgDialog->addRecipient(MessageComposer::TO, RsGxsId(gxs_id));
nMsgDialog->show();
nMsgDialog->activateWindow();
/* window will destroy itself! */
}
/* window will destroy itself! */
} }

View File

@ -27,6 +27,8 @@
#include "gui/common/RSTreeWidgetItem.h" #include "gui/common/RSTreeWidgetItem.h"
#include "ChatDialog.h" #include "ChatDialog.h"
Q_DECLARE_METATYPE(RsGxsId)
class GxsIdChooser ; class GxsIdChooser ;
class QToolButton; class QToolButton;
class QWidgetAction; class QWidgetAction;
@ -51,6 +53,7 @@ public:
private slots: private slots:
void participantsTreeWidgetCustomPopupMenu( QPoint point ); void participantsTreeWidgetCustomPopupMenu( QPoint point );
void textBrowserAskContextMenu(QMenu* contextMnu, QString anchorForPosition, const QPoint point);
void inviteFriends() ; void inviteFriends() ;
void leaveLobby() ; void leaveLobby() ;
void filterChanged(const QString &text); void filterChanged(const QString &text);
@ -77,7 +80,7 @@ protected:
protected slots: protected slots:
void changeNickname(); void changeNickname();
void changePartipationState(); void changeParticipationState();
void distantChatParticipant(); void distantChatParticipant();
void participantsTreeWidgetDoubleClicked(QTreeWidgetItem *item, int column); void participantsTreeWidgetDoubleClicked(QTreeWidgetItem *item, int column);
void sendMessage(); void sendMessage();
@ -85,6 +88,7 @@ protected slots:
private: private:
void updateParticipantsList(); void updateParticipantsList();
void initParticipantsContextMenu(QMenu* contextMnu, QList<RsGxsId> idList);
void filterIds(); void filterIds();
@ -117,8 +121,8 @@ private:
QAction *actionSortByActivity; QAction *actionSortByActivity;
QWidgetAction *checkableAction; QWidgetAction *checkableAction;
QAction *sendMessageAct; QAction *sendMessageAct;
QAction *showinpeopleAct; QAction *showInPeopleAct;
GxsIdChooser *ownIdChooser ; GxsIdChooser *ownIdChooser ;
//icons cache //icons cache
QIcon bullet_red_128, bullet_grey_128, bullet_green_128, bullet_yellow_128; QIcon bullet_red_128, bullet_grey_128, bullet_green_128, bullet_yellow_128;

View File

@ -66,8 +66,6 @@
#define FMM 2.5//fontMetricsMultiplicator #define FMM 2.5//fontMetricsMultiplicator
#define PERSONID "PersonId:"
/***** /*****
* #define CHAT_DEBUG 1 * #define CHAT_DEBUG 1
*****/ *****/
@ -594,31 +592,15 @@ bool ChatWidget::eventFilter(QObject *obj, QEvent *event)
if (event->type() == QEvent::ToolTip) { if (event->type() == QEvent::ToolTip) {
QHelpEvent* helpEvent = static_cast<QHelpEvent*>(event); QHelpEvent* helpEvent = static_cast<QHelpEvent*>(event);
QTextCursor cursor = ui->textBrowser->cursorForPosition(helpEvent->pos()); QString toolTipText = ui->textBrowser->anchorForPosition(helpEvent->pos());
cursor.select(QTextCursor::WordUnderCursor); if (toolTipText.isEmpty() && !ui->textBrowser->getShowImages()){
QString toolTipText = ""; QString imageStr;
if (!cursor.selectedText().isEmpty()){ if (ui->textBrowser->checkImage(helpEvent->pos(), imageStr)) {
QRegExp rx("<a name=\"(.*)\"",Qt::CaseSensitive, QRegExp::RegExp2); toolTipText = imageStr;
rx.setMinimal(true);
QString sel=cursor.selection().toHtml();
QStringList anchors;
int pos=0;
while ((pos = rx.indexIn(sel,pos)) != -1) {
anchors << rx.cap(1);
pos += rx.matchedLength();
}
if (!anchors.isEmpty()){
toolTipText = anchors.at(0);
}
if (toolTipText.isEmpty() && !ui->textBrowser->getShowImages()){
QString imageStr;
if (ui->textBrowser->checkImage(helpEvent->pos(), imageStr)) {
toolTipText = imageStr;
}
} else if (toolTipText.startsWith(PERSONID)){
toolTipText = toolTipText.replace(PERSONID, tr("Person id: ") );
toolTipText = toolTipText.append(tr("\nDouble click on it to add his name on text writer.") );
} }
} else if (toolTipText.startsWith(PERSONID)){
toolTipText = toolTipText.replace(PERSONID, tr("Person id: ") );
toolTipText = toolTipText.append(tr("\nDouble click on it to add his name on text writer.") );
} }
if (!toolTipText.isEmpty()){ if (!toolTipText.isEmpty()){
QToolTip::showText(helpEvent->globalPos(), toolTipText); QToolTip::showText(helpEvent->globalPos(), toolTipText);
@ -710,32 +692,19 @@ bool ChatWidget::eventFilter(QObject *obj, QEvent *event)
if (event->type() == QEvent::MouseButtonDblClick) { if (event->type() == QEvent::MouseButtonDblClick) {
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event); QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
QTextCursor cursor = ui->textBrowser->cursorForPosition(mouseEvent->pos()); QString anchor = ui->textBrowser->anchorForPosition(mouseEvent->pos());
cursor.select(QTextCursor::WordUnderCursor); if (!anchor.isEmpty()){
if (!cursor.selectedText().isEmpty()){ if (anchor.startsWith(PERSONID)){
QRegExp rx("<a name=\"(.*)\"",Qt::CaseSensitive, QRegExp::RegExp2); QString strId = anchor.replace(PERSONID,"");
rx.setMinimal(true); if (strId.contains(" "))
QString sel=cursor.selection().toHtml(); strId.truncate(strId.indexOf(" "));
QStringList anchors;
int pos=0;
while ((pos = rx.indexIn(sel,pos)) != -1) {
anchors << rx.cap(1);
pos += rx.matchedLength();
}
if (!anchors.isEmpty()){ RsGxsId mId = RsGxsId(strId.toStdString());
if (anchors.at(0).startsWith(PERSONID)){ if(!mId.isNull()) {
QString strId = QString(anchors.at(0)).replace(PERSONID,""); RsIdentityDetails details;
if (strId.contains(" ")) if (rsIdentity->getIdDetails(mId, details)){
strId.truncate(strId.indexOf(" ")); QString text = QString("@").append(GxsIdDetails::getName(details)).append(" ");
ui->chatTextEdit->textCursor().insertText(text);
RsGxsId mId = RsGxsId(strId.toStdString());
if(!mId.isNull()) {
RsIdentityDetails details;
if (rsIdentity->getIdDetails(mId, details)){
QString text = QString("@").append(GxsIdDetails::getName(details)).append(" ");
ui->chatTextEdit->textCursor().insertText(text);
}
} }
} }
} }
@ -1138,6 +1107,9 @@ void ChatWidget::contextMenuTextBrowser(QPoint point)
contextMnu->addAction(ui->actionSave_image); contextMnu->addAction(ui->actionSave_image);
} }
QString anchor = ui->textBrowser->anchorForPosition(point);
emit textBrowserAskContextMenu(contextMnu, anchor, point);
contextMnu->exec(ui->textBrowser->viewport()->mapToGlobal(point)); contextMnu->exec(ui->textBrowser->viewport()->mapToGlobal(point));
delete(contextMnu); delete(contextMnu);
} }

View File

@ -37,6 +37,9 @@
#include <retroshare/rsmsgs.h> #include <retroshare/rsmsgs.h>
#include <retroshare/rsfiles.h> #include <retroshare/rsfiles.h>
//For PersonId anchor.
#define PERSONID "PersonId:"
class QAction; class QAction;
class QTextEdit; class QTextEdit;
class QPushButton; class QPushButton;
@ -137,6 +140,7 @@ signals:
void infoChanged(ChatWidget*); void infoChanged(ChatWidget*);
void newMessage(ChatWidget*); void newMessage(ChatWidget*);
void statusChanged(int); void statusChanged(int);
void textBrowserAskContextMenu(QMenu* contextMnu, QString anchorForPosition, const QPoint point);
protected: protected:
bool eventFilter(QObject *obj, QEvent *event); bool eventFilter(QObject *obj, QEvent *event);

View File

@ -243,3 +243,30 @@ bool RSTextBrowser::checkImage(QPoint pos, QString &imageStr)
} }
return false; return false;
} }
/**
* @brief RSTextBrowser::anchorForPosition Replace anchorAt that doesn't works as expected.
* @param pos Where to get anchor from text
* @return anchor If text at pos is inside anchor, else empty string.
*/
QString RSTextBrowser::anchorForPosition(const QPoint &pos) const
{
QTextCursor cursor = cursorForPosition(pos);
cursor.select(QTextCursor::WordUnderCursor);
QString anchor = "";
if (!cursor.selectedText().isEmpty()){
QRegExp rx("<a name=\"(.*)\"",Qt::CaseSensitive, QRegExp::RegExp2);
rx.setMinimal(true);
QString sel = cursor.selection().toHtml();
QStringList anchors;
int pos=0;
while ((pos = rx.indexIn(sel,pos)) != -1) {
anchors << rx.cap(1);
pos += rx.matchedLength();
}
if (!anchors.isEmpty()){
anchor = anchors.at(0);
}
}
return anchor;
}

View File

@ -24,6 +24,8 @@ public:
QPixmap getBlockedImage(); QPixmap getBlockedImage();
bool checkImage(QPoint pos, QString &imageStr); bool checkImage(QPoint pos, QString &imageStr);
bool checkImage(QPoint pos) {QString imageStr; return checkImage(pos, imageStr); } bool checkImage(QPoint pos) {QString imageStr; return checkImage(pos, imageStr); }
QString anchorForPosition(const QPoint &pos) const;
void activateLinkClick(bool active); void activateLinkClick(bool active);