Merge pull request #2760 from csoler/v0.6-BugFixing_30

added "copy http link" action to board posts when applicable
This commit is contained in:
csoler 2023-08-07 14:48:34 +02:00 committed by GitHub
commit e5b111c8bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 107 additions and 14 deletions

View File

@ -74,7 +74,7 @@ BasePostedItem::BasePostedItem( FeedHolder *feedHolder, uint32_t feedId
BasePostedItem::~BasePostedItem() BasePostedItem::~BasePostedItem()
{ {
auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(200); auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(200);
while( (mIsLoadingGroup || mIsLoadingMessage || mIsLoadingComment) while( (mIsLoadingGroup || mIsLoadingMessage || mIsLoadingComment)
&& std::chrono::steady_clock::now() < timeout) && std::chrono::steady_clock::now() < timeout)
{ {

View File

@ -22,6 +22,7 @@
#include <QMenu> #include <QMenu>
#include <QSignalMapper> #include <QSignalMapper>
#include <QPainter> #include <QPainter>
#include <QClipboard>
#include <QMessageBox> #include <QMessageBox>
#include "retroshare/rsgxscircles.h" #include "retroshare/rsgxscircles.h"
@ -72,6 +73,7 @@ static const int POSTED_TABS_POSTS = 1;
// //
#define IMAGE_COPYLINK ":/images/copyrslink.png" #define IMAGE_COPYLINK ":/images/copyrslink.png"
#define IMAGE_AUTHOR ":/images/user/personal64.png" #define IMAGE_AUTHOR ":/images/user/personal64.png"
#define IMAGE_COPYHTTP ":/images/emblem-web.png"
Q_DECLARE_METATYPE(RsPostedPost); Q_DECLARE_METATYPE(RsPostedPost);
@ -340,7 +342,18 @@ void PostedListWidgetWithModel::postContextMenu(const QPoint& point)
// 2 - generate the menu for that post. // 2 - generate the menu for that post.
RsPostedPost post = index.data(Qt::UserRole).value<RsPostedPost>() ;
menu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyMessageLink()))->setData(index); menu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyMessageLink()))->setData(index);
QByteArray urlarray(post.mLink.c_str());
QUrl url = QUrl::fromEncoded(urlarray.trimmed());
std::cerr << "Using link: \"" << post.mLink << "\"" << std::endl;
if(url.scheme()=="http" || url.scheme()=="https")
menu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_COPYHTTP), tr("Copy http Link"), this, SLOT(copyHttpLink()))->setData(index);
menu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_AUTHOR), tr("Show author in People tab"), this, SLOT(showAuthorInPeople()))->setData(index); menu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_AUTHOR), tr("Show author in People tab"), this, SLOT(showAuthorInPeople()))->setData(index);
#ifdef TODO #ifdef TODO
@ -456,6 +469,31 @@ void PostedListWidgetWithModel::showAuthorInPeople()
MainWindow::showWindow(MainWindow::People); MainWindow::showWindow(MainWindow::People);
idDialog->navigate(RsGxsId(post.mMeta.mAuthorId)); idDialog->navigate(RsGxsId(post.mMeta.mAuthorId));
} }
void PostedListWidgetWithModel::copyHttpLink()
{
try
{
if (groupId().isNull())
throw std::runtime_error("No channel currently selected!");
QModelIndex index = qobject_cast<QAction*>(QObject::sender())->data().toModelIndex();
if(!index.isValid())
throw std::runtime_error("No post under mouse!");
RsPostedPost post = index.data(Qt::UserRole).value<RsPostedPost>() ;
if(post.mMeta.mMsgId.isNull())
throw std::runtime_error("Post has empty MsgId!");
QApplication::clipboard()->setText(QString::fromStdString(post.mLink)) ;
QMessageBox::information(NULL,tr("information"),tr("The Retrohare link was copied to your clipboard.")) ;
}
catch(std::exception& e)
{
QMessageBox::critical(NULL,tr("Link creation error"),tr("Link could not be created: ")+e.what());
}
}
void PostedListWidgetWithModel::copyMessageLink() void PostedListWidgetWithModel::copyMessageLink()
{ {
try try
@ -823,6 +861,7 @@ void PostedListWidgetWithModel::insertBoardDetails(const RsPostedGroup& group)
ui->subscribeToolButton->setText(tr("Subscribe")); ui->subscribeToolButton->setText(tr("Subscribe"));
ui->infoPosts->setText(QString::number(group.mMeta.mVisibleMsgCount)); ui->infoPosts->setText(QString::number(group.mMeta.mVisibleMsgCount));
ui->poplabel->setText(QString::number(group.mMeta.mPop));
if(group.mMeta.mLastPost==0) if(group.mMeta.mLastPost==0)
ui->infoLastPost->setText(tr("Never")); ui->infoLastPost->setText(tr("Never"));

View File

@ -147,6 +147,7 @@ private slots:
void settingsChanged(); void settingsChanged();
void postPostLoad(); void postPostLoad();
void copyMessageLink(); void copyMessageLink();
void copyHttpLink();
void nextPosts(); void nextPosts();
void prevPosts(); void prevPosts();
void filterItems(QString s); void filterItems(QString s);

View File

@ -54,7 +54,7 @@
<string notr="true">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt; <string notr="true">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt; &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; } p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt; &lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt;&quot;&gt;Description&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> &lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt;&quot;&gt;Description&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
<property name="textInteractionFlags"> <property name="textInteractionFlags">
@ -84,8 +84,11 @@ p, li { white-space: pre-wrap; }
<bold>true</bold> <bold>true</bold>
</font> </font>
</property> </property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Maximum number of data items (including posts, comments, votes) across friend nodes.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text"> <property name="text">
<string>Contributions:</string> <string>Items (at friends):</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -179,6 +182,9 @@ p, li { white-space: pre-wrap; }
<bold>true</bold> <bold>true</bold>
</font> </font>
</property> </property>
<property name="toolTip">
<string>Number of subscribed friend nodes</string>
</property>
<property name="text"> <property name="text">
<string>Popularity:</string> <string>Popularity:</string>
</property> </property>
@ -615,8 +621,8 @@ p, li { white-space: pre-wrap; }
</customwidget> </customwidget>
</customwidgets> </customwidgets>
<resources> <resources>
<include location="../icons.qrc"/>
<include location="Posted_images.qrc"/> <include location="Posted_images.qrc"/>
<include location="../icons.qrc"/>
</resources> </resources>
<connections/> <connections/>
</ui> </ui>

View File

@ -83,6 +83,19 @@ GxsForumMsgItem::GxsForumMsgItem(FeedHolder *feedHolder, uint32_t feedId, const
GxsForumMsgItem::~GxsForumMsgItem() GxsForumMsgItem::~GxsForumMsgItem()
{ {
auto timeout = std::chrono::steady_clock::now() + std::chrono::milliseconds(300);
while( (mLoadingGroup || mLoadingMessage || mLoadingSetAsRead || mLoadingParentMessage)
&& std::chrono::steady_clock::now() < timeout)
{
RsDbg() << __PRETTY_FUNCTION__ << " is Waiting for "
<< (mLoadingGroup ? "Group " : "")
<< (mLoadingMessage ? "Message " : "")
<< (mLoadingParentMessage ? "Parent message " : "")
<< (mLoadingSetAsRead ? "Set as read" : "")
<< "loading." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
delete(ui); delete(ui);
} }
@ -167,6 +180,8 @@ QString GxsForumMsgItem::groupName()
void GxsForumMsgItem::loadGroup() void GxsForumMsgItem::loadGroup()
{ {
mLoadingGroup = true;
RsThread::async([this]() RsThread::async([this]()
{ {
// 1 - get group data // 1 - get group data
@ -199,6 +214,7 @@ void GxsForumMsgItem::loadGroup()
* after a blocking call to RetroShare API complete */ * after a blocking call to RetroShare API complete */
setGroup(group); setGroup(group);
mLoadingGroup = false;
}, this ); }, this );
}); });
@ -210,6 +226,7 @@ void GxsForumMsgItem::loadMessage()
std::cerr << "GxsForumMsgItem::loadMessage(): messageId=" << messageId() << " groupId=" << groupId() ; std::cerr << "GxsForumMsgItem::loadMessage(): messageId=" << messageId() << " groupId=" << groupId() ;
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
mLoadingMessage = true;
RsThread::async([this]() RsThread::async([this]()
{ {
@ -244,6 +261,7 @@ void GxsForumMsgItem::loadMessage()
* after a blocking call to RetroShare API complete */ * after a blocking call to RetroShare API complete */
setMessage(msg); setMessage(msg);
mLoadingMessage = false;
}, this ); }, this );
}); });
@ -255,6 +273,7 @@ void GxsForumMsgItem::loadParentMessage(const RsGxsMessageId& parent_msg)
std::cerr << "GxsForumMsgItem::loadParentMessage()"; std::cerr << "GxsForumMsgItem::loadParentMessage()";
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
mLoadingParentMessage = true;
RsThread::async([parent_msg,this]() RsThread::async([parent_msg,this]()
{ {
@ -291,6 +310,8 @@ void GxsForumMsgItem::loadParentMessage(const RsGxsMessageId& parent_msg)
mParentMessage = msg; mParentMessage = msg;
fillParentMessage(); fillParentMessage();
mLoadingParentMessage = false;
}, this ); }, this );
}); });
} }
@ -480,6 +501,7 @@ void GxsForumMsgItem::setAsRead(bool doUpdate)
} }
mCloseOnRead = false; mCloseOnRead = false;
mLoadingSetAsRead = true;
RsThread::async( [this, doUpdate]() { RsThread::async( [this, doUpdate]() {
RsGxsGrpMsgIdPair msgPair = std::make_pair(groupId(), messageId()); RsGxsGrpMsgIdPair msgPair = std::make_pair(groupId(), messageId());
@ -489,6 +511,7 @@ void GxsForumMsgItem::setAsRead(bool doUpdate)
if (doUpdate) { if (doUpdate) {
RsQThreadUtils::postToObject( [this]() { RsQThreadUtils::postToObject( [this]() {
setReadStatus(false, true); setReadStatus(false, true);
mLoadingSetAsRead = false;
} ); } );
} }
}); });

