mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-01-12 16:09:37 -05:00
Merge branch 'RetroShare:master' into browse_image
This commit is contained in:
commit
9c950affcf
@ -1120,8 +1120,7 @@ void TransfersDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> eve
|
||||
break;
|
||||
|
||||
SoundManager::play(SOUND_DOWNLOAD_COMPLETE);
|
||||
if (Settings->getNotifyFlags() & RS_POPUP_DOWNLOAD)
|
||||
NotifyQt::getInstance()->addToaster(RS_POPUP_DOWNLOAD, fe->mHash.toStdString(), nfo.fname.c_str(),"");
|
||||
NotifyQt::getInstance()->addToaster(RS_POPUP_DOWNLOAD, fe->mHash.toStdString(), nfo.fname.c_str(),"");
|
||||
}
|
||||
[[fallthrough]];
|
||||
|
||||
|
@ -301,8 +301,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>634</width>
|
||||
<height>538</height>
|
||||
<width>456</width>
|
||||
<height>731</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="scrollAreaWidgetContentsVLayout">
|
||||
@ -338,21 +338,14 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>518</width>
|
||||
<height>17</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="info_Frame_Invite">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="palette">
|
||||
<palette>
|
||||
<active>
|
||||
@ -490,6 +483,9 @@
|
||||
<property name="text">
|
||||
<string notr="true">Invite messages stay into your Outbox until an acknowledgement of receipt has been received.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
@ -895,9 +891,12 @@ border-image: url(:/images/closepressed.png)
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<widget class="QCheckBox" name="autoBanIdentities_CB">
|
||||
<property name="text">
|
||||
<property name="toolTip">
|
||||
<string>Auto-Ban all identities signed by the same node</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Auto-Ban profile</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
|
@ -441,8 +441,7 @@ void NewsFeed::handleConnectionEvent(std::shared_ptr<const RsEvent> event)
|
||||
{
|
||||
case RsConnectionEventCode::PEER_CONNECTED:
|
||||
addFeedItemIfUnique(new PeerItem(this, NEWSFEED_PEERLIST, e.mSslId, PEER_TYPE_CONNECT, false), true);
|
||||
if (Settings->getNotifyFlags() & RS_POPUP_CONNECT)
|
||||
NotifyQt::getInstance()->addToaster(RS_POPUP_CONNECT, e.mSslId.toStdString().c_str(), "", "");
|
||||
NotifyQt::getInstance()->addToaster(RS_POPUP_CONNECT, e.mSslId.toStdString().c_str(), "", "");
|
||||
break;
|
||||
case RsConnectionEventCode::PEER_DISCONNECTED: // not handled yet
|
||||
break;
|
||||
@ -508,8 +507,7 @@ void NewsFeed::handleSecurityEvent(std::shared_ptr<const RsEvent> event)
|
||||
if (Settings->getMessageFlags() & RS_MESSAGE_CONNECT_ATTEMPT)
|
||||
MessageComposer::addConnectAttemptMsg(e.mPgpId, e.mSslId, QString::fromStdString(det.name + "(" + det.location + ")"));
|
||||
|
||||
if (Settings->getNotifyFlags() & RS_POPUP_CONNECT_ATTEMPT)
|
||||
NotifyQt::getInstance()->addToaster(RS_POPUP_CONNECT_ATTEMPT, e.mPgpId.toStdString().c_str(), det.location, e.mSslId.toStdString().c_str());
|
||||
NotifyQt::getInstance()->addToaster(RS_POPUP_CONNECT_ATTEMPT, e.mPgpId.toStdString().c_str(), det.location, e.mSslId.toStdString().c_str());
|
||||
}
|
||||
|
||||
void NewsFeed::testFeeds(uint /*notifyFlags*/)
|
||||
|
@ -43,6 +43,7 @@
|
||||
|
||||
#define LINK_IMAGE ":/images/thumb-link.png"
|
||||
|
||||
|
||||
// #ifdef DEBUG_BOARDPOSTDISPLAYWIDGET 1
|
||||
|
||||
/** Constructor */
|
||||
@ -58,6 +59,7 @@ BoardPostDisplayWidgetBase::BoardPostDisplayWidgetBase(const RsPostedPost& post,
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void BoardPostDisplayWidgetBase::setCommentsSize(int comNb)
|
||||
{
|
||||
QString sComButText = tr("Comment");
|
||||
@ -168,6 +170,7 @@ void BoardPostDisplayWidgetBase::baseSetup()
|
||||
|
||||
readButton()->setChecked(false);
|
||||
|
||||
#ifdef TO_REMOVE
|
||||
QMenu *menu = new QMenu();
|
||||
menu->addAction(CopyLinkAction);
|
||||
menu->addSeparator();
|
||||
@ -175,6 +178,7 @@ void BoardPostDisplayWidgetBase::baseSetup()
|
||||
shareButton()->setPopupMode(QToolButton::InstantPopup);
|
||||
|
||||
connect(menu,SIGNAL(aboutToShow()),this,SLOT(handleShareButtonClicked()));
|
||||
#endif
|
||||
|
||||
RsReputationLevel overall_reputation = rsReputations->overallReputationLevel(mPost.mMeta.mAuthorId);
|
||||
bool redacted = (overall_reputation == RsReputationLevel::LOCALLY_NEGATIVE);
|
||||
@ -182,7 +186,9 @@ void BoardPostDisplayWidgetBase::baseSetup()
|
||||
if(redacted)
|
||||
{
|
||||
commentButton()->setDisabled(true);
|
||||
#ifdef TO_REMOVE
|
||||
shareButton()->setDisabled(true);
|
||||
#endif
|
||||
voteUpButton()->setDisabled(true);
|
||||
voteDownButton()->setDisabled(true);
|
||||
fromLabel()->setId(mPost.mMeta.mAuthorId);
|
||||
@ -275,6 +281,7 @@ void BoardPostDisplayWidgetBase::baseSetup()
|
||||
emit sizeChanged(this);
|
||||
#endif
|
||||
}
|
||||
#ifdef TO_REMOVE
|
||||
void BoardPostDisplayWidgetBase::handleShareButtonClicked()
|
||||
{
|
||||
emit shareButtonClicked();
|
||||
@ -284,6 +291,8 @@ void BoardPostDisplayWidgetBase::handleCopyLinkClicked()
|
||||
{
|
||||
emit copylinkClicked();
|
||||
}
|
||||
#endif
|
||||
|
||||
//===================================================================================================================================
|
||||
//== class BoardPostDisplayWidget ==
|
||||
//===================================================================================================================================
|
||||
@ -292,6 +301,7 @@ BoardPostDisplayWidget_compact::BoardPostDisplayWidget_compact(const RsPostedPos
|
||||
: BoardPostDisplayWidgetBase(post,display_flags,parent), ui(new Ui::BoardPostDisplayWidget_compact())
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->shareButton->hide();
|
||||
BoardPostDisplayWidget_compact::setup();
|
||||
}
|
||||
|
||||
@ -400,10 +410,10 @@ QLabel *BoardPostDisplayWidget_compact::newLabel() { return ui->ne
|
||||
QToolButton *BoardPostDisplayWidget_compact::readButton() { return ui->readButton; }
|
||||
GxsIdLabel *BoardPostDisplayWidget_compact::fromLabel() { return ui->fromLabel; }
|
||||
QLabel *BoardPostDisplayWidget_compact::dateLabel() { return ui->dateLabel; }
|
||||
QLabel *BoardPostDisplayWidget_compact::titleLabel() { return ui->titleLabel; }
|
||||
ElidedLabel *BoardPostDisplayWidget_compact::titleLabel() { return ui->titleLabel; }
|
||||
QLabel *BoardPostDisplayWidget_compact::scoreLabel() { return ui->scoreLabel; }
|
||||
QLabel *BoardPostDisplayWidget_compact::notes() { return ui->notes; }
|
||||
QToolButton *BoardPostDisplayWidget_compact::shareButton() { return ui->shareButton; }
|
||||
//QToolButton *BoardPostDisplayWidget_compact::shareButton() { return ui->shareButton; }
|
||||
QLabel *BoardPostDisplayWidget_compact::pictureLabel() { return ui->pictureLabel; }
|
||||
QFrame *BoardPostDisplayWidget_compact::feedFrame() { return ui->feedFrame; }
|
||||
|
||||
@ -415,7 +425,8 @@ BoardPostDisplayWidget_card::BoardPostDisplayWidget_card(const RsPostedPost& pos
|
||||
: BoardPostDisplayWidgetBase(post,display_flags,parent), ui(new Ui::BoardPostDisplayWidget_card())
|
||||
{
|
||||
ui->setupUi(this);
|
||||
BoardPostDisplayWidget_card::setup();
|
||||
ui->shareButton->hide();
|
||||
BoardPostDisplayWidget_card::setup();
|
||||
}
|
||||
|
||||
BoardPostDisplayWidget_card::~BoardPostDisplayWidget_card()
|
||||
@ -469,10 +480,10 @@ QLabel *BoardPostDisplayWidget_card::newLabel() { return ui->newLa
|
||||
QToolButton *BoardPostDisplayWidget_card::readButton() { return ui->readButton; }
|
||||
GxsIdLabel *BoardPostDisplayWidget_card::fromLabel() { return ui->fromLabel; }
|
||||
QLabel *BoardPostDisplayWidget_card::dateLabel() { return ui->dateLabel; }
|
||||
QLabel *BoardPostDisplayWidget_card::titleLabel() { return ui->titleLabel; }
|
||||
ElidedLabel *BoardPostDisplayWidget_card::titleLabel() { return ui->titleLabel; }
|
||||
QLabel *BoardPostDisplayWidget_card::scoreLabel() { return ui->scoreLabel; }
|
||||
QLabel *BoardPostDisplayWidget_card::notes() { return ui->notes; }
|
||||
QToolButton *BoardPostDisplayWidget_card::shareButton() { return ui->shareButton; }
|
||||
//QToolButton *BoardPostDisplayWidget_card::shareButton() { return ui->shareButton; }
|
||||
QLabel *BoardPostDisplayWidget_card::pictureLabel() { return ui->pictureLabel; }
|
||||
QFrame *BoardPostDisplayWidget_card::feedFrame() { return ui->feedFrame; }
|
||||
|
||||
|
@ -37,6 +37,7 @@ class QToolButton;
|
||||
class QTextEdit;
|
||||
class ClickableLabel;
|
||||
class GxsIdLabel;
|
||||
class ElidedLabel;
|
||||
|
||||
struct RsPostedPost;
|
||||
|
||||
@ -72,14 +73,14 @@ protected:
|
||||
virtual QToolButton *commentButton() =0;
|
||||
virtual QToolButton *voteDownButton() =0;
|
||||
virtual QLabel *newLabel() =0;
|
||||
virtual QLabel *titleLabel()=0;
|
||||
virtual ElidedLabel *titleLabel()=0;
|
||||
virtual GxsIdLabel *fromLabel()=0;
|
||||
virtual QLabel *dateLabel()=0;
|
||||
virtual QLabel *scoreLabel() =0;
|
||||
virtual QLabel *notes() =0;
|
||||
virtual QLabel *pictureLabel()=0;
|
||||
virtual QToolButton *readButton() =0;
|
||||
virtual QToolButton *shareButton() =0;
|
||||
// virtual QToolButton *shareButton() =0;
|
||||
virtual QFrame *feedFrame() =0;
|
||||
|
||||
protected slots:
|
||||
@ -89,9 +90,10 @@ protected slots:
|
||||
void makeUpVote() ;
|
||||
void makeDownVote() ;
|
||||
void setCommentsSize(int comNb) ;
|
||||
#ifdef TO_REMOVE
|
||||
void handleShareButtonClicked() ;
|
||||
void handleCopyLinkClicked() ;
|
||||
|
||||
#endif
|
||||
|
||||
signals:
|
||||
void changeReadStatusRequested(const RsGxsMessageId&,bool);
|
||||
@ -99,8 +101,8 @@ signals:
|
||||
void expand(RsGxsMessageId,bool);
|
||||
void commentsRequested(const RsGxsMessageId&,bool);
|
||||
void thumbnailOpenned();
|
||||
void shareButtonClicked();
|
||||
void copylinkClicked();
|
||||
// void shareButtonClicked();
|
||||
// void copylinkClicked();
|
||||
|
||||
protected:
|
||||
RsPostedPost mPost;
|
||||
@ -123,12 +125,14 @@ public:
|
||||
QLabel *newLabel() override;
|
||||
GxsIdLabel *fromLabel() override;
|
||||
QLabel *dateLabel() override;
|
||||
QLabel *titleLabel() override;
|
||||
ElidedLabel *titleLabel() override;
|
||||
QLabel *scoreLabel() override;
|
||||
QLabel *notes() override;
|
||||
QLabel *pictureLabel() override;
|
||||
QToolButton *readButton() override;
|
||||
#ifdef TO_REMOVE
|
||||
QToolButton *shareButton() override;
|
||||
#endif
|
||||
QFrame *feedFrame() override;
|
||||
|
||||
public slots:
|
||||
@ -162,11 +166,11 @@ public:
|
||||
QLabel *newLabel() override;
|
||||
GxsIdLabel *fromLabel() override;
|
||||
QLabel *dateLabel() override;
|
||||
QLabel *titleLabel() override;
|
||||
ElidedLabel *titleLabel() override;
|
||||
QLabel *scoreLabel() override;
|
||||
QLabel *notes() override;
|
||||
QToolButton *readButton() override;
|
||||
QToolButton *shareButton() override;
|
||||
// QToolButton *shareButton() override;
|
||||
QLabel *pictureLabel() override;
|
||||
QFrame *feedFrame() override;
|
||||
|
||||
|
@ -305,7 +305,7 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="titleLabel">
|
||||
<widget class="ElidedLabel" name="titleLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
@ -464,6 +464,12 @@
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>ElidedLabel</class>
|
||||
<extends>QLabel</extends>
|
||||
<header>gui/common/ElidedLabel.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>GxsIdLabel</class>
|
||||
<extends>QLabel</extends>
|
||||
|
@ -211,7 +211,7 @@
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="titleLabel">
|
||||
<widget class="ElidedLabel" name="titleLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
@ -515,6 +515,12 @@
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>ElidedLabel</class>
|
||||
<extends>QLabel</extends>
|
||||
<header>gui/common/ElidedLabel.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>GxsIdLabel</class>
|
||||
<extends>QLabel</extends>
|
||||
|
@ -19,6 +19,7 @@
|
||||
*******************************************************************************/
|
||||
|
||||
#include <QBuffer>
|
||||
#include <QClipboard>
|
||||
#include <QMessageBox>
|
||||
#include <QByteArray>
|
||||
#include <QStringList>
|
||||
@ -59,6 +60,7 @@ PostedCreatePostDialog::PostedCreatePostDialog(RsPosted *posted, const RsGxsGrou
|
||||
|
||||
connect(ui->postButton, SIGNAL(clicked()), this, SLOT(createPost()));
|
||||
connect(ui->addPicButton, SIGNAL(clicked() ), this , SLOT(addPicture()));
|
||||
connect(ui->pasteButton, SIGNAL(clicked() ), this , SLOT(pastePicture()));
|
||||
connect(ui->RichTextEditWidget, SIGNAL(textSizeOk(bool)),ui->postButton, SLOT(setEnabled(bool)));
|
||||
|
||||
ui->headerFrame->setHeaderImage(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/postedlinks.png"));
|
||||
@ -256,6 +258,35 @@ void PostedCreatePostDialog::addPicture()
|
||||
|
||||
}
|
||||
|
||||
void PostedCreatePostDialog::pastePicture()
|
||||
{
|
||||
imagefilename = "";
|
||||
imagebytes.clear();
|
||||
QPixmap empty;
|
||||
ui->imageLabel->setPixmap(empty);
|
||||
|
||||
// paste picture from clipboard
|
||||
const QClipboard *clipboard = QApplication::clipboard();
|
||||
const QMimeData *mimeData = clipboard->mimeData();
|
||||
|
||||
QImage image;
|
||||
if (mimeData->hasImage()) {
|
||||
image = (qvariant_cast<QImage>(mimeData->imageData()));
|
||||
|
||||
QImage opt;
|
||||
if(ImageUtil::optimizeSizeBytes(imagebytes, image, opt,"JPG", 640*480, MAXMESSAGESIZE - 2000)) { //Leave space for other stuff
|
||||
ui->imageLabel->setPixmap(QPixmap::fromImage(opt));
|
||||
ui->stackedWidgetPicture->setCurrentIndex(IMG_PICTURE);
|
||||
ui->removeButton->show();
|
||||
}
|
||||
} else {
|
||||
QMessageBox::information(nullptr,tr("No clipboard image found."),tr("There is no image data in the clipboard to paste"));
|
||||
imagefilename = "";
|
||||
imagebytes.clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int PostedCreatePostDialog::viewMode()
|
||||
{
|
||||
if (ui->viewPostButton->isChecked()) {
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include <QDialog>
|
||||
#include <gui/common/HashBox.h>
|
||||
#include "retroshare/rsposted.h"
|
||||
#include "util/RichTextEdit.h"
|
||||
|
||||
namespace Ui {
|
||||
class PostedCreatePostDialog;
|
||||
@ -50,6 +49,7 @@ private:
|
||||
private slots:
|
||||
void createPost();
|
||||
void addPicture();
|
||||
void pastePicture();
|
||||
void on_removeButton_clicked();
|
||||
void fileHashingFinished(QList<HashedFile> hashedFiles);
|
||||
void reject() override; //QDialog
|
||||
|
@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>575</width>
|
||||
<height>518</height>
|
||||
<height>468</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -152,8 +152,8 @@
|
||||
<property name="topMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item row="1" column="0">
|
||||
<spacer name="addPicLeft_HSpacer">
|
||||
<item row="1" column="2">
|
||||
<spacer name="addPicRight_HSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
@ -182,15 +182,8 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="3">
|
||||
<widget class="QLabel" name="sizeWarningLabel">
|
||||
<property name="text">
|
||||
<string>Post size is limited to 32 KB, pictures will be downscaled.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<spacer name="addPicRight_HSpacer">
|
||||
<item row="1" column="0">
|
||||
<spacer name="addPicLeft_HSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
@ -203,6 +196,13 @@
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="3">
|
||||
<widget class="QLabel" name="sizeWarningLabel">
|
||||
<property name="text">
|
||||
<string>Post size is limited to 32 KB, pictures will be downscaled.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="3">
|
||||
<spacer name="addPic_VSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
@ -215,6 +215,26 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="pasteButton">
|
||||
<property name="toolTip">
|
||||
<string>Paste image from clipboard</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Paste Picture</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../icons.qrc">
|
||||
<normaloff>:/icons/svg/paste_image.svg</normaloff>:/icons/svg/paste_image.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
@ -225,7 +245,7 @@
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>267</width>
|
||||
<height>138</height>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
|
@ -253,7 +253,7 @@
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="titleLabel">
|
||||
<widget class="ElidedLabel" name="titleLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
|
@ -219,7 +219,7 @@ QWidget *PostedPostDelegate::createEditor(QWidget *parent, const QStyleOptionVie
|
||||
else
|
||||
w = new BoardPostDisplayWidget_card(post,displayFlags(post.mMeta.mMsgId),parent);
|
||||
|
||||
QObject::connect(w,SIGNAL(vote(RsGxsGrpMsgIdPair,bool)),mPostListWidget,SLOT(voteMsg(RsGxsGrpMsgIdPair,bool)));
|
||||
QObject::connect(w,SIGNAL(vote(RsGxsGrpMsgIdPair,bool)),mPostListWidget,SLOT(voteMsg(RsGxsGrpMsgIdPair,bool)));
|
||||
QObject::connect(w,SIGNAL(expand(RsGxsMessageId,bool)),this,SLOT(expandItem(RsGxsMessageId,bool)));
|
||||
QObject::connect(w,SIGNAL(commentsRequested(RsGxsMessageId,bool)),mPostListWidget,SLOT(openComments(RsGxsMessageId)));
|
||||
QObject::connect(w,SIGNAL(changeReadStatusRequested(RsGxsMessageId,bool)),mPostListWidget,SLOT(changeReadStatus(RsGxsMessageId,bool)));
|
||||
@ -230,7 +230,6 @@ QWidget *PostedPostDelegate::createEditor(QWidget *parent, const QStyleOptionVie
|
||||
QObject::connect(w,SIGNAL(expand(RsGxsMessageId,bool)),this,SLOT(markCurrentPostAsRead()));
|
||||
QObject::connect(w,SIGNAL(commentsRequested(RsGxsMessageId,bool)),mPostListWidget,SLOT(markCurrentPostAsRead()));
|
||||
QObject::connect(w,SIGNAL(shareButtonClicked()),mPostListWidget,SLOT(markCurrentPostAsRead()));
|
||||
QObject::connect(w,SIGNAL(copylinkClicked()),mPostListWidget,SLOT(copyMessageLink()));
|
||||
|
||||
w->setGeometry(option.rect);
|
||||
w->adjustSize();
|
||||
@ -277,7 +276,6 @@ PostedListWidgetWithModel::PostedListWidgetWithModel(const RsGxsGroupId& postedI
|
||||
connect(ui->nextButton,SIGNAL(clicked()),this,SLOT(nextPosts()));
|
||||
connect(ui->prevButton,SIGNAL(clicked()),this,SLOT(prevPosts()));
|
||||
|
||||
connect(ui->postsTree,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(postContextMenu(QPoint)));
|
||||
connect(ui->viewModeButton,SIGNAL(clicked()),this,SLOT(switchDisplayMode()));
|
||||
|
||||
connect(mPostedPostsModel,SIGNAL(boardPostsLoaded()),this,SLOT(postPostLoad()));
|
||||
@ -296,7 +294,11 @@ PostedListWidgetWithModel::PostedListWidgetWithModel(const RsGxsGroupId& postedI
|
||||
|
||||
connect(ui->postsTree,SIGNAL(sizeChanged(QSize)),this,SLOT(handlePostsTreeSizeChange(QSize)));
|
||||
|
||||
/* load settings */
|
||||
ui->postsTree->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
//QObject::connect(this,SIGNAL(copylinkClicked()),this,SLOT(copyMessageLink()));
|
||||
connect(ui->postsTree,SIGNAL(customContextMenuRequested(const QPoint&)),this,SLOT(postContextMenu(const QPoint&)));
|
||||
|
||||
/* load settings */
|
||||
processSettings(true);
|
||||
|
||||
/* Initialize subscribe button */
|
||||
@ -325,6 +327,32 @@ PostedListWidgetWithModel::PostedListWidgetWithModel(const RsGxsGroupId& postedI
|
||||
}, mEventHandlerId, RsEventType::GXS_POSTED );
|
||||
}
|
||||
|
||||
void PostedListWidgetWithModel::postContextMenu(const QPoint& point)
|
||||
{
|
||||
QMenu menu(this);
|
||||
|
||||
// 1 - check that we are clicking on a post
|
||||
|
||||
QModelIndex index = ui->postsTree->indexAt(point);
|
||||
|
||||
if(!index.isValid())
|
||||
return;
|
||||
|
||||
// 2 - generate the menu for that post.
|
||||
|
||||
menu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyMessageLink()))->setData(index);
|
||||
menu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_AUTHOR), tr("Show author in People tab"), this, SLOT(showAuthorInPeople()))->setData(index);
|
||||
|
||||
#ifdef TODO
|
||||
// This feature is not implemented yet in libretroshare.
|
||||
|
||||
if(IS_GROUP_PUBLISHER(mGroup.mMeta.mSubscribeFlags))
|
||||
menu.addAction(FilesDefs::getIconFromQtResourcePath(":/images/edit_16.png"), tr("Edit"), this, SLOT(editPost()));
|
||||
#endif
|
||||
|
||||
menu.exec(QCursor::pos());
|
||||
}
|
||||
|
||||
void PostedListWidgetWithModel::switchDisplayMode()
|
||||
{
|
||||
if(mPostedPostsDelegate->getDisplayMode() == BoardPostDisplayWidget_compact::DISPLAY_MODE_CARD)
|
||||
@ -403,7 +431,7 @@ void PostedListWidgetWithModel::prevPosts()
|
||||
|
||||
void PostedListWidgetWithModel::showAuthorInPeople()
|
||||
{
|
||||
QModelIndex index = ui->postsTree->selectionModel()->currentIndex();
|
||||
QModelIndex index = qobject_cast<QAction*>(QObject::sender())->data().toModelIndex();
|
||||
|
||||
if(!index.isValid())
|
||||
throw std::runtime_error("No post under mouse!");
|
||||
@ -428,23 +456,6 @@ void PostedListWidgetWithModel::showAuthorInPeople()
|
||||
MainWindow::showWindow(MainWindow::People);
|
||||
idDialog->navigate(RsGxsId(post.mMeta.mAuthorId));
|
||||
}
|
||||
void PostedListWidgetWithModel::postContextMenu(const QPoint&)
|
||||
{
|
||||
QMenu menu(this);
|
||||
|
||||
menu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyMessageLink()));
|
||||
menu.addAction(FilesDefs::getIconFromQtResourcePath(IMAGE_AUTHOR), tr("Show author in People tab"), this, SLOT(showAuthorInPeople()));
|
||||
|
||||
#ifdef TODO
|
||||
// This feature is not implemented yet in libretroshare.
|
||||
|
||||
if(IS_GROUP_PUBLISHER(mGroup.mMeta.mSubscribeFlags))
|
||||
menu.addAction(FilesDefs::getIconFromQtResourcePath(":/images/edit_16.png"), tr("Edit"), this, SLOT(editPost()));
|
||||
#endif
|
||||
|
||||
menu.exec(QCursor::pos());
|
||||
}
|
||||
|
||||
void PostedListWidgetWithModel::copyMessageLink()
|
||||
{
|
||||
try
|
||||
@ -452,7 +463,7 @@ void PostedListWidgetWithModel::copyMessageLink()
|
||||
if (groupId().isNull())
|
||||
throw std::runtime_error("No channel currently selected!");
|
||||
|
||||
QModelIndex index = ui->postsTree->selectionModel()->currentIndex();
|
||||
QModelIndex index = qobject_cast<QAction*>(QObject::sender())->data().toModelIndex();
|
||||
|
||||
if(!index.isValid())
|
||||
throw std::runtime_error("No post under mouse!");
|
||||
@ -528,87 +539,6 @@ void PostedListWidgetWithModel::handleEvent_main_thread(std::shared_ptr<const Rs
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TO_REMOVE
|
||||
void PostedListWidgetWithModel::showPostDetails()
|
||||
{
|
||||
QModelIndex index = ui->postsTree->selectionModel()->currentIndex();
|
||||
RsPostedPost post = index.data(Qt::UserRole).value<RsPostedPost>() ;
|
||||
|
||||
QTextDocument doc;
|
||||
doc.setHtml(post.mMsg.c_str());
|
||||
|
||||
if(post.mMeta.mPublishTs == 0)
|
||||
{
|
||||
ui->postDetails_TE->clear();
|
||||
ui->postLogo_LB->hide();
|
||||
ui->postName_LB->hide();
|
||||
ui->postTime_LB->hide();
|
||||
mChannelPostFilesModel->clear();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ui->postLogo_LB->show();
|
||||
ui->postName_LB->show();
|
||||
ui->postTime_LB->show();
|
||||
|
||||
if(index.row()==0 && index.column()==0)
|
||||
std::cerr << "here" << std::endl;
|
||||
|
||||
std::cerr << "showPostDetails: setting mLastSelectedPosts[groupId()] to current post Id " << post.mMeta.mMsgId << ". Previous value: " << mLastSelectedPosts[groupId()] << std::endl;
|
||||
mLastSelectedPosts[groupId()] = post.mMeta.mMsgId;
|
||||
|
||||
std::list<ChannelPostFileInfo> files;
|
||||
for(auto& file:post.mFiles)
|
||||
files.push_back(ChannelPostFileInfo(file,post.mMeta.mPublishTs));
|
||||
|
||||
mChannelPostFilesModel->setFiles(files);
|
||||
|
||||
auto all_msgs_versions(post.mOlderVersions);
|
||||
all_msgs_versions.insert(post.mMeta.mMsgId);
|
||||
|
||||
ui->commentsDialog->commentLoad(post.mMeta.mGroupId, all_msgs_versions, post.mMeta.mMsgId);
|
||||
|
||||
std::cerr << "Showing details about selected index : "<< index.row() << "," << index.column() << std::endl;
|
||||
|
||||
ui->postDetails_TE->setText(RsHtml().formatText(NULL, QString::fromUtf8(post.mMsg.c_str()), /* RSHTML_FORMATTEXT_EMBED_SMILEYS |*/ RSHTML_FORMATTEXT_EMBED_LINKS));
|
||||
|
||||
QPixmap postImage;
|
||||
|
||||
if (post.mThumbnail.mData != NULL)
|
||||
GxsIdDetails::loadPixmapFromData(post.mThumbnail.mData, post.mThumbnail.mSize, postImage,GxsIdDetails::ORIGINAL);
|
||||
else
|
||||
postImage = FilesDefs::getPixmapFromQtResourcePath(ChannelPostThumbnailView::CHAN_DEFAULT_IMAGE);
|
||||
|
||||
int W = QFontMetricsF(font()).height() * 8;
|
||||
|
||||
// Using fixed width so that the post will not displace the text when we browse.
|
||||
|
||||
ui->postLogo_LB->setPixmap(postImage);
|
||||
ui->postLogo_LB->setFixedSize(W,postImage.height()/(float)postImage.width()*W);
|
||||
|
||||
ui->postName_LB->setText(QString::fromUtf8(post.mMeta.mMsgName.c_str()));
|
||||
ui->postName_LB->setFixedWidth(W);
|
||||
ui->postTime_LB->setText(QDateTime::fromMSecsSinceEpoch(post.mMeta.mPublishTs*1000).toString("MM/dd/yyyy, hh:mm"));
|
||||
ui->postTime_LB->setFixedWidth(W);
|
||||
|
||||
//ui->channelPostFiles_TV->resizeColumnToContents(RsGxsChannelPostFilesModel::COLUMN_FILES_FILE);
|
||||
//ui->channelPostFiles_TV->resizeColumnToContents(RsGxsChannelPostFilesModel::COLUMN_FILES_SIZE);
|
||||
ui->channelPostFiles_TV->setAutoSelect(true);
|
||||
|
||||
// Now also set the post as read
|
||||
|
||||
if(IS_MSG_UNREAD(post.mMeta.mMsgStatus) || IS_MSG_NEW(post.mMeta.mMsgStatus))
|
||||
{
|
||||
RsGxsGrpMsgIdPair postId;
|
||||
postId.second = post.mMeta.mMsgId;
|
||||
postId.first = post.mMeta.mGroupId;
|
||||
|
||||
RsThread::async([postId]() { rsGxsChannels->markRead(postId, true) ; } );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void PostedListWidgetWithModel::updateGroupData()
|
||||
{
|
||||
if(groupId().isNull())
|
||||
|
@ -136,6 +136,7 @@ private slots:
|
||||
#ifdef TO_REMOVE
|
||||
void showPostDetails();
|
||||
#endif
|
||||
void postContextMenu(const QPoint&);
|
||||
void showAuthorInPeople();
|
||||
void tabCloseRequested(int index);
|
||||
void updateSorting(int);
|
||||
@ -145,7 +146,6 @@ private slots:
|
||||
void subscribeGroup(bool subscribe);
|
||||
void settingsChanged();
|
||||
void postPostLoad();
|
||||
void postContextMenu(const QPoint&);
|
||||
void copyMessageLink();
|
||||
void nextPosts();
|
||||
void prevPosts();
|
||||
|
@ -454,22 +454,6 @@ p, li { white-space: pre-wrap; }
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LineEditClear" name="filter_LE">
|
||||
<property name="placeholderText">
|
||||
|
@ -42,15 +42,26 @@ PulseAddDialog::PulseAddDialog(QWidget *parent)
|
||||
connect(ui.pushButton_Cancel, SIGNAL( clicked( void ) ), this, SLOT( cancelPulse( void ) ) );
|
||||
connect(ui.textEdit_Pulse, SIGNAL( textChanged( void ) ), this, SLOT( pulseTextChanged( void ) ) );
|
||||
connect(ui.pushButton_picture, SIGNAL(clicked()), this, SLOT( toggle()));
|
||||
connect(ui.pushButton_remove, SIGNAL(clicked()), this, SLOT( removePictures()));
|
||||
|
||||
|
||||
// this connection is from browse push button to the slot function onBrowseButtonClicked()
|
||||
connect(ui.pushButton_Browse, SIGNAL(clicked()), this, SLOT( onBrowseButtonClicked()));
|
||||
|
||||
ui.pushButton_picture->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/photo.png")));
|
||||
ui.pushButton_Browse->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/png/add-image.png")));
|
||||
ui.pushButton_remove->setIcon(FilesDefs::getIconFromQtResourcePath(QString(":/icons/mail/delete.png")));
|
||||
|
||||
ui.frame_picture->hide();
|
||||
ui.pushButton_picture->hide();
|
||||
|
||||
// initially hiding the browse button as the attach image button is not pressed
|
||||
ui.frame_PictureBrowse->hide();
|
||||
//ui.frame_PictureBrowse->hide();
|
||||
|
||||
ui.label_image1->hide();
|
||||
ui.label_image2->hide();
|
||||
ui.label_image3->hide();
|
||||
ui.label_image4->hide();
|
||||
|
||||
setAcceptDrops(true);
|
||||
}
|
||||
@ -160,11 +171,10 @@ void PulseAddDialog::cleanup()
|
||||
ui.label_image4->clear();
|
||||
ui.label_image4->setText(tr("Drag and Drop Image"));
|
||||
|
||||
ui.lineEdit_FilePath->clear();
|
||||
|
||||
// Hide Drag & Drop Frame and the browse frame
|
||||
ui.frame_picture->hide();
|
||||
ui.frame_PictureBrowse->hide();
|
||||
//ui.frame_PictureBrowse->hide();
|
||||
ui.pushButton_picture->hide();
|
||||
|
||||
ui.pushButton_picture->setChecked(false);
|
||||
}
|
||||
@ -489,24 +499,29 @@ void PulseAddDialog::addImage(const QString &path)
|
||||
std::cerr << "PulseAddDialog::addImage() Installing in Image1";
|
||||
std::cerr << std::endl;
|
||||
ui.label_image1->setPixmap(icon);
|
||||
ui.label_image1->show();
|
||||
ui.frame_picture->show();
|
||||
mImage1.copy((uint8_t *) ba.data(), ba.size());
|
||||
std::cerr << "PulseAddDialog::addImage() Installing in Image1 Size: " << mImage1.mSize;
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
else if (mImage2.empty()) {
|
||||
ui.label_image2->setPixmap(icon);
|
||||
ui.label_image2->show();
|
||||
mImage2.copy((uint8_t *) ba.data(), ba.size());
|
||||
std::cerr << "PulseAddDialog::addImage() Installing in Image2 Size: " << mImage2.mSize;
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
else if (mImage3.empty()) {
|
||||
ui.label_image3->setPixmap(icon);
|
||||
ui.label_image3->show();
|
||||
mImage3.copy((uint8_t *) ba.data(), ba.size());
|
||||
std::cerr << "PulseAddDialog::addImage() Installing in Image3 Size: " << mImage3.mSize;
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
else if (mImage4.empty()) {
|
||||
ui.label_image4->setPixmap(icon);
|
||||
ui.label_image4->show();
|
||||
mImage4.copy((uint8_t *) ba.data(), ba.size());
|
||||
std::cerr << "PulseAddDialog::addImage() Installing in Image4 Size: " << mImage4.mSize;
|
||||
std::cerr << std::endl;
|
||||
@ -523,7 +538,6 @@ void PulseAddDialog::toggle()
|
||||
{
|
||||
// Show the input methods (drag and drop field and the browse button)
|
||||
ui.frame_picture->show();
|
||||
ui.frame_PictureBrowse->show();
|
||||
|
||||
ui.pushButton_picture->setToolTip(tr("Hide Pictures"));
|
||||
}
|
||||
@ -531,7 +545,6 @@ void PulseAddDialog::toggle()
|
||||
{
|
||||
// Hide the input methods (drag and drop field and the browse button)
|
||||
ui.frame_picture->hide();
|
||||
ui.frame_PictureBrowse->hide();
|
||||
|
||||
ui.pushButton_picture->setToolTip(tr("Add Pictures"));
|
||||
}
|
||||
@ -543,8 +556,27 @@ void PulseAddDialog::onBrowseButtonClicked()
|
||||
QString filePath;
|
||||
misc::getOpenFileName(this, RshareSettings::LASTDIR_IMAGES, tr("Load Picture File"), "Pictures (*.png *.xpm *.jpg *.jpeg *.gif *.webp )", filePath);
|
||||
if (!filePath.isEmpty()) {
|
||||
ui.lineEdit_FilePath->setText(filePath);
|
||||
//ui.lineEdit_FilePath->setText(filePath);
|
||||
addImage(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
void PulseAddDialog::removePictures()
|
||||
{
|
||||
|
||||
mImage1.clear();
|
||||
ui.label_image1->clear();
|
||||
mImage2.clear();
|
||||
ui.label_image2->clear();
|
||||
mImage3.clear();
|
||||
ui.label_image3->clear();
|
||||
mImage4.clear();
|
||||
ui.label_image4->clear();
|
||||
|
||||
ui.label_image1->hide();
|
||||
ui.label_image2->hide();
|
||||
ui.label_image3->hide();
|
||||
ui.label_image4->hide();
|
||||
|
||||
ui.frame_picture->hide();
|
||||
}
|
||||
|
@ -53,7 +53,8 @@ private slots:
|
||||
void clearDialog();
|
||||
void pulseTextChanged();
|
||||
void toggle();
|
||||
void onBrowseButtonClicked();
|
||||
void onBrowseButtonClicked();
|
||||
void removePictures();
|
||||
|
||||
private:
|
||||
// OLD VERSIONs, private now.
|
||||
|
@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>720</width>
|
||||
<width>735</width>
|
||||
<height>513</height>
|
||||
</rect>
|
||||
</property>
|
||||
@ -52,6 +52,7 @@
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
@ -249,6 +250,12 @@
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_picture">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
@ -278,6 +285,22 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_image4">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Drag and Drop Image</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_image3">
|
||||
<property name="minimumSize">
|
||||
@ -310,63 +333,22 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_image4">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
<item row="0" column="2" rowspan="2">
|
||||
<widget class="QToolButton" name="pushButton_remove">
|
||||
<property name="toolTip">
|
||||
<string>Remove all images</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Drag and Drop Image</string>
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_PictureBrowse">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>50</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_FilePath">
|
||||
<property name="minimumSize">
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>541</width>
|
||||
<height>25</height>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_Browse">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>101</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Browse...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@ -413,7 +395,6 @@
|
||||
</layout>
|
||||
<zorder>frame_URL</zorder>
|
||||
<zorder>frame_picture</zorder>
|
||||
<zorder>frame_PictureBrowse</zorder>
|
||||
<zorder>textEdit_Pulse</zorder>
|
||||
</widget>
|
||||
</item>
|
||||
@ -423,7 +404,7 @@
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_picture">
|
||||
<widget class="QToolButton" name="pushButton_picture">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
@ -438,6 +419,22 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="pushButton_Browse">
|
||||
<property name="toolTip">
|
||||
<string>Add Picture</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="buttonHSpacer">
|
||||
<property name="orientation">
|
||||
@ -456,6 +453,7 @@
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
|
@ -23,6 +23,8 @@
|
||||
#include "WireGroupDialog.h"
|
||||
#include "WireGroupItem.h"
|
||||
#include "gui/settings/rsharesettings.h"
|
||||
#include "gui/gxs/GxsIdDetails.h"
|
||||
#include "gui/common/FilesDefs.h"
|
||||
|
||||
#include "PulseViewGroup.h"
|
||||
#include "PulseReplySeperator.h"
|
||||
@ -345,8 +347,20 @@ void WireDialog::updateGroups(std::vector<RsWireGroup>& groups)
|
||||
{
|
||||
// grab own groups.
|
||||
// setup Chooser too.
|
||||
mOwnGroups.push_back(it);
|
||||
ui.groupChooser->addItem(QString::fromStdString(it.mMeta.mGroupName));
|
||||
mOwnGroups.push_back(it);
|
||||
QPixmap pixmap;
|
||||
if (it.mHeadshot.mData)
|
||||
{
|
||||
if (GxsIdDetails::loadPixmapFromData( it.mHeadshot.mData,it.mHeadshot.mSize,pixmap,GxsIdDetails::ORIGINAL))
|
||||
pixmap = pixmap.scaled(32,32);
|
||||
}
|
||||
else
|
||||
{
|
||||
// default.
|
||||
pixmap = FilesDefs::getPixmapFromQtResourcePath(":/icons/wire.png").scaled(32,32);
|
||||
}
|
||||
|
||||
ui.groupChooser->addItem(QPixmap(pixmap),QString::fromStdString(it.mMeta.mGroupName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -165,7 +165,6 @@ ChatWidget::ChatWidget(QWidget *parent)
|
||||
connect(ui->actionResetFont, SIGNAL(triggered()), this, SLOT(resetFont()));
|
||||
connect(ui->actionQuote, SIGNAL(triggered()), this, SLOT(quote()));
|
||||
connect(ui->actionDropPlacemark, SIGNAL(triggered()), this, SLOT(dropPlacemark()));
|
||||
connect(ui->actionSave_image, SIGNAL(triggered()), this, SLOT(saveImage()));
|
||||
connect(ui->actionImport_sticker, SIGNAL(triggered()), this, SLOT(saveSticker()));
|
||||
connect(ui->actionShow_Hidden_Images, SIGNAL(triggered()), ui->textBrowser, SLOT(showImages()));
|
||||
ui->actionShow_Hidden_Images->setIcon(ui->textBrowser->getBlockedImage());
|
||||
@ -628,7 +627,7 @@ bool ChatWidget::eventFilter(QObject *obj, QEvent *event)
|
||||
QString toolTipText = ui->textBrowser->anchorForPosition(helpEvent->pos());
|
||||
if (toolTipText.isEmpty() && !ui->textBrowser->getShowImages()){
|
||||
QString imageStr;
|
||||
if (ui->textBrowser->checkImage(helpEvent->pos(), imageStr)) {
|
||||
if (ImageUtil::checkImage(ui->textBrowser, helpEvent->pos(), imageStr)) {
|
||||
toolTipText = imageStr;
|
||||
}
|
||||
} else if (toolTipText.startsWith(PERSONID)){
|
||||
@ -1151,10 +1150,7 @@ void ChatWidget::pasteText(const QString& S)
|
||||
|
||||
void ChatWidget::contextMenuTextBrowser(QPoint point)
|
||||
{
|
||||
QMatrix matrix;
|
||||
matrix.translate(ui->textBrowser->horizontalScrollBar()->value(), ui->textBrowser->verticalScrollBar()->value());
|
||||
|
||||
QMenu *contextMnu = ui->textBrowser->createStandardContextMenu(matrix.map(point));
|
||||
QMenu *contextMnu = ui->textBrowser->createStandardContextMenuFromPoint(point);
|
||||
|
||||
contextMnu->addSeparator();
|
||||
contextMnu->addAction(ui->actionClearChatHistory);
|
||||
@ -1162,14 +1158,12 @@ void ChatWidget::contextMenuTextBrowser(QPoint point)
|
||||
contextMnu->addAction(ui->actionQuote);
|
||||
contextMnu->addAction(ui->actionDropPlacemark);
|
||||
|
||||
if(ui->textBrowser->checkImage(point))
|
||||
if(ImageUtil::checkImage(ui->textBrowser, point))
|
||||
{
|
||||
if (! ui->textBrowser->getShowImages())
|
||||
contextMnu->addAction(ui->actionShow_Hidden_Images);
|
||||
|
||||
ui->actionSave_image->setData(point);
|
||||
ui->actionImport_sticker->setData(point);
|
||||
contextMnu->addAction(ui->actionSave_image);
|
||||
contextMnu->addAction(ui->actionImport_sticker);
|
||||
}
|
||||
|
||||
@ -1995,13 +1989,6 @@ void ChatWidget::dropPlacemark()
|
||||
// or not.
|
||||
}
|
||||
|
||||
void ChatWidget::saveImage()
|
||||
{
|
||||
QPoint point = ui->actionSave_image->data().toPoint();
|
||||
QTextCursor cursor = ui->textBrowser->cursorForPosition(point);
|
||||
ImageUtil::extractImage(window(), cursor);
|
||||
}
|
||||
|
||||
void ChatWidget::saveSticker()
|
||||
{
|
||||
QPoint point = ui->actionImport_sticker->data().toPoint();
|
||||
|
@ -196,7 +196,6 @@ private slots:
|
||||
|
||||
void quote();
|
||||
void dropPlacemark();
|
||||
void saveImage();
|
||||
void saveSticker();
|
||||
|
||||
private:
|
||||
|
@ -1049,15 +1049,6 @@ border-image: url(:/images/closepressed.png)
|
||||
<string>Insert horizontal rule</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionSave_image">
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/document_save.png</normaloff>:/images/document_save.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save image</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionImport_sticker">
|
||||
<property name="icon">
|
||||
<iconset resource="../icons.qrc">
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "MimeTextEdit.h"
|
||||
#include "util/HandleRichText.h"
|
||||
#include "gui/RetroShareLink.h"
|
||||
#include "util/imageutil.h"
|
||||
|
||||
#include <retroshare/rspeers.h>
|
||||
|
||||
@ -246,6 +247,18 @@ void MimeTextEdit::contextMenuEvent(QContextMenuEvent *e)
|
||||
|
||||
QMenu *contextMenu = createStandardContextMenu(e->pos());
|
||||
|
||||
if (ImageUtil::checkImage(this, e->pos())) {
|
||||
contextMenu->addSeparator();
|
||||
|
||||
QAction *a = contextMenu->addAction(FilesDefs::getIconFromQtResourcePath(":/images/document_save.png"), tr("Save image"), this, SLOT(saveImage()));
|
||||
a->setData(e->pos());
|
||||
|
||||
a = contextMenu->addAction( tr("Copy image"), this, SLOT(copyImage()));
|
||||
a->setData(e->pos());
|
||||
|
||||
contextMenu->addSeparator();
|
||||
}
|
||||
|
||||
/* Add actions for pasting links */
|
||||
contextMenu->addAction( tr("Paste as plain text"), this, SLOT(pastePlainText()));
|
||||
QAction *spoilerAction = contextMenu->addAction(tr("Spoiler"), this, SLOT(spoiler()));
|
||||
@ -292,3 +305,27 @@ void MimeTextEdit::spoiler()
|
||||
{
|
||||
RsHtml::insertSpoilerText(this->textCursor());
|
||||
}
|
||||
|
||||
void MimeTextEdit::saveImage()
|
||||
{
|
||||
QAction *action = dynamic_cast<QAction*>(sender()) ;
|
||||
if (!action) {
|
||||
return;
|
||||
}
|
||||
|
||||
QPoint point = action->data().toPoint();
|
||||
QTextCursor cursor = cursorForPosition(point);
|
||||
ImageUtil::extractImage(window(), cursor);
|
||||
}
|
||||
|
||||
void MimeTextEdit::copyImage()
|
||||
{
|
||||
QAction *action = dynamic_cast<QAction*>(sender()) ;
|
||||
if (!action) {
|
||||
return;
|
||||
}
|
||||
|
||||
QPoint point = action->data().toPoint();
|
||||
QTextCursor cursor = cursorForPosition(point);
|
||||
ImageUtil::copyImage(window(), cursor);
|
||||
}
|
||||
|
@ -75,6 +75,8 @@ private slots:
|
||||
void pasteOwnCertificateLink();
|
||||
void pastePlainText();
|
||||
void spoiler();
|
||||
void saveImage();
|
||||
void copyImage();
|
||||
|
||||
private:
|
||||
QString textUnderCursor() const;
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include "RSImageBlockWidget.h"
|
||||
#include "gui/common/FilesDefs.h"
|
||||
#include "util/imageutil.h"
|
||||
|
||||
#include <retroshare/rsinit.h> //To get RsAccounts
|
||||
|
||||
@ -33,6 +34,7 @@
|
||||
#include <QPainter>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QTextDocumentFragment>
|
||||
#include <QScrollBar>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
@ -232,64 +234,6 @@ void RSTextBrowser::activateLinkClick(bool active)
|
||||
mLinkClickActive = active;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RSTextBrowser::checkImage
|
||||
* @param pos where to check if image is shown in viewport coordinate
|
||||
* @param imageStr return html source of cursor
|
||||
* @return True if an image is under cursor
|
||||
*/
|
||||
bool RSTextBrowser::checkImage(QPoint pos, QString &imageStr)
|
||||
{
|
||||
//Get text cursor under pos. But if pos is under text browser end line this return last cursor.
|
||||
QTextCursor cursor = cursorForPosition(pos);
|
||||
//First get rect of cursor (could be at left or right of image)
|
||||
QRect cursorRectStart = cursorRect(cursor);
|
||||
//Second get text
|
||||
cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1);//To get character just before
|
||||
QRect cursorRectLeft = cursorRect(cursor);
|
||||
cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, 2);
|
||||
QRect cursorRectRight = cursorRect(cursor);
|
||||
imageStr = cursor.selection().toHtml();
|
||||
#ifdef RSTEXTBROWSER_CHECKIMAGE_DEBUG
|
||||
mCursorRectStart = cursorRectStart;
|
||||
mCursorRectLeft = cursorRectLeft;
|
||||
mCursorRectRight = cursorRectRight;
|
||||
|
||||
std::cerr << "cursorRect LTRB :" << cursorRectStart.left() << ";" << cursorRectStart.top() << ";" << cursorRectStart.right() << ";" << cursorRectStart.bottom() << std::endl;
|
||||
std::cerr << "cursorRectLeft :" << cursorRectLeft.left() << ";" << cursorRectLeft.top() << ";" << cursorRectLeft.right() << ";" << cursorRectLeft.bottom() << std::endl;
|
||||
std::cerr << "cursorRectRight :" << cursorRectRight.left() << ";" << cursorRectRight.top() << ";" << cursorRectRight.right() << ";" << cursorRectRight.bottom() << std::endl;
|
||||
std::cerr << "pos XY :" << pos.x() << ";" << pos.y() << std::endl;
|
||||
#endif
|
||||
QRect cursorRectEnd = cursorRectStart;
|
||||
//Finally set left with right of precedent character.
|
||||
if (cursorRectEnd.top() < cursorRectLeft.bottom())
|
||||
{
|
||||
cursorRectEnd.setLeft(cursorRectLeft.right());
|
||||
} else {
|
||||
//Image on new line
|
||||
cursorRectEnd.setLeft(0);
|
||||
}
|
||||
//And set Right with left of next character.
|
||||
if (cursorRectEnd.bottom() > cursorRectRight.top())
|
||||
{
|
||||
cursorRectEnd.setRight(cursorRectRight.left());
|
||||
} else {
|
||||
//New line after Image.
|
||||
}
|
||||
#ifdef RSTEXTBROWSER_CHECKIMAGE_DEBUG
|
||||
mCursorRectEnd = cursorRectEnd;
|
||||
|
||||
std::cerr << "final cursorRect:" << cursorRectEnd.left() << ";" << cursorRectEnd.top() << ";" << cursorRectEnd.right() << ";" << cursorRectEnd.bottom() << std::endl;
|
||||
viewport()->update();
|
||||
#endif
|
||||
//If pos is on text rect
|
||||
if (cursorRectEnd.contains(pos))
|
||||
{
|
||||
return imageStr.indexOf("base64,") != -1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RSTextBrowser::anchorForPosition Replace anchorAt that doesn't works as expected.
|
||||
* @param pos Where to get anchor from text
|
||||
@ -317,18 +261,59 @@ QString RSTextBrowser::anchorForPosition(const QPoint &pos) const
|
||||
return anchor;
|
||||
}
|
||||
|
||||
QMenu *RSTextBrowser::createStandardContextMenu()
|
||||
void RSTextBrowser::addContextMenuAction(QAction *action)
|
||||
{
|
||||
return createStandardContextMenu(QPoint());
|
||||
mContextMenuActions.push_back(action);
|
||||
}
|
||||
QMenu *RSTextBrowser::createStandardContextMenu(const QPoint &position)
|
||||
|
||||
void RSTextBrowser::contextMenuEvent(QContextMenuEvent *event)
|
||||
{
|
||||
QMenu *menu = QTextBrowser::createStandardContextMenu(position);
|
||||
emit calculateContextMenuActions();
|
||||
|
||||
QMenu *contextMenu = createStandardContextMenuFromPoint(event->pos());
|
||||
|
||||
QList<QAction*>::iterator it;
|
||||
for (it = mContextMenuActions.begin(); it != mContextMenuActions.end(); ++it) {
|
||||
contextMenu->addAction(*it);
|
||||
}
|
||||
|
||||
contextMenu->exec(QCursor::pos());
|
||||
|
||||
delete(contextMenu);
|
||||
}
|
||||
|
||||
QMenu *RSTextBrowser::createStandardContextMenuFromPoint(const QPoint &widgetPos)
|
||||
{
|
||||
QMatrix matrix;
|
||||
matrix.translate(horizontalScrollBar()->value(), verticalScrollBar()->value());
|
||||
|
||||
QMenu *menu = QTextBrowser::createStandardContextMenu(matrix.map(widgetPos));
|
||||
|
||||
menu->addSeparator();
|
||||
QAction *a = menu->addAction(FilesDefs::getIconFromQtResourcePath("://icons/textedit/code.png"), tr("View &Source"), this, SLOT(viewSource()));
|
||||
a->setEnabled(!this->document()->isEmpty());
|
||||
|
||||
if (ImageUtil::checkImage(this, widgetPos
|
||||
#ifdef RSTEXTBROWSER_CHECKIMAGE_DEBUG
|
||||
, &mCursorRectStart, &mCursorRectLeft, &mCursorRectRight, &mCursorRectEnd
|
||||
#endif
|
||||
)) {
|
||||
a = menu->addAction(FilesDefs::getIconFromQtResourcePath(":/images/document_save.png"), tr("Save image"), this, SLOT(saveImage()));
|
||||
a->setData(widgetPos);
|
||||
|
||||
a = menu->addAction( tr("Copy image"), this, SLOT(copyImage()));
|
||||
a->setData(widgetPos);
|
||||
}
|
||||
|
||||
#ifdef RSTEXTBROWSER_CHECKIMAGE_DEBUG
|
||||
std::cerr << "cursorRect LTRB :" << mCursorRectStart.left() << ";" << mCursorRectStart.top() << ";" << mCursorRectStart.right() << ";" << mCursorRectStart.bottom() << std::endl;
|
||||
std::cerr << "cursorRectLeft :" << mCursorRectLeft.left() << ";" << mCursorRectLeft.top() << ";" << mCursorRectLeft.right() << ";" << mCursorRectLeft.bottom() << std::endl;
|
||||
std::cerr << "cursorRectRight :" << mCursorRectRight.left() << ";" << mCursorRectRight.top() << ";" << mCursorRectRight.right() << ";" << mCursorRectRight.bottom() << std::endl;
|
||||
std::cerr << "pos XY :" << widgetPos.x() << ";" << widgetPos.y() << std::endl;
|
||||
std::cerr << "final cursorRect:" << mCursorRectEnd.left() << ";" << mCursorRectEnd.top() << ";" << mCursorRectEnd.right() << ";" << mCursorRectEnd.bottom() << std::endl;
|
||||
viewport()->update();
|
||||
#endif
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
@ -350,3 +335,27 @@ void RSTextBrowser::viewSource()
|
||||
|
||||
delete dialog;
|
||||
}
|
||||
|
||||
void RSTextBrowser::saveImage()
|
||||
{
|
||||
QAction *action = dynamic_cast<QAction*>(sender()) ;
|
||||
if (!action) {
|
||||
return;
|
||||
}
|
||||
|
||||
QPoint point = action->data().toPoint();
|
||||
QTextCursor cursor = cursorForPosition(point);
|
||||
ImageUtil::extractImage(window(), cursor);
|
||||
}
|
||||
|
||||
void RSTextBrowser::copyImage()
|
||||
{
|
||||
QAction *action = dynamic_cast<QAction*>(sender()) ;
|
||||
if (!action) {
|
||||
return;
|
||||
}
|
||||
|
||||
QPoint point = action->data().toPoint();
|
||||
QTextCursor cursor = cursorForPosition(point);
|
||||
ImageUtil::copyImage(window(), cursor);
|
||||
}
|
||||
|
@ -45,10 +45,10 @@ public:
|
||||
void setImageBlockWidget(RSImageBlockWidget *widget);
|
||||
void resetImagesStatus(bool load);
|
||||
QPixmap getBlockedImage();
|
||||
bool checkImage(QPoint pos, QString &imageStr);
|
||||
bool checkImage(QPoint pos) {QString imageStr; return checkImage(pos, imageStr); }
|
||||
QString anchorForPosition(const QPoint &pos) const;
|
||||
|
||||
// Add QAction to context menu (action won't be deleted)
|
||||
void addContextMenuAction(QAction *action);
|
||||
|
||||
void activateLinkClick(bool active);
|
||||
|
||||
@ -58,8 +58,10 @@ public:
|
||||
QVariant textColorQuotes() const { return highlighter->textColorQuotes();}
|
||||
bool getShowImages() const { return mShowImages; }
|
||||
|
||||
QMenu *createStandardContextMenu();
|
||||
QMenu *createStandardContextMenu(const QPoint &position);
|
||||
QMenu *createStandardContextMenuFromPoint(const QPoint &widgetPos);
|
||||
|
||||
Q_SIGNALS:
|
||||
void calculateContextMenuActions();
|
||||
|
||||
public slots:
|
||||
void showImages();
|
||||
@ -70,9 +72,16 @@ private slots:
|
||||
void linkClicked(const QUrl &url);
|
||||
void destroyImageBlockWidget();
|
||||
void viewSource();
|
||||
void saveImage();
|
||||
void copyImage();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event);
|
||||
virtual void contextMenuEvent(QContextMenuEvent *event);
|
||||
|
||||
private:
|
||||
// Hide method from QTextBrowser
|
||||
using QTextBrowser::createStandardContextMenu;
|
||||
|
||||
private:
|
||||
QString mPlaceholderText;
|
||||
@ -80,6 +89,7 @@ private:
|
||||
RSImageBlockWidget *mImageBlockWidget;
|
||||
bool mLinkClickActive;
|
||||
RsSyntaxHighlighter *highlighter;
|
||||
QList<QAction*> mContextMenuActions;
|
||||
#ifdef RSTEXTBROWSER_CHECKIMAGE_DEBUG
|
||||
QRect mCursorRectStart;
|
||||
QRect mCursorRectLeft;
|
||||
|
@ -186,13 +186,13 @@ void BaseBoardsCommentsItem::loadMessage()
|
||||
if (posts.size() == 1)
|
||||
{
|
||||
std::cerr << (void*)this << ": Obtained post, with msgId = " << posts[0].mMeta.mMsgId << std::endl;
|
||||
const RsPostedPost& post(posts[0]);
|
||||
RsPostedPost post(posts[0]); // no reference to temporary because it's passed to a thread!
|
||||
|
||||
RsQThreadUtils::postToObject( [post,this]() { setPost(post,true); mIsLoadingMessage = false;}, this );
|
||||
}
|
||||
else if(comments.size() == 1)
|
||||
{
|
||||
const RsGxsComment& cmt = comments[0];
|
||||
RsGxsComment cmt(comments[0]);
|
||||
std::cerr << (void*)this << ": Obtained comment, setting messageId to threadID = " << cmt.mMeta.mThreadId << std::endl;
|
||||
|
||||
RsQThreadUtils::postToObject( [cmt,this]()
|
||||
@ -287,14 +287,13 @@ void BaseBoardsCommentsItem::readToggled(bool checked)
|
||||
return;
|
||||
}
|
||||
|
||||
setReadStatus(false, checked); // Can't call this inside an async call since the widget may be destroyed afterwards!
|
||||
// So we do it right away.
|
||||
|
||||
RsThread::async( [this,checked]() {
|
||||
RsGxsGrpMsgIdPair msgPair = std::make_pair(groupId(), messageId());
|
||||
|
||||
rsPosted->setCommentReadStatus(msgPair, !checked);
|
||||
|
||||
RsQThreadUtils::postToObject( [this,checked]() {
|
||||
setReadStatus(false, checked);
|
||||
} );
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -292,13 +292,13 @@ void ChannelsCommentsItem::loadMessage()
|
||||
#ifdef DEBUG_ITEM
|
||||
std::cerr << (void*)this << ": Obtained post, with msgId = " << posts[0].mMeta.mMsgId << std::endl;
|
||||
#endif
|
||||
const RsGxsChannelPost& post(posts[0]);
|
||||
RsGxsChannelPost post(posts[0]); // no reference to temporary here, because we pass this to a thread
|
||||
|
||||
RsQThreadUtils::postToObject( [post,this]() { setPost(post); }, this );
|
||||
}
|
||||
else if(comments.size() == 1)
|
||||
{
|
||||
const RsGxsComment& cmt = comments[0];
|
||||
RsGxsComment cmt(comments[0]);
|
||||
#ifdef DEBUG_ITEM
|
||||
std::cerr << (void*)this << ": Obtained comment, setting messageId to threadID = " << cmt.mMeta.mThreadId << std::endl;
|
||||
#endif
|
||||
|
@ -125,7 +125,7 @@ void GxsForumGroupItem::loadGroup()
|
||||
std::cerr << std::endl;
|
||||
return;
|
||||
}
|
||||
const RsGxsForumGroup& group(groups[0]);
|
||||
RsGxsForumGroup group(groups[0]);// no reference to teporary accross threads!
|
||||
|
||||
RsQThreadUtils::postToObject( [group,this]()
|
||||
{
|
||||
|
@ -235,7 +235,7 @@ void GxsForumMsgItem::loadMessage()
|
||||
std::cerr << std::endl;
|
||||
return;
|
||||
}
|
||||
const RsGxsForumMsg& msg(msgs[0]);
|
||||
RsGxsForumMsg msg(msgs[0]);
|
||||
|
||||
RsQThreadUtils::postToObject( [msg,this]()
|
||||
{
|
||||
@ -280,7 +280,7 @@ void GxsForumMsgItem::loadParentMessage(const RsGxsMessageId& parent_msg)
|
||||
std::cerr << std::endl;
|
||||
return;
|
||||
}
|
||||
const RsGxsForumMsg& msg(msgs[0]);
|
||||
RsGxsForumMsg msg(msgs[0]);
|
||||
|
||||
RsQThreadUtils::postToObject( [msg,this]()
|
||||
{
|
||||
|
@ -794,56 +794,25 @@ void CreateGxsChannelMsg::sendMessage(const std::string &subject, const std::str
|
||||
/* rsGxsChannels */
|
||||
if (rsGxsChannels)
|
||||
{
|
||||
RsGxsChannelPost post;
|
||||
|
||||
post.mMeta.mGroupId = mChannelId;
|
||||
post.mMeta.mParentId.clear() ;
|
||||
post.mMeta.mThreadId.clear() ;
|
||||
post.mMeta.mMsgId.clear() ;
|
||||
|
||||
post.mMeta.mOrigMsgId = mOrigPostId;
|
||||
post.mMeta.mMsgName = subject;
|
||||
post.mMsg = msg;
|
||||
post.mFiles = files;
|
||||
|
||||
QByteArray ba;
|
||||
QBuffer buffer(&ba);
|
||||
|
||||
RsGxsImage image;
|
||||
|
||||
if(!picture.isNull())
|
||||
{
|
||||
// send chan image
|
||||
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
preview_W->getCroppedScaledPicture().save(&buffer, "JPG"); // writes image into ba in PNG format
|
||||
post.mThumbnail.copy((uint8_t *) ba.data(), ba.size());
|
||||
image.copy((uint8_t *) ba.data(), ba.size());
|
||||
}
|
||||
|
||||
std::string error_string;
|
||||
RsGxsMessageId post_id;
|
||||
|
||||
#ifdef ENABLE_GENERATE
|
||||
int generateCount = 0;
|
||||
if (generateCheckBox->isChecked()) {
|
||||
generateCount = generateSpinBox->value();
|
||||
if (QMessageBox::question(this, tr("Generate mass data"), tr("Do you really want to generate %1 messages ?").arg(generateCount), QMessageBox::Yes|QMessageBox::No, QMessageBox::No) == QMessageBox::No) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t token;
|
||||
#ifdef ENABLE_GENERATE
|
||||
if (generateCount) {
|
||||
for (int count = 0; count < generateCount; ++count) {
|
||||
RsGxsChannelPost generatePost = post;
|
||||
generatePost.mMeta.mMsgName = QString("%1 %2").arg(QString::fromUtf8(post.mMeta.mMsgName.c_str())).arg(count + 1, 3, 10, QChar('0')).toUtf8().constData();
|
||||
|
||||
rsGxsChannels->createPost(token, generatePost);
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
rsGxsChannels->createPost(token, post);
|
||||
#ifdef ENABLE_GENERATE
|
||||
}
|
||||
#endif
|
||||
if(!rsGxsChannels->createPostV2(mChannelId,subject,msg,files,image,mOrigPostId,post_id,error_string))
|
||||
QMessageBox::critical(nullptr,tr("Cannot publish post"),QString::fromStdString(error_string));
|
||||
}
|
||||
|
||||
accept();
|
||||
|
@ -27,6 +27,8 @@
|
||||
#include "retroshare/rsgxschannels.h"
|
||||
#include "retroshare/rsexpr.h"
|
||||
|
||||
#include "gui/MainWindow.h"
|
||||
#include "gui/mainpagestack.h"
|
||||
#include "gui/common/FilesDefs.h"
|
||||
#include "util/qtthreadsutils.h"
|
||||
#include "util/HandleRichText.h"
|
||||
@ -36,7 +38,7 @@
|
||||
#include "GxsChannelPostFilesModel.h"
|
||||
|
||||
//#define DEBUG_CHANNEL_MODEL_DATA
|
||||
//#define DEBUG_CHANNEL_MODEL
|
||||
#define DEBUG_CHANNEL_MODEL
|
||||
|
||||
Q_DECLARE_METATYPE(RsMsgMetaData)
|
||||
Q_DECLARE_METATYPE(RsGxsChannelPost)
|
||||
@ -61,7 +63,7 @@ void RsGxsChannelPostsModel::setMode(TreeMode mode)
|
||||
if(mode == TREE_MODE_LIST)
|
||||
setNumColumns(2);
|
||||
|
||||
triggerViewUpdate();
|
||||
triggerViewUpdate(true,true);
|
||||
}
|
||||
|
||||
void RsGxsChannelPostsModel::computeCommentCounts( std::vector<RsGxsChannelPost>& posts, std::vector<RsGxsComment>& comments)
|
||||
@ -116,12 +118,15 @@ void RsGxsChannelPostsModel::preMods()
|
||||
}
|
||||
void RsGxsChannelPostsModel::postMods()
|
||||
{
|
||||
triggerViewUpdate();
|
||||
emit layoutChanged();
|
||||
}
|
||||
void RsGxsChannelPostsModel::triggerViewUpdate()
|
||||
void RsGxsChannelPostsModel::triggerViewUpdate(bool data_changed, bool layout_changed)
|
||||
{
|
||||
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(rowCount()-1,mColumns-1,(void*)NULL));
|
||||
if(data_changed)
|
||||
emit dataChanged(createIndex(0,0,(void*)NULL), createIndex(rowCount()-1,mColumns-1,(void*)NULL));
|
||||
|
||||
if(layout_changed)
|
||||
emit layoutChanged();
|
||||
}
|
||||
|
||||
void RsGxsChannelPostsModel::getFilesList(std::list<ChannelPostFileInfo>& files)
|
||||
@ -168,11 +173,7 @@ void RsGxsChannelPostsModel::updateFilter(uint32_t& count)
|
||||
{
|
||||
preMods();
|
||||
|
||||
beginResetModel();
|
||||
|
||||
mFilteredPosts.clear();
|
||||
//mFilteredPosts.push_back(0);
|
||||
endResetModel();
|
||||
|
||||
for(size_t i=0;i<mPosts.size();++i)
|
||||
if(postPassesFilter(mPosts[i],mFilteredStrings,mFilterUnread))
|
||||
@ -314,17 +315,8 @@ bool RsGxsChannelPostsModel::setNumColumns(int n)
|
||||
|
||||
preMods();
|
||||
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
|
||||
mColumns = n;
|
||||
|
||||
if (rowCount()>0)
|
||||
{
|
||||
beginInsertRows(QModelIndex(),0,rowCount()-1);
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
postMods();
|
||||
|
||||
return true;
|
||||
@ -453,7 +445,6 @@ const RsGxsGroupId& RsGxsChannelPostsModel::currentGroupId() const
|
||||
{
|
||||
return mChannelGroup.mMeta.mGroupId;
|
||||
}
|
||||
|
||||
void RsGxsChannelPostsModel::updateChannel(const RsGxsGroupId& channel_group_id)
|
||||
{
|
||||
if(channel_group_id.isNull())
|
||||
@ -547,7 +538,7 @@ void RsGxsChannelPostsModel::updateSinglePost(const RsGxsChannelPost& post,std::
|
||||
uint32_t count;
|
||||
updateFilter(count);
|
||||
|
||||
triggerViewUpdate();
|
||||
triggerViewUpdate(true,false);
|
||||
}
|
||||
|
||||
void RsGxsChannelPostsModel::setPosts(const RsGxsChannelGroup& group, std::vector<RsGxsChannelPost>& posts)
|
||||
@ -557,7 +548,7 @@ void RsGxsChannelPostsModel::setPosts(const RsGxsChannelGroup& group, std::vecto
|
||||
initEmptyHierarchy();
|
||||
mChannelGroup = group;
|
||||
|
||||
createPostsArray(posts);
|
||||
createPostsArray(posts);
|
||||
|
||||
std::sort(mPosts.begin(),mPosts.end());
|
||||
|
||||
@ -586,7 +577,9 @@ void RsGxsChannelPostsModel::update_posts(const RsGxsGroupId& group_id)
|
||||
if(group_id.isNull())
|
||||
return;
|
||||
|
||||
RsThread::async([this, group_id]()
|
||||
MainWindow::getPage(MainWindow::Channels)->setCursor(Qt::WaitCursor) ; // Maybe we should pass that widget when calling update_posts
|
||||
|
||||
RsThread::async([this, group_id]()
|
||||
{
|
||||
// 1 - get message data from p3GxsChannels
|
||||
|
||||
@ -641,12 +634,14 @@ void RsGxsChannelPostsModel::update_posts(const RsGxsGroupId& group_id)
|
||||
delete comments;
|
||||
delete votes;
|
||||
|
||||
}, this );
|
||||
MainWindow::getPage(MainWindow::Channels)->setCursor(Qt::ArrowCursor) ;
|
||||
|
||||
}, this );
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
void RsGxsChannelPostsModel::createPostsArray(std::vector<RsGxsChannelPost>& posts)
|
||||
void RsGxsChannelPostsModel::old_createPostsArray(std::vector<RsGxsChannelPost>& posts)
|
||||
{
|
||||
// collect new versions of posts if any
|
||||
|
||||
@ -692,9 +687,6 @@ void RsGxsChannelPostsModel::createPostsArray(std::vector<RsGxsChannelPost>& pos
|
||||
|
||||
uint32_t current_index = new_versions[i] ;
|
||||
uint32_t source_index = new_versions[i] ;
|
||||
#ifdef DEBUG_CHANNEL_MODEL
|
||||
RsGxsMessageId source_msg_id = posts[source_index].mMeta.mMsgId ;
|
||||
#endif
|
||||
|
||||
// What we do is everytime we find a replacement post, we climb up the replacement graph until we find the original post
|
||||
// (or the most recent version of it). When we reach this post, we replace it with the data of the source post.
|
||||
@ -764,6 +756,153 @@ void RsGxsChannelPostsModel::createPostsArray(std::vector<RsGxsChannelPost>& pos
|
||||
}
|
||||
}
|
||||
|
||||
void RsGxsChannelPostsModel::createPostsArray(std::vector<RsGxsChannelPost>& posts)
|
||||
{
|
||||
// The hierarchy of posts may contain edited posts. In the new model (03/2023), mOrigMsgId points to the original
|
||||
// top-level post in the hierarchy of edited posts. However, in the old model, mOrigMsgId points to the edited post.
|
||||
// Therefore the algorithm below is made to cope with both models at once.
|
||||
//
|
||||
// In the future, using the new model, it will be possible to delete old versions from the db, and detect new versions
|
||||
// because they all share the same mOrigMsgId.
|
||||
//
|
||||
// We proceed as follows:
|
||||
//
|
||||
// 1 - create a search map to convert post IDs into their index in the posts tab
|
||||
// 2 - recursively climb up the post mOrigMsgId until no parent is found. At top level, create the original post, and add all previous elements as newer versions.
|
||||
// 3 - go through the list of original posts, select among them the most recent version, and set all others as older versions.
|
||||
//
|
||||
// The algorithm handles the case where some parent has been deleted.
|
||||
|
||||
#ifdef DEBUG_CHANNEL_MODEL
|
||||
std::cerr << "Inserting channel posts" << std::endl;
|
||||
#endif
|
||||
|
||||
// 1 - create a search map to convert post IDs into their index in the posts tab
|
||||
|
||||
#ifdef DEBUG_CHANNEL_MODEL
|
||||
std::cerr << " Given list: " << std::endl;
|
||||
#endif
|
||||
std::map<RsGxsMessageId,uint32_t> search_map ;
|
||||
|
||||
for (uint32_t i=0;i<posts.size();++i)
|
||||
{
|
||||
#ifdef DEBUG_CHANNEL_MODEL
|
||||
std::cerr << " " << i << ": " << posts[i].mMeta.mMsgId << " orig=" << posts[i].mMeta.mOrigMsgId << " publish TS =" << posts[i].mMeta.mPublishTs << std::endl;
|
||||
#endif
|
||||
search_map[posts[i].mMeta.mMsgId] = i ;
|
||||
}
|
||||
|
||||
// 2 - recursively climb up the post mOrigMsgId until no parent is found. At top level, create the original post, and add all previous elements as newer versions.
|
||||
|
||||
#ifdef DEBUG_CHANNEL_MODEL
|
||||
std::cerr << " Searching for top-level posts..." << std::endl;
|
||||
#endif
|
||||
std::map<RsGxsMessageId,std::pair<uint32_t,std::set<RsGxsMessageId> > > original_versions ;
|
||||
|
||||
for (uint32_t i=0;i<posts.size();++i)
|
||||
{
|
||||
#ifdef DEBUG_CHANNEL_MODEL
|
||||
std::cerr << " Post " << i;
|
||||
#endif
|
||||
|
||||
// We use a recursive function here, so as to collect versions when climbing up to the top level post, and
|
||||
// set the top level as the orig for all visited posts on the way back.
|
||||
|
||||
std::function<RsGxsMessageId (uint32_t,std::set<RsGxsMessageId>& versions,rstime_t newest_time,uint32_t newest_index,int depth)> recurs_find_top_level
|
||||
= [&posts,&search_map,&recurs_find_top_level,&original_versions](uint32_t index,
|
||||
std::set<RsGxsMessageId>& collected_versions,
|
||||
rstime_t newest_time,
|
||||
uint32_t newest_index,
|
||||
int depth)
|
||||
-> RsGxsMessageId
|
||||
{
|
||||
const auto& m(posts[index].mMeta);
|
||||
|
||||
if(m.mPublishTs > newest_time)
|
||||
{
|
||||
newest_index = index;
|
||||
newest_time = m.mPublishTs;
|
||||
}
|
||||
collected_versions.insert(m.mMsgId);
|
||||
|
||||
RsGxsMessageId top_level_id;
|
||||
std::map<RsGxsMessageId,uint32_t>::const_iterator it;
|
||||
|
||||
if(m.mOrigMsgId.isNull() || m.mOrigMsgId==m.mMsgId) // we have a top-level post.
|
||||
top_level_id = m.mMsgId;
|
||||
else if( (it = search_map.find(m.mOrigMsgId)) == search_map.end()) // we don't have the post. Never mind, we store the
|
||||
{
|
||||
top_level_id = m.mOrigMsgId;
|
||||
collected_versions.insert(m.mOrigMsgId); // this one will never be added to the set by the previous call
|
||||
}
|
||||
else
|
||||
{
|
||||
top_level_id = recurs_find_top_level(it->second,collected_versions,newest_time,newest_index,depth+1);
|
||||
posts[index].mMeta.mOrigMsgId = top_level_id; // this fastens calculation because it will skip already seen posts.
|
||||
|
||||
return top_level_id;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CHANNEL_MODEL
|
||||
std::cerr << std::string(2*depth,' ') << " top level = " << top_level_id ;
|
||||
#endif
|
||||
auto vit = original_versions.find(top_level_id);
|
||||
|
||||
if(vit != original_versions.end())
|
||||
{
|
||||
if(posts[vit->second.first].mMeta.mPublishTs < newest_time)
|
||||
vit->second.first = newest_index;
|
||||
|
||||
#ifdef DEBUG_CHANNEL_MODEL
|
||||
std::cerr << " already existing. " << std::endl;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
original_versions[top_level_id].first = newest_index;
|
||||
#ifdef DEBUG_CHANNEL_MODEL
|
||||
std::cerr << " new. " << std::endl;
|
||||
#endif
|
||||
}
|
||||
original_versions[top_level_id].second.insert(collected_versions.begin(),collected_versions.end());
|
||||
|
||||
return top_level_id;
|
||||
};
|
||||
|
||||
auto versions_set = std::set<RsGxsMessageId>();
|
||||
recurs_find_top_level(i,versions_set,posts[i].mMeta.mPublishTs,i,0);
|
||||
}
|
||||
|
||||
mPosts.clear();
|
||||
|
||||
#ifdef DEBUG_CHANNEL_MODEL
|
||||
std::cerr << " Total top_level posts: " << original_versions.size() << std::endl;
|
||||
|
||||
for(auto it:original_versions)
|
||||
{
|
||||
std::cerr << " Post " << it.first << ". Total versions = " << it.second.second.size() << " latest: " << posts[it.second.first].mMeta.mMsgId << std::endl;
|
||||
|
||||
for(auto m:it.second.second)
|
||||
if(m != it.first)
|
||||
std::cerr << " other (newer version): " << m << std::endl;
|
||||
}
|
||||
#endif
|
||||
// make sure the posts are delivered in the same order they appears in the posts[] tab.
|
||||
|
||||
std::vector<uint32_t> ids;
|
||||
|
||||
for(auto id:original_versions)
|
||||
ids.push_back(id.second.first);
|
||||
|
||||
std::sort(ids.begin(),ids.end());
|
||||
|
||||
for(uint32_t i=0;i<ids.size();++i)
|
||||
{
|
||||
mPosts.push_back(posts[ids[i]]);
|
||||
mPosts.back().mOlderVersions = original_versions[posts[ids[i]].mMeta.mMsgId].second;
|
||||
}
|
||||
|
||||
}
|
||||
void RsGxsChannelPostsModel::setAllMsgReadStatus(bool read_status)
|
||||
{
|
||||
// No need to call preMods()/postMods() here because we're not changing the model
|
||||
|
@ -115,7 +115,7 @@ public:
|
||||
void updateChannel(const RsGxsGroupId& channel_group_id);
|
||||
const RsGxsGroupId& currentGroupId() const;
|
||||
|
||||
void triggerViewUpdate();
|
||||
void triggerViewUpdate(bool data_changed,bool layout_changed);
|
||||
|
||||
// sets the number of columns. Returns 0 if nothing changes.
|
||||
bool setNumColumns(int n);
|
||||
@ -235,8 +235,9 @@ private:
|
||||
//static void convertMsgToPostEntry(const RsGxsChannelGroup &mChannelGroup, const RsMsgMetaData &msg, bool useChildTS, ChannelModelPostEntry& fentry);
|
||||
|
||||
//void computeMessagesHierarchy(const RsGxsChannelGroup& forum_group, const std::vector<RsMsgMetaData> &msgs_array, std::vector<ChannelPostsModelPostEntry> &posts, std::map<RsGxsMessageId, std::vector<std::pair<time_t, RsGxsMessageId> > > &mPostVersions);
|
||||
void createPostsArray(std::vector<RsGxsChannelPost> &posts);
|
||||
void setPosts(const RsGxsChannelGroup& group, std::vector<RsGxsChannelPost> &posts);
|
||||
void old_createPostsArray(std::vector<RsGxsChannelPost> &posts);
|
||||
void createPostsArray(std::vector<RsGxsChannelPost>& posts);
|
||||
void setPosts(const RsGxsChannelGroup& group, std::vector<RsGxsChannelPost> &posts);
|
||||
public:
|
||||
void updateSinglePost(const RsGxsChannelPost& post, std::set<RsGxsFile>& added_files, std::set<RsGxsFile>& removed_files);
|
||||
private:
|
||||
|
@ -92,9 +92,9 @@ Q_DECLARE_METATYPE(ChannelPostFileInfo)
|
||||
int ChannelPostDelegate::cellSize(int col,const QFont& font,uint32_t parent_width) const
|
||||
{
|
||||
if(mUseGrid || col==0)
|
||||
return mZoom*COLUMN_SIZE_FONT_FACTOR_W*QFontMetricsF(font).height();
|
||||
return (int)floor(mZoom*COLUMN_SIZE_FONT_FACTOR_W*QFontMetricsF(font).height());
|
||||
else
|
||||
return 0.8*parent_width - mZoom*COLUMN_SIZE_FONT_FACTOR_W*QFontMetricsF(font).height();
|
||||
return (int)floor(0.8*parent_width - mZoom*COLUMN_SIZE_FONT_FACTOR_W*QFontMetricsF(font).height());
|
||||
}
|
||||
|
||||
void ChannelPostDelegate::zoom(bool zoom_or_unzoom)
|
||||
@ -279,18 +279,18 @@ void ChannelPostDelegate::setWidgetGrid(bool use_grid)
|
||||
|
||||
QWidget *ChannelPostFilesDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &/*option*/, const QModelIndex& index) const
|
||||
{
|
||||
ChannelPostFileInfo file = index.data(Qt::UserRole).value<ChannelPostFileInfo>() ;
|
||||
ChannelPostFileInfo file = index.data(Qt::UserRole).value<ChannelPostFileInfo>() ;
|
||||
|
||||
if(index.column() == RsGxsChannelPostFilesModel::COLUMN_FILES_FILE)
|
||||
{
|
||||
if(index.column() == RsGxsChannelPostFilesModel::COLUMN_FILES_FILE)
|
||||
{
|
||||
GxsChannelFilesStatusWidget* w = new GxsChannelFilesStatusWidget(file,parent,true);
|
||||
w->setFocusPolicy(Qt::StrongFocus);
|
||||
connect(w,SIGNAL(onButtonClick()),this->parent(),SLOT(updateDAll_PB()));
|
||||
|
||||
return w;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
return w;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
void ChannelPostFilesDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
|
||||
{
|
||||
@ -379,7 +379,7 @@ GxsChannelPostsWidgetWithModel::GxsChannelPostsWidgetWithModel(const RsGxsGroupI
|
||||
connect(ui->viewType_TB,SIGNAL(clicked()),this,SLOT(switchView()));
|
||||
|
||||
ui->showUnread_TB->setIcon(FilesDefs::getIconFromQtResourcePath(":/images/message-state-unread.png"));
|
||||
ui->showUnread_TB->setChecked(false);
|
||||
whileBlocking(ui->showUnread_TB)->setChecked(false);
|
||||
ui->showUnread_TB->setToolTip(tr("Show unread posts only"));
|
||||
connect(ui->showUnread_TB,SIGNAL(toggled(bool)),this,SLOT(switchOnlyUnread(bool)));
|
||||
|
||||
@ -392,7 +392,7 @@ GxsChannelPostsWidgetWithModel::GxsChannelPostsWidgetWithModel(const RsGxsGroupI
|
||||
|
||||
mChannelPostsDelegate->setAspectRatio(ChannelPostThumbnailView::ASPECT_RATIO_16_9);
|
||||
|
||||
connect(ui->postsTree,SIGNAL(zoomRequested(bool)),this,SLOT(updateZoomFactor(bool)));
|
||||
connect(ui->postsTree,SIGNAL(zoomRequested(bool)),this,SLOT(onUpdateZoomFactor(bool)));
|
||||
connect(ui->commentsDialog,SIGNAL(commentsLoaded(int)),this,SLOT(updateCommentsCount(int)));
|
||||
|
||||
ui->channelPostFiles_TV->setModel(mChannelPostFilesModel = new RsGxsChannelPostFilesModel(this));
|
||||
@ -517,23 +517,33 @@ void GxsChannelPostsWidgetWithModel::currentTabChanged(int t)
|
||||
case CHANNEL_TABS_POSTS:
|
||||
ui->showUnread_TB->setHidden(false);
|
||||
ui->viewType_TB->setHidden(false);
|
||||
updateZoomFactor(0); // fixes a bug due to the widget now knowing its size when not displayed.
|
||||
break;
|
||||
}
|
||||
}
|
||||
void GxsChannelPostsWidgetWithModel::updateZoomFactor(bool zoom_or_unzoom)
|
||||
void GxsChannelPostsWidgetWithModel::onUpdateZoomFactor(bool zoom_or_unzoom)
|
||||
{
|
||||
mChannelPostsDelegate->zoom(zoom_or_unzoom);
|
||||
if(zoom_or_unzoom)
|
||||
updateZoomFactor(1);
|
||||
else
|
||||
updateZoomFactor(-1);
|
||||
}
|
||||
void GxsChannelPostsWidgetWithModel::updateZoomFactor(int what_to_do)
|
||||
{
|
||||
if(what_to_do != 0)
|
||||
mChannelPostsDelegate->zoom(what_to_do > 0);
|
||||
|
||||
QSize s = ui->postsTree->size();
|
||||
int n_columns = std::max(1,(int)floor(s.width() / (float)(mChannelPostsDelegate->cellSize(0,font(),s.width()))));
|
||||
mChannelPostsModel->setNumColumns(n_columns); // forces the update
|
||||
|
||||
for(int i=0;i<mChannelPostsModel->columnCount();++i)
|
||||
ui->postsTree->setColumnWidth(i,mChannelPostsDelegate->cellSize(i,font(),ui->postsTree->width()));
|
||||
|
||||
QSize s = ui->postsTree->size();
|
||||
|
||||
int n_columns = std::max(1,(int)floor(s.width() / (mChannelPostsDelegate->cellSize(0,font(),s.width()))));
|
||||
|
||||
mChannelPostsModel->setNumColumns(n_columns); // forces the update
|
||||
|
||||
ui->postsTree->dataChanged(QModelIndex(),QModelIndex());
|
||||
if(what_to_do)
|
||||
mChannelPostsModel->triggerViewUpdate(true,false);
|
||||
else
|
||||
mChannelPostsModel->triggerViewUpdate(false,true);
|
||||
}
|
||||
|
||||
void GxsChannelPostsWidgetWithModel::sortColumnPostFiles(int col,Qt::SortOrder so)
|
||||
@ -639,7 +649,7 @@ void GxsChannelPostsWidgetWithModel::switchView()
|
||||
selectItem(msg_id);
|
||||
ui->postsTree->setFocus();
|
||||
|
||||
mChannelPostsModel->triggerViewUpdate(); // This is already called by setMode(), but the model cannot know how many
|
||||
mChannelPostsModel->triggerViewUpdate(false,true); // This is already called by setMode(), but the model cannot know how many
|
||||
// columns is actually has until we call handlePostsTreeSizeChange(), so
|
||||
// we have to call it again here.
|
||||
}
|
||||
@ -1067,8 +1077,9 @@ void GxsChannelPostsWidgetWithModel::postChannelPostLoad()
|
||||
best = i;
|
||||
|
||||
mChannelPostsDelegate->setAspectRatio(static_cast<ChannelPostThumbnailView::AspectRatio>(best));
|
||||
mChannelPostsModel->triggerViewUpdate();
|
||||
handlePostsTreeSizeChange(ui->postsTree->size(),true); // force the update
|
||||
|
||||
updateZoomFactor(0);
|
||||
}
|
||||
|
||||
void GxsChannelPostsWidgetWithModel::updateDisplay(bool update_group_data,bool update_posts)
|
||||
|
@ -154,7 +154,7 @@ private slots:
|
||||
void editPost();
|
||||
void postContextMenu(const QPoint&);
|
||||
void copyMessageLink();
|
||||
void updateZoomFactor(bool zoom_or_unzoom);
|
||||
void onUpdateZoomFactor(bool zoom_or_unzoom);
|
||||
void switchView();
|
||||
void switchOnlyUnread(bool b);
|
||||
void markMessageUnread();
|
||||
@ -168,7 +168,8 @@ public slots:
|
||||
void copyChannelFilesLink();
|
||||
|
||||
private:
|
||||
void processSettings(bool load);
|
||||
void updateZoomFactor(int what_to_do); // -1=unzoom, 0=nothing, 1=zoom
|
||||
void processSettings(bool load);
|
||||
RsGxsMessageId getCurrentItemId() const;
|
||||
void selectItem(const RsGxsMessageId& msg_id);
|
||||
|
||||
|
@ -402,7 +402,7 @@
|
||||
<string notr="true"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;">
|
||||
</style></head><body style=" font-family:'Sans Serif'; font-size:11pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;">Description</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
@ -534,7 +534,7 @@ p, li { white-space: pre-wrap; }
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<widget class="QLabel" name="postName_LB">
|
||||
<widget class="ElidedLabel" name="postName_LB">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
|
@ -19,6 +19,7 @@
|
||||
*******************************************************************************/
|
||||
|
||||
#include "CreateGxsForumMsg.h"
|
||||
#include "ui_CreateGxsForumMsg.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QFile>
|
||||
@ -54,63 +55,64 @@
|
||||
/** Constructor */
|
||||
CreateGxsForumMsg::CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessageId &pId, const RsGxsMessageId& mOId, const RsGxsId& posterId, bool isModerating)
|
||||
: QDialog(NULL, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint),
|
||||
mForumId(fId), mParentId(pId), mOrigMsgId(mOId),mPosterId(posterId),mIsModerating(isModerating)
|
||||
mForumId(fId), mParentId(pId), mOrigMsgId(mOId),mPosterId(posterId),mIsModerating(isModerating),
|
||||
ui(new Ui::CreateGxsForumMsg)
|
||||
{
|
||||
/* Invoke the Qt Designer generated object setup routine */
|
||||
ui.setupUi(this);
|
||||
ui->setupUi(this);
|
||||
|
||||
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
|
||||
/* Setup UI helper */
|
||||
mStateHelper = new UIStateHelper(this);
|
||||
mStateHelper->addWidget(CREATEGXSFORUMMSG_FORUMINFO, ui.postButton);
|
||||
mStateHelper->addWidget(CREATEGXSFORUMMSG_FORUMINFO, ui.innerFrame);
|
||||
mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_FORUMINFO, ui.forumName);
|
||||
mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_FORUMINFO, ui.forumSubject);
|
||||
mStateHelper->addClear(CREATEGXSFORUMMSG_FORUMINFO, ui.forumName);
|
||||
mStateHelper->addWidget(CREATEGXSFORUMMSG_FORUMINFO, ui->postButton);
|
||||
mStateHelper->addWidget(CREATEGXSFORUMMSG_FORUMINFO, ui->innerFrame);
|
||||
mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_FORUMINFO, ui->forumName);
|
||||
mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_FORUMINFO, ui->forumSubject);
|
||||
mStateHelper->addClear(CREATEGXSFORUMMSG_FORUMINFO, ui->forumName);
|
||||
|
||||
mStateHelper->addWidget(CREATEGXSFORUMMSG_PARENTMSG, ui.postButton);
|
||||
mStateHelper->addWidget(CREATEGXSFORUMMSG_PARENTMSG, ui.innerFrame);
|
||||
mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_PARENTMSG, ui.forumName);
|
||||
mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_PARENTMSG, ui.forumSubject);
|
||||
mStateHelper->addClear(CREATEGXSFORUMMSG_PARENTMSG, ui.forumName);
|
||||
mStateHelper->addWidget(CREATEGXSFORUMMSG_PARENTMSG, ui->postButton);
|
||||
mStateHelper->addWidget(CREATEGXSFORUMMSG_PARENTMSG, ui->innerFrame);
|
||||
mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_PARENTMSG, ui->forumName);
|
||||
mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_PARENTMSG, ui->forumSubject);
|
||||
mStateHelper->addClear(CREATEGXSFORUMMSG_PARENTMSG, ui->forumName);
|
||||
|
||||
mStateHelper->addWidget(CREATEGXSFORUMMSG_ORIGMSG, ui.postButton);
|
||||
mStateHelper->addWidget(CREATEGXSFORUMMSG_ORIGMSG, ui.innerFrame);
|
||||
mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_ORIGMSG, ui.forumName);
|
||||
mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_ORIGMSG, ui.forumSubject);
|
||||
mStateHelper->addClear(CREATEGXSFORUMMSG_ORIGMSG, ui.forumName);
|
||||
mStateHelper->addWidget(CREATEGXSFORUMMSG_ORIGMSG, ui->postButton);
|
||||
mStateHelper->addWidget(CREATEGXSFORUMMSG_ORIGMSG, ui->innerFrame);
|
||||
mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_ORIGMSG, ui->forumName);
|
||||
mStateHelper->addLoadPlaceholder(CREATEGXSFORUMMSG_ORIGMSG, ui->forumSubject);
|
||||
mStateHelper->addClear(CREATEGXSFORUMMSG_ORIGMSG, ui->forumName);
|
||||
|
||||
|
||||
QString text = mOId.isNull()?(pId.isNull() ? tr("Start New Thread") : tr("Post Forum Message")):tr("Edit Message");
|
||||
setWindowTitle(text);
|
||||
|
||||
if (!mOId.isNull())
|
||||
ui.postButton->setText(tr ("Update"));
|
||||
ui->postButton->setText(tr ("Update"));
|
||||
|
||||
ui.forumMessage->setPlaceholderText(tr ("Text"));
|
||||
ui->forumMessage->setPlaceholderText(tr ("Text"));
|
||||
|
||||
ui.headerFrame->setHeaderImage(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/forums.png"));
|
||||
ui.headerFrame->setHeaderText(text);
|
||||
ui->headerFrame->setHeaderImage(FilesDefs::getPixmapFromQtResourcePath(":/icons/png/forums.png"));
|
||||
ui->headerFrame->setHeaderText(text);
|
||||
|
||||
ui.generateSpinBox->setEnabled(false);
|
||||
ui->generateSpinBox->setEnabled(false);
|
||||
|
||||
Settings->loadWidgetInformation(this);
|
||||
|
||||
connect(ui.hashBox, SIGNAL(fileHashingFinished(QList<HashedFile>)), this, SLOT(fileHashingFinished(QList<HashedFile>)));
|
||||
connect(ui->hashBox, SIGNAL(fileHashingFinished(QList<HashedFile>)), this, SLOT(fileHashingFinished(QList<HashedFile>)));
|
||||
|
||||
// connect up the buttons.
|
||||
connect(ui.postButton, SIGNAL(clicked()), this, SLOT(createMsg()));
|
||||
connect(ui.cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
|
||||
connect(ui.emoticonButton, SIGNAL(clicked()), this, SLOT(smileyWidgetForums()));
|
||||
connect(ui.attachFileButton, SIGNAL(clicked()), this, SLOT(addFile()));
|
||||
connect(ui.attachPictureButton, SIGNAL(clicked()), this, SLOT(addPicture()));
|
||||
connect(ui.forumMessage, SIGNAL(textChanged()), this, SLOT(checkLength()));
|
||||
connect(ui.generateCheckBox, SIGNAL(toggled(bool)), ui.generateSpinBox, SLOT(setEnabled(bool)));
|
||||
connect(ui->postButton, SIGNAL(clicked()), this, SLOT(createMsg()));
|
||||
connect(ui->cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
|
||||
connect(ui->emoticonButton, SIGNAL(clicked()), this, SLOT(smileyWidgetForums()));
|
||||
connect(ui->attachFileButton, SIGNAL(clicked()), this, SLOT(addFile()));
|
||||
connect(ui->attachPictureButton, SIGNAL(clicked()), this, SLOT(addPicture()));
|
||||
connect(ui->forumMessage, SIGNAL(textChanged()), this, SLOT(checkLength()));
|
||||
connect(ui->generateCheckBox, SIGNAL(toggled(bool)), ui->generateSpinBox, SLOT(setEnabled(bool)));
|
||||
|
||||
setAcceptDrops(true);
|
||||
ui.hashBox->setDropWidget(this);
|
||||
ui.hashBox->setAutoHide(false);
|
||||
ui->hashBox->setDropWidget(this);
|
||||
ui->hashBox->setAutoHide(false);
|
||||
|
||||
mParentMsgLoaded = false;
|
||||
mForumMetaLoaded = false;
|
||||
@ -118,11 +120,11 @@ CreateGxsForumMsg::CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessage
|
||||
|
||||
newMsg();
|
||||
|
||||
ui.hashGroupBox->hide();
|
||||
ui->hashGroupBox->hide();
|
||||
|
||||
#ifndef ENABLE_GENERATE
|
||||
ui.generateCheckBox->hide();
|
||||
ui.generateSpinBox->hide();
|
||||
ui->generateCheckBox->hide();
|
||||
ui->generateSpinBox->hide();
|
||||
#endif
|
||||
processSettings(true);
|
||||
}
|
||||
@ -130,6 +132,9 @@ CreateGxsForumMsg::CreateGxsForumMsg(const RsGxsGroupId &fId, const RsGxsMessage
|
||||
CreateGxsForumMsg::~CreateGxsForumMsg()
|
||||
{
|
||||
processSettings(false);
|
||||
|
||||
delete ui;
|
||||
|
||||
}
|
||||
|
||||
void CreateGxsForumMsg::processSettings(bool load)
|
||||
@ -142,14 +147,14 @@ void CreateGxsForumMsg::processSettings(bool load)
|
||||
RsGxsId gxs_id(Settings->value("IDChooser", QString::fromStdString(RsGxsId().toStdString())).toString().toStdString());
|
||||
|
||||
if(!gxs_id.isNull() && rsIdentity->isOwnId(gxs_id))
|
||||
ui.idChooser->setChosenId(gxs_id);
|
||||
ui->idChooser->setChosenId(gxs_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
// state of ID Chooser combobox
|
||||
RsGxsId id;
|
||||
|
||||
if(ui.idChooser->getChosenId(id))
|
||||
if(ui->idChooser->getChosenId(id))
|
||||
Settings->setValue("IDChooser", QString::fromStdString(id.toStdString()));
|
||||
}
|
||||
|
||||
@ -171,11 +176,11 @@ void CreateGxsForumMsg::newMsg()
|
||||
std::set<RsGxsId> id_set ;
|
||||
id_set.insert(mPosterId) ;
|
||||
|
||||
ui.idChooser->loadIds(IDCHOOSER_ID_REQUIRED | IDCHOOSER_NO_CREATE, mPosterId);
|
||||
ui.idChooser->setIdConstraintSet(id_set);
|
||||
ui->idChooser->loadIds(IDCHOOSER_ID_REQUIRED | IDCHOOSER_NO_CREATE, mPosterId);
|
||||
ui->idChooser->setIdConstraintSet(id_set);
|
||||
}
|
||||
else
|
||||
ui.idChooser->loadIds(IDCHOOSER_ID_REQUIRED, mPosterId);
|
||||
ui->idChooser->loadIds(IDCHOOSER_ID_REQUIRED, mPosterId);
|
||||
|
||||
if (mForumId.isNull()) {
|
||||
mStateHelper->setActive(CREATEGXSFORUMMSG_FORUMINFO, false);
|
||||
@ -185,7 +190,7 @@ void CreateGxsForumMsg::newMsg()
|
||||
mStateHelper->clear(CREATEGXSFORUMMSG_FORUMINFO);
|
||||
mStateHelper->clear(CREATEGXSFORUMMSG_PARENTMSG);
|
||||
mStateHelper->clear(CREATEGXSFORUMMSG_ORIGMSG);
|
||||
ui.forumName->setText(tr("No Forum"));
|
||||
ui->forumName->setText(tr("No Forum"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -306,7 +311,7 @@ void CreateGxsForumMsg::loadFormInformation()
|
||||
if(!mPosterId.isNull())
|
||||
fl |= IDCHOOSER_NO_CREATE;
|
||||
|
||||
ui.idChooser->setFlags(fl) ;
|
||||
ui->idChooser->setFlags(fl) ;
|
||||
|
||||
QString name = QString::fromUtf8(mForumMeta.mGroupName.c_str());
|
||||
QString subj;
|
||||
@ -327,19 +332,19 @@ void CreateGxsForumMsg::loadFormInformation()
|
||||
subj = "Re: " + title;
|
||||
}
|
||||
|
||||
ui.forumName->setText(misc::removeNewLine(name));
|
||||
ui->forumName->setText(misc::removeNewLine(name));
|
||||
|
||||
std::cerr << "Setting name to \"" << misc::removeNewLine(name).toStdString() << std::endl;
|
||||
if(!subj.isNull())
|
||||
ui.forumSubject->setText(misc::removeNewLine(subj));
|
||||
ui->forumSubject->setText(misc::removeNewLine(subj));
|
||||
|
||||
if (ui.forumSubject->text().isEmpty())
|
||||
if (ui->forumSubject->text().isEmpty())
|
||||
{
|
||||
ui.forumSubject->setFocus();
|
||||
ui.forumSubject->setPlaceholderText(tr ("Title"));
|
||||
ui->forumSubject->setFocus();
|
||||
ui->forumSubject->setPlaceholderText(tr ("Title"));
|
||||
}
|
||||
else
|
||||
ui.forumMessage->setFocus();
|
||||
ui->forumMessage->setFocus();
|
||||
|
||||
#ifdef TOGXS
|
||||
if (mForumMeta.mGroupFlags & RS_DISTRIB_AUTHEN_REQ)
|
||||
@ -347,18 +352,18 @@ void CreateGxsForumMsg::loadFormInformation()
|
||||
if (1)
|
||||
#endif
|
||||
{
|
||||
ui.signBox->setChecked(true);
|
||||
ui.signBox->setEnabled(false);
|
||||
ui.signBox->hide();
|
||||
ui->signBox->setChecked(true);
|
||||
ui->signBox->setEnabled(false);
|
||||
ui->signBox->hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Uncheck sign box by default for anonymous forums */
|
||||
ui.signBox->setChecked(false);
|
||||
ui.signBox->setEnabled(true);
|
||||
ui->signBox->setChecked(false);
|
||||
ui->signBox->setEnabled(true);
|
||||
}
|
||||
|
||||
//ui.forumMessage->setText("");
|
||||
//ui->forumMessage->setText("");
|
||||
}
|
||||
|
||||
static const uint32_t MAX_ALLOWED_GXS_MESSAGE_SIZE = 199000;
|
||||
@ -366,27 +371,27 @@ static const uint32_t MAX_ALLOWED_GXS_MESSAGE_SIZE = 199000;
|
||||
void CreateGxsForumMsg::checkLength()
|
||||
{
|
||||
QString text;
|
||||
RsHtml::optimizeHtml(ui.forumMessage, text);
|
||||
RsHtml::optimizeHtml(ui->forumMessage, text);
|
||||
std::wstring msg = text.toStdWString();
|
||||
int charRemains = MAX_ALLOWED_GXS_MESSAGE_SIZE - msg.length();
|
||||
if(charRemains >= 0) {
|
||||
text = tr("It remains %1 characters after HTML conversion.").arg(charRemains);
|
||||
ui.info_Label->setStyleSheet("QLabel#info_Label { }");
|
||||
ui->info_Label->setStyleSheet("QLabel#info_Label { }");
|
||||
}else{
|
||||
text = tr("Warning: This message is too big of %1 characters after HTML conversion.").arg((0-charRemains));
|
||||
ui.info_Label->setStyleSheet("QLabel#info_Label {color: red; font: bold; }");
|
||||
ui->info_Label->setStyleSheet("QLabel#info_Label {color: red; font: bold; }");
|
||||
}
|
||||
ui.postButton->setToolTip(text);
|
||||
ui.postButton->setEnabled(charRemains>=0);
|
||||
ui.info_Label->setText(text);
|
||||
ui->postButton->setToolTip(text);
|
||||
ui->postButton->setEnabled(charRemains>=0);
|
||||
ui->info_Label->setText(text);
|
||||
}
|
||||
|
||||
void CreateGxsForumMsg::createMsg()
|
||||
{
|
||||
QString name = misc::removeNewLine(ui.forumSubject->text());
|
||||
QString name = misc::removeNewLine(ui->forumSubject->text());
|
||||
QString desc;
|
||||
|
||||
RsHtml::optimizeHtml(ui.forumMessage, desc);
|
||||
RsHtml::optimizeHtml(ui->forumMessage, desc);
|
||||
|
||||
if(name.isEmpty() | desc.isEmpty()) {
|
||||
/* error message */
|
||||
@ -415,9 +420,9 @@ void CreateGxsForumMsg::createMsg()
|
||||
if ((msg.mMsg == "") && (msg.mMeta.mMsgName == ""))
|
||||
return; /* do nothing */
|
||||
|
||||
if (ui.signBox->isChecked()) {
|
||||
if (ui->signBox->isChecked()) {
|
||||
RsGxsId authorId;
|
||||
switch (ui.idChooser->getChosenId(authorId)) {
|
||||
switch (ui->idChooser->getChosenId(authorId)) {
|
||||
case GxsIdChooser::KnowId:
|
||||
case GxsIdChooser::UnKnowId:
|
||||
msg.mMeta.mAuthorId = authorId;
|
||||
@ -447,23 +452,23 @@ void CreateGxsForumMsg::createMsg()
|
||||
QMessageBox::warning(this, tr("RetroShare"),tr("Congrats, you found a bug!")+" "+QString(__FILE__)+":"+QString(__LINE__), QMessageBox::Ok, QMessageBox::Ok);
|
||||
|
||||
return;
|
||||
}//switch (ui.idChooser->getChosenId(authorId))
|
||||
}//switch (ui->idChooser->getChosenId(authorId))
|
||||
} else {
|
||||
//std::cerr << "CreateGxsForumMsg::createMsg() No Signature (for now :)";
|
||||
//std::cerr << std::endl;
|
||||
QMessageBox::warning(this, tr("RetroShare"),tr("Please choose Signing Id, it is required"), QMessageBox::Ok, QMessageBox::Ok);
|
||||
return;
|
||||
}//if (ui.signBox->isChecked())
|
||||
}//if (ui->signBox->isChecked())
|
||||
|
||||
int generateCount = 0;
|
||||
|
||||
#ifdef ENABLE_GENERATE
|
||||
if (ui.generateCheckBox->isChecked()) {
|
||||
generateCount = ui.generateSpinBox->value();
|
||||
if (ui->generateCheckBox->isChecked()) {
|
||||
generateCount = ui->generateSpinBox->value();
|
||||
if (QMessageBox::question(this, tr("Generate mass data"), tr("Do you really want to generate %1 messages ?").arg(generateCount), QMessageBox::Yes|QMessageBox::No, QMessageBox::No) == QMessageBox::No) {
|
||||
return;
|
||||
}//if (QMessageBox::question(this,
|
||||
}//if (ui.generateCheckBox->isChecked())
|
||||
}//if (ui->generateCheckBox->isChecked())
|
||||
#endif
|
||||
|
||||
uint32_t token;
|
||||
@ -490,7 +495,7 @@ void CreateGxsForumMsg::closeEvent (QCloseEvent * /*event*/)
|
||||
|
||||
void CreateGxsForumMsg::reject()
|
||||
{
|
||||
if (ui.forumMessage->document()->isModified()) {
|
||||
if (ui->forumMessage->document()->isModified()) {
|
||||
QMessageBox::StandardButton ret;
|
||||
ret = QMessageBox::warning(this, tr("Cancel Forum Message"),
|
||||
tr("Forum Message has not been sent yet!\n"
|
||||
@ -511,7 +516,7 @@ void CreateGxsForumMsg::reject()
|
||||
|
||||
void CreateGxsForumMsg::smileyWidgetForums()
|
||||
{
|
||||
Emoticons::showSmileyWidget(this, ui.emoticonButton, SLOT(addSmileys()), false);
|
||||
Emoticons::showSmileyWidget(this, ui->emoticonButton, SLOT(addSmileys()), false);
|
||||
}
|
||||
|
||||
void CreateGxsForumMsg::addSmileys()
|
||||
@ -520,17 +525,17 @@ void CreateGxsForumMsg::addSmileys()
|
||||
// add trailing space
|
||||
smiley += QString(" ");
|
||||
// add preceding space when needed (not at start of text or preceding space already exists)
|
||||
if(!ui.forumMessage->textCursor().atStart() && ui.forumMessage->toPlainText()[ui.forumMessage->textCursor().position() - 1] != QChar(' '))
|
||||
if(!ui->forumMessage->textCursor().atStart() && ui->forumMessage->toPlainText()[ui->forumMessage->textCursor().position() - 1] != QChar(' '))
|
||||
smiley = QString(" ") + smiley;
|
||||
ui.forumMessage->textCursor().insertText(smiley);
|
||||
ui->forumMessage->textCursor().insertText(smiley);
|
||||
}
|
||||
|
||||
void CreateGxsForumMsg::addFile()
|
||||
{
|
||||
QStringList files;
|
||||
if (misc::getOpenFileNames(this, RshareSettings::LASTDIR_EXTRAFILE, tr("Add Extra File"), "", files)) {
|
||||
ui.hashBox->addAttachments(files,RS_FILE_REQ_ANONYMOUS_ROUTING);
|
||||
ui.hashGroupBox->show();
|
||||
ui->hashBox->addAttachments(files,RS_FILE_REQ_ANONYMOUS_ROUTING);
|
||||
ui->hashGroupBox->show();
|
||||
}
|
||||
}
|
||||
|
||||
@ -541,7 +546,7 @@ void CreateGxsForumMsg::addPicture()
|
||||
QString encodedImage;
|
||||
if (RsHtml::makeEmbeddedImage(file, encodedImage, 640*480, MAX_ALLOWED_GXS_MESSAGE_SIZE - 200)) {
|
||||
QTextDocumentFragment fragment = QTextDocumentFragment::fromHtml(encodedImage);
|
||||
ui.forumMessage->textCursor().insertFragment(fragment);
|
||||
ui->forumMessage->textCursor().insertFragment(fragment);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -563,11 +568,11 @@ void CreateGxsForumMsg::fileHashingFinished(QList<HashedFile> hashedFiles)
|
||||
}
|
||||
|
||||
if (!mesgString.isEmpty()) {
|
||||
ui.forumMessage->textCursor().insertHtml(mesgString);
|
||||
ui->forumMessage->textCursor().insertHtml(mesgString);
|
||||
}
|
||||
|
||||
ui.forumMessage->setFocus( Qt::OtherFocusReason );
|
||||
ui.hashGroupBox->hide();
|
||||
ui->forumMessage->setFocus( Qt::OtherFocusReason );
|
||||
ui->hashGroupBox->hide();
|
||||
}
|
||||
|
||||
void CreateGxsForumMsg::loadCircleInfo(const RsGxsGroupId& circle_id)
|
||||
@ -603,11 +608,11 @@ void CreateGxsForumMsg::loadCircleInfo(const RsGxsGroupId& circle_id)
|
||||
//for(std::set<RsGxsId>::const_iterator it(cg.mInvitedMembers.begin());it!=cg.mInvitedMembers.end();++it)
|
||||
// std::cerr << " added constraint to circle element " << *it << std::endl;
|
||||
|
||||
ui.idChooser->setIdConstraintSet(cg.mInvitedMembers) ;
|
||||
ui.idChooser->setFlags(IDCHOOSER_NO_CREATE | ui.idChooser->flags()) ; // since there's a circle involved, no ID creation can be needed
|
||||
ui->idChooser->setIdConstraintSet(cg.mInvitedMembers) ;
|
||||
ui->idChooser->setFlags(IDCHOOSER_NO_CREATE | ui->idChooser->flags()) ; // since there's a circle involved, no ID creation can be needed
|
||||
|
||||
RsGxsId tmpid ;
|
||||
if(ui.idChooser->countEnabledEntries() == 0)
|
||||
if(ui->idChooser->countEnabledEntries() == 0)
|
||||
{
|
||||
QMessageBox::information(NULL,tr("No compatible ID for this forum"),tr("None of your identities is allowed to post in this forum. This could be due to the forum being limited to a circle that contains none of your identities, or forum flags requiring a PGP-signed identity.")) ;
|
||||
close() ;
|
||||
@ -618,10 +623,10 @@ void CreateGxsForumMsg::loadCircleInfo(const RsGxsGroupId& circle_id)
|
||||
|
||||
void CreateGxsForumMsg::setSubject(const QString& msg)
|
||||
{
|
||||
ui.forumSubject->setText(msg);
|
||||
ui->forumSubject->setText(msg);
|
||||
}
|
||||
|
||||
void CreateGxsForumMsg::insertPastedText(const QString& msg)
|
||||
{
|
||||
ui.forumMessage->append(msg);
|
||||
ui->forumMessage->append(msg);
|
||||
}
|
||||
|
@ -21,10 +21,15 @@
|
||||
#ifndef _CREATE_GXSFORUM_MSG_DIALOG_H
|
||||
#define _CREATE_GXSFORUM_MSG_DIALOG_H
|
||||
|
||||
#include "ui_CreateGxsForumMsg.h"
|
||||
#include <QDialog>
|
||||
|
||||
#include <retroshare/rsgxsforums.h>
|
||||
#include <retroshare/rsgxscircles.h>
|
||||
#include "gui/common/HashBox.h"
|
||||
|
||||
namespace Ui {
|
||||
class CreateGxsForumMsg;
|
||||
}
|
||||
|
||||
class UIStateHelper;
|
||||
|
||||
@ -80,7 +85,7 @@ private:
|
||||
UIStateHelper *mStateHelper;
|
||||
|
||||
/** Qt Designer generated object */
|
||||
Ui::CreateGxsForumMsg ui;
|
||||
Ui::CreateGxsForumMsg *ui;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1278,8 +1278,8 @@ void RsGxsForumModel::recursSetMsgReadStatus(ForumModelIndex i,bool read_status,
|
||||
void *ref ;
|
||||
convertTabEntryToRefPointer(i,ref); // we dont use i+1 here because i is not a row, but an index in the mPosts tab
|
||||
|
||||
QModelIndex itemIndex = createIndex(i - 1, 0, ref);
|
||||
emit dataChanged(itemIndex, itemIndex);
|
||||
QModelIndex itemIndex = (mTreeMode == TREE_MODE_FLAT)?createIndex(i - 1, 0, ref):createIndex(mPosts[i].prow,0,ref);
|
||||
emit dataChanged(itemIndex, itemIndex);
|
||||
}
|
||||
|
||||
if(!with_children)
|
||||
|
@ -276,7 +276,6 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget
|
||||
|
||||
connect(ui->versions_CB, SIGNAL(currentIndexChanged(int)), this, SLOT(changedVersion()));
|
||||
connect(ui->threadTreeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(threadListCustomPopupMenu(QPoint)));
|
||||
connect(ui->postText, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuTextBrowser(QPoint)));
|
||||
connect(ui->forumName, SIGNAL(clicked(QPoint)), this, SLOT(showForumInfo()));
|
||||
|
||||
ui->subscribeToolButton->hide() ;
|
||||
@ -303,8 +302,6 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget
|
||||
connect(ui->filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterItems(QString)));
|
||||
connect(ui->filterLineEdit, SIGNAL(filterChanged(int)), this, SLOT(filterColumnChanged(int)));
|
||||
|
||||
connect(ui->actionSave_image, SIGNAL(triggered()), this, SLOT(saveImage()));
|
||||
|
||||
connect(ui->threadedView_TB, SIGNAL(toggled(bool)), this, SLOT(toggleThreadedView(bool)));
|
||||
connect(ui->flatView_TB, SIGNAL(toggled(bool)), this, SLOT(toggleFlatView(bool)));
|
||||
connect(ui->latestPostInThreadView_TB, SIGNAL(toggled(bool)), this, SLOT(toggleLstPostInThreadView(bool)));
|
||||
@ -793,25 +790,6 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/)
|
||||
contextMnu.exec(QCursor::pos());
|
||||
}
|
||||
|
||||
void GxsForumThreadWidget::contextMenuTextBrowser(QPoint point)
|
||||
{
|
||||
QMatrix matrix;
|
||||
matrix.translate(ui->postText->horizontalScrollBar()->value(), ui->postText->verticalScrollBar()->value());
|
||||
|
||||
QMenu *contextMnu = ui->postText->createStandardContextMenu(matrix.map(point));
|
||||
|
||||
contextMnu->addSeparator();
|
||||
|
||||
if(ui->postText->checkImage(point))
|
||||
{
|
||||
ui->actionSave_image->setData(point);
|
||||
contextMnu->addAction(ui->actionSave_image);
|
||||
}
|
||||
|
||||
contextMnu->exec(ui->postText->viewport()->mapToGlobal(point));
|
||||
delete(contextMnu);
|
||||
}
|
||||
|
||||
void GxsForumThreadWidget::headerContextMenuRequested(const QPoint &pos)
|
||||
{
|
||||
QMenu* header_context_menu = new QMenu(tr("Show column"), this);
|
||||
@ -1823,13 +1801,6 @@ void GxsForumThreadWidget::replyForumMessageData(const RsGxsForumMsg &msg)
|
||||
}
|
||||
}
|
||||
|
||||
void GxsForumThreadWidget::saveImage()
|
||||
{
|
||||
QPoint point = ui->actionSave_image->data().toPoint();
|
||||
QTextCursor cursor = ui->postText->cursorForPosition(point);
|
||||
ImageUtil::extractImage(window(), cursor);
|
||||
}
|
||||
|
||||
void GxsForumThreadWidget::toggleThreadedView(bool b) { if(b) changedViewBox(VIEW_THREADED); }
|
||||
void GxsForumThreadWidget::toggleFlatView(bool b) { if(b) changedViewBox(VIEW_FLAT); }
|
||||
void GxsForumThreadWidget::toggleLstPostInThreadView(bool b) { if(b) changedViewBox(VIEW_LAST_POST); }
|
||||
|
@ -108,7 +108,6 @@ protected:
|
||||
private slots:
|
||||
/** Create the context popup menu and it's submenus */
|
||||
void threadListCustomPopupMenu(QPoint point);
|
||||
void contextMenuTextBrowser(QPoint point);
|
||||
void headerContextMenuRequested(const QPoint& pos);
|
||||
void showForumInfo();
|
||||
|
||||
@ -134,8 +133,6 @@ private slots:
|
||||
// This method is used to perform an asynchroneous action on the message data. Any of the methods above can be used as parameter.
|
||||
void async_msg_action(const MsgMethod& method);
|
||||
|
||||
void saveImage();
|
||||
|
||||
void markMsgAsRead();
|
||||
void markMsgAsReadChildren();
|
||||
void markMsgAsUnread();
|
||||
|
@ -568,9 +568,6 @@
|
||||
<family>MS Sans Serif</family>
|
||||
</font>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@ -578,15 +575,6 @@
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<action name="actionSave_image">
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/document_save.png</normaloff>:/images/document_save.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save image</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
@ -208,6 +208,7 @@
|
||||
<file>icons/svg/newsfeed.svg</file>
|
||||
<file>icons/svg/options.svg</file>
|
||||
<file>icons/svg/paste.svg</file>
|
||||
<file>icons/svg/paste_image.svg</file>
|
||||
<file>icons/svg/people-notify.svg</file>
|
||||
<file>icons/svg/people.svg</file>
|
||||
<file>icons/svg/person.svg</file>
|
||||
|
89
retroshare-gui/src/gui/icons/svg/paste_image.svg
Normal file
89
retroshare-gui/src/gui/icons/svg/paste_image.svg
Normal file
@ -0,0 +1,89 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="800px"
|
||||
height="800px"
|
||||
viewBox="0 0 24 24"
|
||||
version="1.1"
|
||||
id="svg9"
|
||||
sodipodi:docname="paste_image.svg"
|
||||
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs13" />
|
||||
<sodipodi:namedview
|
||||
id="namedview11"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.65"
|
||||
inkscape:cx="400.76923"
|
||||
inkscape:cy="400.76923"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="705"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg9" />
|
||||
<g
|
||||
id=""
|
||||
stroke="none"
|
||||
stroke-width="1"
|
||||
fill="none"
|
||||
fill-rule="evenodd"
|
||||
style="fill:#039bd5;fill-opacity:1"
|
||||
transform="matrix(1.0392218,0,0,1.0392218,-1.9428799,-0.49382824)">
|
||||
<g
|
||||
id=""
|
||||
fill="#212121"
|
||||
fill-rule="nonzero"
|
||||
style="fill:#039bd5;fill-opacity:1">
|
||||
<path
|
||||
id="🎨-Color"
|
||||
style="fill:#039bd5;fill-opacity:1;stroke-width:34.6407"
|
||||
transform="matrix(0.02886775,0,0,0.02886775,1.4076686,0.47519042)"
|
||||
d="m 306.18945,52.820312 c -40.0879,10e-7 -73.09816,30.310784 -77.36133,69.263668 l -61.08593,0.0176 -5.33594,0.17969 c -40.5569,2.74231 -72.605469,36.50942 -72.605469,77.76172 v 467.80859 l 0.179688,5.33594 c 2.742299,40.55688 36.509321,72.60547 77.761721,72.60547 h 52.125 l 3.52539,-0.23633 c 12.68112,-1.72033 22.45508,-12.58924 22.45508,-25.74219 0,-14.34857 -11.63181,-25.98242 -25.98047,-25.98242 h -52.125 l -3.52539,-0.23633 C 151.53568,691.8754 141.76172,681.00453 141.76172,667.85158 V 200.04297 l 0.23633,-3.52539 c 1.72034,-12.68112 12.5912,-22.45508 25.74414,-22.45508 l 73.84375,-0.006 c 13.97689,20.75897 37.69587,34.41602 64.60351,34.41602 h 121.47461 c 26.90774,0 50.62476,-13.65705 64.60156,-34.41602 l 73.84376,0.006 3.52539,0.23828 c 12.681,1.72034 22.45507,12.58925 22.45507,25.74219 v 51.87305 l 0.23828,3.52539 c 1.72033,12.68102 12.5912,22.45507 25.74415,22.45507 14.34857,0 25.98046,-11.6319 25.98046,-25.98046 v -51.87305 l -0.18164,-5.33594 c -2.74229,-40.5569 -36.50942,-72.60547 -77.76171,-72.60547 l -61.08594,-0.0176 C 500.76027,83.131296 467.75208,52.820313 427.66406,52.820312 Z m 0,51.960938 h 121.47461 c 14.28463,0 25.86328,11.58073 25.86328,25.86523 0,14.28461 -11.57865,25.86329 -25.86328,25.86329 H 306.18945 c -14.2845,0 -25.86523,-11.57868 -25.86523,-25.86329 0,-14.2845 11.58073,-25.86523 25.86523,-25.86523 z m 104.03711,225.16602 c -0.33514,0 -0.66945,0.003 -1.0039,0.006 0.0913,0.10704 0.17843,0.24832 0.26953,0.35743 0.6531,-0.11675 1.30303,-0.25154 1.95703,-0.36328 z m 171.90039,104.82031 c 0.14437,0.15262 0.28921,0.30435 0.4336,0.45703 -0.005,-0.10958 -0.0139,-0.21866 -0.0195,-0.32813 -0.14235,-0.0328 -0.27106,-0.0979 -0.41407,-0.1289 z M 409.08203,623.94336 c -0.34384,0.18716 -0.46718,0.25312 -0.68555,0.37109 8.7e-4,0.001 8e-4,0.003 0.002,0.004 0.16412,-0.0872 0.10477,-0.0549 0.64453,-0.3418 0.0129,-0.011 0.0261,-0.0221 0.0391,-0.0332 z m 209.33789,74.14844 c -0.31273,0.21286 -0.62794,0.42235 -0.94336,0.63086 0.55318,0.008 1.09907,-0.028 1.63477,-0.14258 -0.2314,-0.16229 -0.46355,-0.32441 -0.69141,-0.48828 z" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.03347274,0,0,0.03347274,6.3883953,6.7648694)"
|
||||
id="g14">
|
||||
<g
|
||||
id="g6">
|
||||
<g
|
||||
id="g4">
|
||||
<path
|
||||
d="M 426.667,68.267 H 51.2 C 22.923,68.267 0,91.19 0,119.467 V 358.4 c 0,28.277 22.923,51.2 51.2,51.2 h 375.467 c 28.277,0 51.2,-22.923 51.2,-51.2 V 119.467 c 0,-28.277 -22.923,-51.2 -51.2,-51.2 z m 17.066,197.734 -107.4,-107.4 c -6.664,-6.663 -17.468,-6.663 -24.132,0 L 170.667,300.134 114.466,243.933 c -6.664,-6.663 -17.468,-6.663 -24.132,0 L 34.133,300.134 V 119.467 c 0,-9.426 7.641,-17.067 17.067,-17.067 h 375.467 c 9.426,0 17.067,7.641 17.067,17.067 v 146.534 z"
|
||||
data-original="#000000"
|
||||
class="active-path"
|
||||
data-old_color="#000000"
|
||||
fill="#039bd5"
|
||||
id="path2-3" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g12">
|
||||
<g
|
||||
id="g10">
|
||||
<circle
|
||||
cx="153.60001"
|
||||
cy="187.733"
|
||||
r="51.200001"
|
||||
data-original="#000000"
|
||||
class="active-path"
|
||||
data-old_color="#000000"
|
||||
fill="#039bd5"
|
||||
id="circle8" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.8 KiB |
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1215</width>
|
||||
<height>825</height>
|
||||
<width>800</width>
|
||||
<height>650</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -96,13 +96,12 @@ void MessageUserNotify::handleEvent_main_thread(std::shared_ptr<const RsEvent> e
|
||||
|
||||
switch (fe->mMailStatusEventCode) {
|
||||
case RsMailStatusEventCode::NEW_MESSAGE:
|
||||
if (Settings->getNotifyFlags() & RS_POPUP_MSG)
|
||||
for (it = fe->mChangedMsgIds.begin(); it != fe->mChangedMsgIds.end(); ++it) {
|
||||
MessageInfo msgInfo;
|
||||
if (rsMail->getMessage(*it, msgInfo)) {
|
||||
NotifyQt::getInstance()->addToaster(RS_POPUP_MSG, msgInfo.msgId.c_str(), msgInfo.title.c_str(), msgInfo.msg.c_str() );
|
||||
}
|
||||
for (it = fe->mChangedMsgIds.begin(); it != fe->mChangedMsgIds.end(); ++it) {
|
||||
MessageInfo msgInfo;
|
||||
if (rsMail->getMessage(*it, msgInfo)) {
|
||||
NotifyQt::getInstance()->addToaster(RS_POPUP_MSG, msgInfo.msgId.c_str(), msgInfo.title.c_str(), msgInfo.msg.c_str() );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RsMailStatusEventCode::MESSAGE_CHANGED:
|
||||
case RsMailStatusEventCode::MESSAGE_REMOVED:
|
||||
|
@ -1173,37 +1173,73 @@ void NotifyQt::addToaster(uint notifyFlags, const std::string& id, const std::st
|
||||
|
||||
ToasterItem *toaster = NULL;
|
||||
|
||||
uint popupflags = Settings->getNotifyFlags();
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case RS_POPUP_ENCRYPTED_MSG:
|
||||
SoundManager::play(SOUND_MESSAGE_ARRIVED);
|
||||
|
||||
toaster = new ToasterItem(new MessageToaster(std::string(), tr("Unknown title"), QString("[%1]").arg(tr("Encrypted message"))));
|
||||
if ((popupflags & RS_POPUP_MSG) && !_disableAllToaster)
|
||||
{
|
||||
toaster = new ToasterItem(new MessageToaster(std::string(), tr("Unknown title"), QString("[%1]").arg(tr("Encrypted message"))));
|
||||
}
|
||||
break;
|
||||
case RS_POPUP_MSG:
|
||||
SoundManager::play(SOUND_MESSAGE_ARRIVED);
|
||||
|
||||
toaster = new ToasterItem(new MessageToaster(id, QString::fromUtf8(title.c_str()), QString::fromUtf8(msg.c_str())));
|
||||
if ((popupflags & RS_POPUP_MSG) && !_disableAllToaster)
|
||||
{
|
||||
toaster = new ToasterItem(new MessageToaster(id, QString::fromUtf8(title.c_str()), QString::fromUtf8(msg.c_str())));
|
||||
}
|
||||
break;
|
||||
case RS_POPUP_CONNECT:
|
||||
SoundManager::play(SOUND_USER_ONLINE);
|
||||
|
||||
toaster = new ToasterItem(new OnlineToaster(RsPeerId(id)));
|
||||
if ((popupflags & RS_POPUP_CONNECT) && !_disableAllToaster)
|
||||
{
|
||||
toaster = new ToasterItem(new OnlineToaster(RsPeerId(id)));
|
||||
}
|
||||
break;
|
||||
case RS_POPUP_DOWNLOAD:
|
||||
SoundManager::play(SOUND_DOWNLOAD_COMPLETE);
|
||||
|
||||
toaster = new ToasterItem(new DownloadToaster(RsFileHash(id), QString::fromUtf8(title.c_str())));
|
||||
if ((popupflags & RS_POPUP_DOWNLOAD) && !_disableAllToaster)
|
||||
{
|
||||
toaster = new ToasterItem(new DownloadToaster(RsFileHash(id), QString::fromUtf8(title.c_str())));
|
||||
}
|
||||
break;
|
||||
case RS_POPUP_CHAT:
|
||||
toaster = new ToasterItem(new ChatToaster(RsPeerId(id), QString::fromUtf8(msg.c_str())));
|
||||
break;
|
||||
if ((popupflags & RS_POPUP_CHAT) && !_disableAllToaster)
|
||||
{
|
||||
// TODO: fix for distant chat, look up if dstant chat uses RS_POPUP_CHAT
|
||||
ChatDialog *chatDialog = ChatDialog::getChat(ChatId(RsPeerId(id)));
|
||||
ChatWidget *chatWidget;
|
||||
if (chatDialog && (chatWidget = chatDialog->getChatWidget()) && chatWidget->isActive()) {
|
||||
// do not show when active
|
||||
break;
|
||||
}
|
||||
toaster = new ToasterItem(new ChatToaster(RsPeerId(id), QString::fromUtf8(msg.c_str())));
|
||||
}
|
||||
case RS_POPUP_GROUPCHAT:
|
||||
#ifdef RS_DIRECT_CHAT
|
||||
toaster = new ToasterItem(new GroupChatToaster(RsPeerId(id), QString::fromUtf8(msg.c_str())));
|
||||
if ((popupflags & RS_POPUP_GROUPCHAT) && !_disableAllToaster)
|
||||
{
|
||||
MainWindow *mainWindow = MainWindow::getInstance();
|
||||
if (mainWindow && mainWindow->isActiveWindow() && !mainWindow->isMinimized()) {
|
||||
if (MainWindow::getActivatePage() == MainWindow::Friends) {
|
||||
if (FriendsDialog::isGroupChatActive()) {
|
||||
// do not show when active
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
toaster = new ToasterItem(new GroupChatToaster(RsPeerId(id), QString::fromUtf8(msg.c_str())));
|
||||
}
|
||||
#endif // RS_DIRECT_CHAT
|
||||
break;
|
||||
case RS_POPUP_CHATLOBBY:
|
||||
if ((popupflags & RS_POPUP_CHATLOBBY) && !_disableAllToaster)
|
||||
{
|
||||
ChatId chat_id(id);
|
||||
|
||||
@ -1221,13 +1257,16 @@ void NotifyQt::addToaster(uint notifyFlags, const std::string& id, const std::st
|
||||
break; // participant is muted
|
||||
|
||||
toaster = new ToasterItem(new ChatLobbyToaster(chat_id.toLobbyId(), sender, QString::fromUtf8(msg.c_str())));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RS_POPUP_CONNECT_ATTEMPT:
|
||||
if ((popupflags & RS_POPUP_CONNECT_ATTEMPT) && !_disableAllToaster)
|
||||
{
|
||||
// id = gpgid
|
||||
// title = ssl name
|
||||
// msg = peer id
|
||||
toaster = new ToasterItem(new FriendRequestToaster(RsPgpId(id), QString::fromUtf8(title.c_str()), RsPeerId(msg)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1240,4 +1279,6 @@ void NotifyQt::addToaster(uint notifyFlags, const std::string& id, const std::st
|
||||
waitingToasterList.push_back(toaster);
|
||||
}
|
||||
}
|
||||
/* Now start the waiting toasters */
|
||||
startWaitingToasters();
|
||||
}
|
||||
|
@ -125,9 +125,6 @@ void ChatPage::updateFontsAndEmotes()
|
||||
/** Saves the changes on this page */
|
||||
void ChatPage::updateChatParams()
|
||||
{
|
||||
// state of distant Chat combobox
|
||||
Settings->setValue("DistantChat", ui.distantChatComboBox->currentIndex());
|
||||
|
||||
Settings->setChatScreenFont(fontTempChat.toString());
|
||||
NotifyQt::getInstance()->notifyChatFontChanged();
|
||||
|
||||
@ -395,9 +392,23 @@ ChatPage::load()
|
||||
whileBlocking(ui.minimumContrast)->setValue(Settings->value("MinimumContrast", 4.5).toDouble());
|
||||
Settings->endGroup();
|
||||
|
||||
// state of distant Chat combobox
|
||||
int index = Settings->value("DistantChat", 0).toInt();
|
||||
whileBlocking(ui.distantChatComboBox)->setCurrentIndex(index);
|
||||
// state of distant Chat combobox
|
||||
|
||||
switch(rsMsgs->getDistantChatPermissionFlags())
|
||||
{
|
||||
default:
|
||||
case RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_NONE:
|
||||
whileBlocking(ui.distantChatComboBox)->setCurrentIndex(0);
|
||||
break ;
|
||||
|
||||
case RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_NON_CONTACTS:
|
||||
whileBlocking(ui.distantChatComboBox)->setCurrentIndex(1);
|
||||
break ;
|
||||
|
||||
case RS_DISTANT_CHAT_CONTACT_PERMISSION_FLAG_FILTER_EVERYBODY:
|
||||
whileBlocking(ui.distantChatComboBox)->setCurrentIndex(2);
|
||||
break ;
|
||||
}
|
||||
|
||||
fontTempChat.fromString(Settings->getChatScreenFont());
|
||||
|
||||
|
@ -19289,7 +19289,12 @@ p, li { white-space: pre-wrap; }
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+17"/>
|
||||
<location line="+4"/>
|
||||
<source>Save image</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location line="+19"/>
|
||||
<source>Document source</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -23,8 +23,12 @@
|
||||
#include "util/rstime.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QWidget>
|
||||
#include <QTextEdit>
|
||||
#include <QByteArray>
|
||||
#include <QImage>
|
||||
#include <QClipboard>
|
||||
#include <QMimeData>
|
||||
#include <QMessageBox>
|
||||
#include <QString>
|
||||
#include <QTextCursor>
|
||||
@ -37,6 +41,64 @@
|
||||
|
||||
ImageUtil::ImageUtil() {}
|
||||
|
||||
bool ImageUtil::checkImage(const QTextEdit *edit, const QPoint &pos, QRect *cursorRectStartOut, QRect *cursorRectLeftOut, QRect *cursorRectRightOut, QRect *cursorRectEndOut)
|
||||
{
|
||||
QString imageStr;
|
||||
return checkImage(edit, pos, imageStr, cursorRectStartOut, cursorRectLeftOut, cursorRectRightOut, cursorRectEndOut);
|
||||
}
|
||||
|
||||
bool ImageUtil::checkImage(const QTextEdit *edit, const QPoint &pos, QString &imageStr, QRect *cursorRectStartOut, QRect *cursorRectLeftOut, QRect *cursorRectRightOut, QRect *cursorRectEndOut)
|
||||
{
|
||||
//Get text cursor under pos. But if pos is under text browser end line this return last cursor.
|
||||
QTextCursor cursor = edit->cursorForPosition(pos);
|
||||
//First get rect of cursor (could be at left or right of image)
|
||||
QRect cursorRectStart = edit->cursorRect(cursor);
|
||||
//Second get text
|
||||
cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1);//To get character just before
|
||||
QRect cursorRectLeft = edit->cursorRect(cursor);
|
||||
cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, 2);
|
||||
QRect cursorRectRight = edit->cursorRect(cursor);
|
||||
imageStr = cursor.selection().toHtml();
|
||||
|
||||
if (cursorRectStartOut) {
|
||||
*cursorRectStartOut = cursorRectStart;
|
||||
}
|
||||
if (cursorRectLeftOut) {
|
||||
*cursorRectLeftOut = cursorRectLeft;
|
||||
}
|
||||
if (cursorRectRightOut) {
|
||||
*cursorRectRightOut = cursorRectRight;
|
||||
}
|
||||
|
||||
QRect cursorRectEnd = cursorRectStart;
|
||||
//Finally set left with right of precedent character.
|
||||
if (cursorRectEnd.top() < cursorRectLeft.bottom())
|
||||
{
|
||||
cursorRectEnd.setLeft(cursorRectLeft.right());
|
||||
} else {
|
||||
//Image on new line
|
||||
cursorRectEnd.setLeft(0);
|
||||
}
|
||||
//And set Right with left of next character.
|
||||
if (cursorRectEnd.bottom() > cursorRectRight.top())
|
||||
{
|
||||
cursorRectEnd.setRight(cursorRectRight.left());
|
||||
} else {
|
||||
//New line after Image.
|
||||
}
|
||||
|
||||
if (cursorRectEndOut) {
|
||||
*cursorRectEndOut = cursorRectEnd;
|
||||
}
|
||||
|
||||
//If pos is on text rect
|
||||
if (cursorRectEnd.contains(pos))
|
||||
{
|
||||
return imageStr.indexOf("base64,") != -1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ImageUtil::extractImage(QWidget *window, QTextCursor cursor, QString file)
|
||||
{
|
||||
cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1);
|
||||
@ -68,6 +130,34 @@ void ImageUtil::extractImage(QWidget *window, QTextCursor cursor, QString file)
|
||||
}
|
||||
}
|
||||
|
||||
void ImageUtil::copyImage(QWidget *window, QTextCursor cursor)
|
||||
{
|
||||
cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1);
|
||||
cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, 2);
|
||||
QString imagestr = cursor.selection().toHtml();
|
||||
bool success = false;
|
||||
int start = imagestr.indexOf("base64,") + 7;
|
||||
int stop = imagestr.indexOf("\"", start);
|
||||
int length = stop - start;
|
||||
if((start >= 0) && (length > 0))
|
||||
{
|
||||
QByteArray ba = QByteArray::fromBase64(imagestr.mid(start, length).toLatin1());
|
||||
QImage image = QImage::fromData(ba);
|
||||
if(!image.isNull())
|
||||
{
|
||||
success = true;
|
||||
QClipboard *clipboard = QApplication::clipboard();
|
||||
QMimeData *data = new QMimeData;
|
||||
data->setImageData(image);
|
||||
clipboard->setMimeData(data, QClipboard::Clipboard);
|
||||
}
|
||||
}
|
||||
if(!success)
|
||||
{
|
||||
QMessageBox::warning(window, QApplication::translate("ImageUtil", "Copy image"), QApplication::translate("ImageUtil", "Not an image"));
|
||||
}
|
||||
}
|
||||
|
||||
bool ImageUtil::optimizeSizeBytes(QByteArray &bytearray, const QImage &original, QImage &optimized, const char *format, int maxPixels, int maxBytes)
|
||||
{
|
||||
//nothing to do if it fits into the limits
|
||||
|
@ -22,16 +22,21 @@
|
||||
#define IMAGEUTIL_H
|
||||
|
||||
#include <QTextCursor>
|
||||
#include <QWidget>
|
||||
#include <QByteArray>
|
||||
#include <qiterator.h>
|
||||
|
||||
class QWidget;
|
||||
class QTextEdit;
|
||||
class QByteArray;
|
||||
|
||||
class ImageUtil
|
||||
{
|
||||
public:
|
||||
ImageUtil();
|
||||
|
||||
static bool checkImage(const QTextEdit *edit, const QPoint &pos, QRect *cursorRectStartOut = NULL, QRect *cursorRectLeftOut = NULL, QRect *cursorRectRightOut = NULL, QRect *cursorRectEndOut = NULL);
|
||||
static bool checkImage(const QTextEdit *edit, const QPoint &pos, QString &imageStr, QRect *cursorRectStartOut = NULL, QRect *cursorRectLeftOut = NULL, QRect *cursorRectRightOut = NULL, QRect *cursorRectEndOut = NULL);
|
||||
static void extractImage(QWidget *window, QTextCursor cursor, QString file = "");
|
||||
static void copyImage(QWidget *window, QTextCursor cursor);
|
||||
static bool optimizeSizeHtml(QString &html, const QImage& original, QImage &optimized, int maxPixels = -1, int maxBytes = -1);
|
||||
static bool optimizeSizeBytes(QByteArray &bytearray, const QImage &original, QImage &optimized, const char *format, int maxPixels, int maxBytes);
|
||||
static bool hasAlphaContent(const QImage& image);
|
||||
|
Loading…
Reference in New Issue
Block a user