mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-02-17 13:24:15 -05:00
commit
9077d8087a
@ -35,6 +35,7 @@
|
|||||||
#include "util/HandleRichText.h"
|
#include "util/HandleRichText.h"
|
||||||
#include "util/DateTime.h"
|
#include "util/DateTime.h"
|
||||||
#include "util/stringutil.h"
|
#include "util/stringutil.h"
|
||||||
|
#include "gui/gxschannels/CreateGxsChannelMsg.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
@ -65,7 +66,8 @@ GxsChannelPostItem::GxsChannelPostItem(FeedHolder *feedHolder, uint32_t feedId,
|
|||||||
|
|
||||||
setup();
|
setup();
|
||||||
|
|
||||||
setGroup(group, false);
|
//setGroup(group, false);
|
||||||
|
requestGroup();
|
||||||
setPost(post);
|
setPost(post);
|
||||||
requestComment();
|
requestComment();
|
||||||
}
|
}
|
||||||
@ -127,6 +129,7 @@ void GxsChannelPostItem::setup()
|
|||||||
connect(ui->commentButton, SIGNAL(clicked()), this, SLOT(loadComments()));
|
connect(ui->commentButton, SIGNAL(clicked()), this, SLOT(loadComments()));
|
||||||
|
|
||||||
connect(ui->playButton, SIGNAL(clicked()), this, SLOT(play(void)));
|
connect(ui->playButton, SIGNAL(clicked()), this, SLOT(play(void)));
|
||||||
|
connect(ui->editButton, SIGNAL(clicked()), this, SLOT(edit(void)));
|
||||||
connect(ui->copyLinkButton, SIGNAL(clicked()), this, SLOT(copyMessageLink()));
|
connect(ui->copyLinkButton, SIGNAL(clicked()), this, SLOT(copyMessageLink()));
|
||||||
|
|
||||||
connect(ui->readButton, SIGNAL(toggled(bool)), this, SLOT(readToggled(bool)));
|
connect(ui->readButton, SIGNAL(toggled(bool)), this, SLOT(readToggled(bool)));
|
||||||
@ -166,6 +169,12 @@ bool GxsChannelPostItem::setGroup(const RsGxsChannelGroup &group, bool doFill)
|
|||||||
|
|
||||||
mGroup = group;
|
mGroup = group;
|
||||||
|
|
||||||
|
// if not publisher, hide the edit button. Without the publish key, there's no way to edit a message.
|
||||||
|
|
||||||
|
std::cerr << "Group subscribe flags = " << std::hex << mGroup.mMeta.mSubscribeFlags << std::dec << std::endl;
|
||||||
|
if(!IS_GROUP_PUBLISHER(mGroup.mMeta.mSubscribeFlags))
|
||||||
|
ui->editButton->hide();
|
||||||
|
|
||||||
if (doFill) {
|
if (doFill) {
|
||||||
fill();
|
fill();
|
||||||
}
|
}
|
||||||
@ -690,6 +699,12 @@ void GxsChannelPostItem::download()
|
|||||||
updateItem();
|
updateItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GxsChannelPostItem::edit()
|
||||||
|
{
|
||||||
|
CreateGxsChannelMsg *msgDialog = new CreateGxsChannelMsg(mGroup.mMeta.mGroupId,mPost.mMeta.mMsgId);
|
||||||
|
msgDialog->show();
|
||||||
|
}
|
||||||
|
|
||||||
void GxsChannelPostItem::play()
|
void GxsChannelPostItem::play()
|
||||||
{
|
{
|
||||||
std::list<SubFileItem *>::iterator it;
|
std::list<SubFileItem *>::iterator it;
|
||||||
|
@ -78,6 +78,7 @@ private slots:
|
|||||||
void readAndClearItem();
|
void readAndClearItem();
|
||||||
void download();
|
void download();
|
||||||
void play();
|
void play();
|
||||||
|
void edit();
|
||||||
void loadComments();
|
void loadComments();
|
||||||
|
|
||||||
void readToggled(bool checked);
|
void readToggled(bool checked);
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>840</width>
|
<width>1052</width>
|
||||||
<height>180</height>
|
<height>338</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gxsChannelPostItem_GLayout">
|
<layout class="QGridLayout" name="gxsChannelPostItem_GLayout">
|
||||||
@ -332,6 +332,13 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="editButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Edit</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer">
|
<spacer name="horizontalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
@ -39,10 +39,12 @@
|
|||||||
//#define ENABLE_GENERATE
|
//#define ENABLE_GENERATE
|
||||||
|
|
||||||
#define CREATEMSG_CHANNELINFO 0x002
|
#define CREATEMSG_CHANNELINFO 0x002
|
||||||
|
#define CREATEMSG_CHANNEL_POST_INFO 0x003
|
||||||
|
|
||||||
/** Constructor */
|
/** Constructor */
|
||||||
CreateGxsChannelMsg::CreateGxsChannelMsg(const RsGxsGroupId &cId)
|
CreateGxsChannelMsg::CreateGxsChannelMsg(const RsGxsGroupId &cId, RsGxsMessageId existing_post)
|
||||||
: QDialog (NULL, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint), mChannelId(cId) ,mCheckAttachment(true), mAutoMediaThumbNail(false)
|
: QDialog (NULL, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint),
|
||||||
|
mChannelId(cId) , mOrigPostId(existing_post),mCheckAttachment(true), mAutoMediaThumbNail(false)
|
||||||
{
|
{
|
||||||
/* Invoke the Qt Designer generated object setup routine */
|
/* Invoke the Qt Designer generated object setup routine */
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
@ -50,6 +52,10 @@ CreateGxsChannelMsg::CreateGxsChannelMsg(const RsGxsGroupId &cId)
|
|||||||
mChannelQueue = new TokenQueue(rsGxsChannels->getTokenService(), this);
|
mChannelQueue = new TokenQueue(rsGxsChannels->getTokenService(), this);
|
||||||
|
|
||||||
headerFrame->setHeaderImage(QPixmap(":/images/channels.png"));
|
headerFrame->setHeaderImage(QPixmap(":/images/channels.png"));
|
||||||
|
|
||||||
|
if(!existing_post.isNull())
|
||||||
|
headerFrame->setHeaderText(tr("Edit Channel Post"));
|
||||||
|
else
|
||||||
headerFrame->setHeaderText(tr("New Channel Post"));
|
headerFrame->setHeaderText(tr("New Channel Post"));
|
||||||
|
|
||||||
setAttribute ( Qt::WA_DeleteOnClose, true );
|
setAttribute ( Qt::WA_DeleteOnClose, true );
|
||||||
@ -555,6 +561,15 @@ void CreateGxsChannelMsg::newChannelMsg()
|
|||||||
|
|
||||||
uint32_t token;
|
uint32_t token;
|
||||||
mChannelQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, groupIds, CREATEMSG_CHANNELINFO);
|
mChannelQueue->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, groupIds, CREATEMSG_CHANNELINFO);
|
||||||
|
|
||||||
|
if(!mOrigPostId.isNull())
|
||||||
|
{
|
||||||
|
GxsMsgReq message_ids;
|
||||||
|
|
||||||
|
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
||||||
|
message_ids[mChannelId].push_back(mOrigPostId);
|
||||||
|
mChannelQueue->requestMsgInfo(token, RS_TOKREQ_ANSTYPE_SUMMARY, opts, message_ids, CREATEMSG_CHANNEL_POST_INFO);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -628,6 +643,7 @@ void CreateGxsChannelMsg::sendMessage(const std::string &subject, const std::str
|
|||||||
post.mMeta.mThreadId.clear() ;
|
post.mMeta.mThreadId.clear() ;
|
||||||
post.mMeta.mMsgId.clear() ;
|
post.mMeta.mMsgId.clear() ;
|
||||||
|
|
||||||
|
post.mMeta.mOrigMsgId = mOrigPostId;
|
||||||
post.mMeta.mMsgName = subject;
|
post.mMeta.mMsgName = subject;
|
||||||
post.mMsg = msg;
|
post.mMsg = msg;
|
||||||
post.mFiles = files;
|
post.mFiles = files;
|
||||||
@ -686,6 +702,39 @@ void CreateGxsChannelMsg::addThumbnail()
|
|||||||
thumbnail_label->setPixmap(picture);
|
thumbnail_label->setPixmap(picture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CreateGxsChannelMsg::loadChannelPostInfo(const uint32_t &token)
|
||||||
|
{
|
||||||
|
std::cerr << "CreateGxsChannelMsg::loadChannelPostInfo()";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
|
||||||
|
std::vector<RsGxsChannelPost> posts;
|
||||||
|
rsGxsChannels->getPostData(token, posts);
|
||||||
|
|
||||||
|
if (posts.size() != 1)
|
||||||
|
{
|
||||||
|
std::cerr << "CreateGxsChannelMsg::loadChannelPostInfo() ERROR INVALID Number of posts in request" << std::endl;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// now populate the widget with the channel post data.
|
||||||
|
const RsGxsChannelPost& post = posts[0];
|
||||||
|
|
||||||
|
if(post.mMeta.mGroupId != mChannelId || post.mMeta.mMsgId != mOrigPostId)
|
||||||
|
{
|
||||||
|
std::cerr << "CreateGxsChannelMsg::loadChannelPostInfo() ERROR INVALID post ID or channel ID" << std::endl;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
subjectEdit->setText(QString::fromUtf8(post.mMeta.mMsgName.c_str())) ;
|
||||||
|
msgEdit->setText(QString::fromUtf8(post.mMsg.c_str())) ;
|
||||||
|
|
||||||
|
for(std::list<RsGxsFile>::const_iterator it(post.mFiles.begin());it!=post.mFiles.end();++it)
|
||||||
|
addAttachment(it->mHash,it->mName,it->mSize,true,RsPeerId());
|
||||||
|
|
||||||
|
picture.loadFromData(post.mThumbnail.mData,post.mThumbnail.mSize,"PNG");
|
||||||
|
thumbnail_label->setPixmap(picture);
|
||||||
|
}
|
||||||
|
|
||||||
void CreateGxsChannelMsg::loadChannelInfo(const uint32_t &token)
|
void CreateGxsChannelMsg::loadChannelInfo(const uint32_t &token)
|
||||||
{
|
{
|
||||||
std::cerr << "CreateGxsChannelMsg::loadChannelInfo()";
|
std::cerr << "CreateGxsChannelMsg::loadChannelInfo()";
|
||||||
@ -719,6 +768,9 @@ void CreateGxsChannelMsg::loadRequest(const TokenQueue *queue, const TokenReques
|
|||||||
case CREATEMSG_CHANNELINFO:
|
case CREATEMSG_CHANNELINFO:
|
||||||
loadChannelInfo(req.mToken);
|
loadChannelInfo(req.mToken);
|
||||||
break;
|
break;
|
||||||
|
case CREATEMSG_CHANNEL_POST_INFO:
|
||||||
|
loadChannelPostInfo(req.mToken);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
std::cerr << "CreateGxsChannelMsg::loadRequest() UNKNOWN UserType ";
|
std::cerr << "CreateGxsChannelMsg::loadRequest() UNKNOWN UserType ";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
|
@ -38,7 +38,7 @@ class CreateGxsChannelMsg : public QDialog, public TokenResponse, private Ui::Cr
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
/** Default Constructor */
|
/** Default Constructor */
|
||||||
CreateGxsChannelMsg(const RsGxsGroupId& cId);
|
CreateGxsChannelMsg(const RsGxsGroupId& cId, RsGxsMessageId existing_post = RsGxsMessageId());
|
||||||
|
|
||||||
/** Default Destructor */
|
/** Default Destructor */
|
||||||
~CreateGxsChannelMsg();
|
~CreateGxsChannelMsg();
|
||||||
@ -71,6 +71,7 @@ private slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void loadChannelInfo(const uint32_t &token);
|
void loadChannelInfo(const uint32_t &token);
|
||||||
|
void loadChannelPostInfo(const uint32_t &token);
|
||||||
void saveChannelInfo(const RsGroupMetaData &group);
|
void saveChannelInfo(const RsGroupMetaData &group);
|
||||||
|
|
||||||
void parseRsFileListAttachments(const std::string &attachList);
|
void parseRsFileListAttachments(const std::string &attachList);
|
||||||
@ -78,7 +79,9 @@ private:
|
|||||||
bool setThumbNail(const std::string& path, int frame);
|
bool setThumbNail(const std::string& path, int frame);
|
||||||
|
|
||||||
RsGxsGroupId mChannelId;
|
RsGxsGroupId mChannelId;
|
||||||
|
RsGxsMessageId mOrigPostId;
|
||||||
RsGroupMetaData mChannelMeta;
|
RsGroupMetaData mChannelMeta;
|
||||||
|
RsMsgMetaData mOrigMeta;
|
||||||
bool mChannelMetaLoaded;
|
bool mChannelMetaLoaded;
|
||||||
|
|
||||||
std::list<SubFileItem *> mAttachments;
|
std::list<SubFileItem *> mAttachments;
|
||||||
|
@ -438,8 +438,6 @@ void GxsChannelPostsWidget::insertChannelPosts(std::vector<RsGxsChannelPost> &po
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<RsGxsChannelPost>::const_reverse_iterator it;
|
|
||||||
|
|
||||||
int count = posts.size();
|
int count = posts.size();
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
@ -447,17 +445,122 @@ void GxsChannelPostsWidget::insertChannelPosts(std::vector<RsGxsChannelPost> &po
|
|||||||
ui->feedWidget->setSortingEnabled(false);
|
ui->feedWidget->setSortingEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (it = posts.rbegin(); it != posts.rend(); ++it)
|
// collect new versions of posts if any
|
||||||
|
|
||||||
|
#ifdef DEBUG_CHANNEL
|
||||||
|
std::cerr << "Inserting channel posts" << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::vector<uint32_t> new_versions ;
|
||||||
|
for (uint32_t i=0;i<posts.size();++i)
|
||||||
{
|
{
|
||||||
if (thread && thread->stopped()) {
|
if(posts[i].mMeta.mOrigMsgId == posts[i].mMeta.mMsgId)
|
||||||
|
posts[i].mMeta.mOrigMsgId.clear();
|
||||||
|
|
||||||
|
#ifdef DEBUG_CHANNEL
|
||||||
|
std::cerr << " " << i << ": msg_id=" << posts[i].mMeta.mMsgId << ": orig msg id = " << posts[i].mMeta.mOrigMsgId << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(!posts[i].mMeta.mOrigMsgId.isNull())
|
||||||
|
new_versions.push_back(i) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_CHANNEL
|
||||||
|
std::cerr << "New versions: " << new_versions.size() << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(!new_versions.empty())
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_CHANNEL
|
||||||
|
std::cerr << " New versions present. Replacing them..." << std::endl;
|
||||||
|
std::cerr << " Creating search map." << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// make a quick search map
|
||||||
|
std::map<RsGxsMessageId,uint32_t> search_map ;
|
||||||
|
for (uint32_t i=0;i<posts.size();++i)
|
||||||
|
search_map[posts[i].mMeta.mMsgId] = i ;
|
||||||
|
|
||||||
|
for(uint32_t i=0;i<new_versions.size();++i)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_CHANNEL
|
||||||
|
std::cerr << " Taking care of new version at index " << new_versions[i] << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint32_t current_index = new_versions[i] ;
|
||||||
|
uint32_t source_index = new_versions[i] ;
|
||||||
|
RsGxsMessageId source_msg_id = posts[source_index].mMeta.mMsgId ;
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
// In the mean time, all other posts have their MsgId cleared, so that the posts are removed from the list.
|
||||||
|
|
||||||
|
std::vector<uint32_t> versions ;
|
||||||
|
std::map<RsGxsMessageId,uint32_t>::const_iterator vit ;
|
||||||
|
|
||||||
|
while(search_map.end() != (vit=search_map.find(posts[current_index].mMeta.mOrigMsgId)))
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_CHANNEL
|
||||||
|
std::cerr << " post at index " << current_index << " replaces a post at position " << vit->second ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Now replace the post only if the new versionis more recent. It may happen indeed that the same post has been corrected multiple
|
||||||
|
// times. In this case, we only need to replace the post with the newest version
|
||||||
|
|
||||||
|
uint32_t prev_index = current_index ;
|
||||||
|
current_index = vit->second ;
|
||||||
|
|
||||||
|
if(posts[current_index].mMeta.mMsgId.isNull()) // This handles the branching situation where this post has been already erased. No need to go down further.
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_CHANNEL
|
||||||
|
std::cerr << " already erased. Stopping." << std::endl;
|
||||||
|
#endif
|
||||||
break ;
|
break ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thread) {
|
if(posts[current_index].mMeta.mPublishTs < posts[source_index].mMeta.mPublishTs)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_CHANNEL
|
||||||
|
std::cerr << " and is more recent => following" << std::endl;
|
||||||
|
#endif
|
||||||
|
posts[current_index].mMeta.mMsgId.clear(); // clear the msg Id so the post will be ignored
|
||||||
|
}
|
||||||
|
#ifdef DEBUG_CHANNEL
|
||||||
|
else
|
||||||
|
std::cerr << " but is older -> Stopping" << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_CHANNEL
|
||||||
|
std::cerr << "Now adding posts..." << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (std::vector<RsGxsChannelPost>::const_reverse_iterator it = posts.rbegin(); it != posts.rend(); ++it)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_CHANNEL
|
||||||
|
std::cerr << " adding post: " << (*it).mMeta.mMsgId ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(!(*it).mMeta.mMsgId.isNull())
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_CHANNEL
|
||||||
|
std::cerr << " added" << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (thread && thread->stopped())
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (thread)
|
||||||
thread->emitAddPost(qVariantFromValue(*it), related, ++pos, count);
|
thread->emitAddPost(qVariantFromValue(*it), related, ++pos, count);
|
||||||
} else {
|
else
|
||||||
createPostItem(*it, related);
|
createPostItem(*it, related);
|
||||||
}
|
}
|
||||||
|
#ifdef DEBUG_CHANNEL
|
||||||
|
else
|
||||||
|
std::cerr << " skipped" << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!thread) {
|
if (!thread) {
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>793</width>
|
<width>828</width>
|
||||||
<height>465</height>
|
<height>557</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
@ -184,6 +184,20 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="editButton">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Edit current post</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../images.qrc">
|
||||||
|
<normaloff>:/images/edit_24.png</normaloff>:/images/edit_24.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer">
|
<spacer name="horizontalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
@ -454,7 +468,7 @@
|
|||||||
<string notr="true"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
<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">
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
p, li { white-space: pre-wrap; }
|
p, li { white-space: pre-wrap; }
|
||||||
</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
|
</style></head><body style=" font-family:'Sans'; font-size:9pt; 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>
|
<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>
|
||||||
<property name="textInteractionFlags">
|
<property name="textInteractionFlags">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user