View File

@ -87,6 +87,10 @@ private:
private: private:
bool mInFill; bool mInFill;
bool mCloseOnRead; bool mCloseOnRead;
bool mLoadingMessage;
bool mLoadingParentMessage;
bool mLoadingGroup;
bool mLoadingSetAsRead;
RsGxsForumGroup mGroup; RsGxsForumGroup mGroup;
RsGxsForumMsg mMessage; RsGxsForumMsg mMessage;

View File

@ -193,17 +193,25 @@ void GxsIdTreeItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem
QStyleOptionViewItem ownOption (option); QStyleOptionViewItem ownOption (option);
initStyleOption(&ownOption, index); initStyleOption(&ownOption, index);
RsGxsId id(index.data(Qt::UserRole).toString().toStdString()); QString dt = index.data(Qt::UserRole).toString();
QString cmt; RsGxsId id(index.data(Qt::UserRole).toString().toStdString());
if(id.isNull()) // This is a trick: UserRole in Mail generally is 0000...00000 when there is a notification, and is empty when there are multiple
// destinations at once. This is not so nice to do that this way, but it's a quick workaround to a more complex method involving an
// additional Qt role only to determine the number of destinations.
if(dt == "")
ownOption.icon = FilesDefs::getIconFromQtResourcePath(":/icons/svg/people2.svg");
else if(id.isNull())
{
if (ownOption.icon.isNull())
ownOption.icon = FilesDefs::getIconFromQtResourcePath(":/icons/notification.svg");
}
else
{ {
if (ownOption.icon.isNull()) QString cmt;
ownOption.icon = FilesDefs::getIconFromQtResourcePath(":/icons/notification.svg");
} if(! computeNameIconAndComment(id,ownOption.text,ownOption.icon,cmt))
else
{
if(! computeNameIconAndComment(id,ownOption.text,ownOption.icon,cmt))
{ {
if(mReloadPeriod > 3) if(mReloadPeriod > 3)
{ {

View File

@ -15,6 +15,7 @@
<file>icons/svg/display_options.svg</file> <file>icons/svg/display_options.svg</file>
<file>icons/svg/listlayout.svg</file> <file>icons/svg/listlayout.svg</file>
<file>icons/svg/gridlayout.svg</file> <file>icons/svg/gridlayout.svg</file>
<file>icons/svg/people2.svg</file>
<file>icons/stars/star0.png</file> <file>icons/stars/star0.png</file>
<file>icons/stars/star1.png</file> <file>icons/stars/star1.png</file>
<file>icons/stars/star2.png</file> <file>icons/stars/star2.png</file>

View File

@ -579,7 +579,18 @@ QVariant RsMessageModel::userRole(const Rs::Msgs::MsgInfoSummary& fmpe,int col)
{ {
case COLUMN_THREAD_AUTHOR: return QVariant(QString::fromStdString(fmpe.from.toStdString())); case COLUMN_THREAD_AUTHOR: return QVariant(QString::fromStdString(fmpe.from.toStdString()));
case COLUMN_THREAD_MSGID: return QVariant(QString::fromStdString(fmpe.msgId)); case COLUMN_THREAD_MSGID: return QVariant(QString::fromStdString(fmpe.msgId));
case COLUMN_THREAD_TO: return QVariant(QString::fromStdString(fmpe.to.toStdString())); case COLUMN_THREAD_TO:
{
// First check if the .to field is filled.
if(!fmpe.to.toStdString().empty())
return QVariant(QString::fromStdString(fmpe.to.toStdString()));
// In the Send box, .to is never filled. In this case we look into destinations.
if(fmpe.destinations.size()==1)
return QVariant(QString::fromStdString((*fmpe.destinations.begin()).toStdString()));
}
default: default:
return QVariant(); return QVariant();
} }