diff --git a/libretroshare/src/services/p3gxsreputation.h b/libretroshare/src/services/p3gxsreputation.h index e9a14d4e7..2045e6f05 100644 --- a/libretroshare/src/services/p3gxsreputation.h +++ b/libretroshare/src/services/p3gxsreputation.h @@ -65,12 +65,14 @@ class Reputation { public: Reputation() : - mOwnOpinion(static_cast(RsOpinion::NEUTRAL)), mOwnOpinionTs(0), + mOwnOpinion(static_cast(RsOpinion::NEUTRAL)), + mOwnOpinionTs(0), mFriendAverage(1.0f), - /* G10h4ck: TODO shouln't this be initialized with - * RsReputation::NEUTRAL or UNKOWN? */ - mReputationScore(static_cast(RsOpinion::NEUTRAL)), - mIdentityFlags(0) {} + mFriendsPositive(0), + mFriendsNegative(0), + mReputationScore(1.0f), + mIdentityFlags(0), + mLastUsedTS(0) {} void updateReputation(); diff --git a/retroshare-gui/src/gui/GenCertDialog.cpp b/retroshare-gui/src/gui/GenCertDialog.cpp index e81c3794d..4fdb9f714 100644 --- a/retroshare-gui/src/gui/GenCertDialog.cpp +++ b/retroshare-gui/src/gui/GenCertDialog.cpp @@ -242,7 +242,7 @@ void GenCertDialog::initKeyList() RsAccounts::GetPGPLoginDetails(*it, name, email); std::cerr << "Adding PGPUser: " << name << " id: " << *it << std::endl; QString gid = QString::fromStdString( (*it).toStdString()).right(8) ; - ui.genPGPuser->addItem(QString::fromUtf8(name.c_str()) + " <" + QString::fromUtf8(email.c_str()) + "> (" + gid + ")", userData); + ui.genPGPuser->addItem(QString::fromUtf8(name.c_str()) + " (" + gid + ")", userData); haveGPGKeys = true; } } @@ -294,7 +294,8 @@ void GenCertDialog::setupState() ui.reuse_existing_node_CB->setEnabled(adv_state) ; ui.importIdentity_PB->setVisible(adv_state && !generate_new) ; - ui.exportIdentity_PB->setVisible(adv_state && !generate_new) ; + //ui.exportIdentity_PB->setVisible(adv_state && !generate_new) ; + ui.exportIdentity_PB->setVisible(false); // not useful, and probably confusing ui.genPGPuser->setVisible(adv_state && haveGPGKeys && !generate_new) ; @@ -317,6 +318,11 @@ void GenCertDialog::setupState() ui.password_input->setVisible(true); ui.password_label->setVisible(true); + if(generate_new) + ui.password_input->setToolTip(tr("

Put a strong password here. This password will be required to start your Retroshare node and protects all your data.

")); + else + ui.password_input->setToolTip(tr("

Please supply the existing password for the selected profile above.

")); + ui.password2_check_LB->setVisible(generate_new); ui.password2_input->setVisible(generate_new); ui.password2_label->setVisible(generate_new); @@ -468,7 +474,10 @@ bool GenCertDialog::importIdentity() RsAccounts::GetPGPLoginDetails(gpg_id, name, email); std::cerr << "Adding PGPUser: " << name << " id: " << gpg_id << std::endl; - QMessageBox::information(this,tr("New profile imported"),tr("Your profile was imported successfully:")+" \n"+"\nName :"+QString::fromStdString(name)+"\nemail: " + QString::fromStdString(email)+"\nKey ID: "+QString::fromStdString(gpg_id.toStdString())+"\n\n"+tr("You can use it now to create a new node.")) ; + QMessageBox::information(this,tr("New profile imported"),tr("Your profile was imported successfully:")+" \n"+"\nName :"+QString::fromStdString(name)+"\nKey ID: "+QString::fromStdString(gpg_id.toStdString())+"\n\n"+tr("You can use it now to create a new node.")) ; + + initKeyList(); + setupState(); return true ; } diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp index cd21d3b6c..c822bb492 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp @@ -18,13 +18,16 @@ * * *******************************************************************************/ - #include +#include #include #include "PostedCreatePostDialog.h" #include "ui_PostedCreatePostDialog.h" #include "util/misc.h" #include "util/TokenQueue.h" +#include "util/RichTextEdit.h" +#include "gui/feeds/SubFileItem.h" +#include "util/rsdir.h" #include "gui/settings/rsharesettings.h" #include @@ -32,21 +35,24 @@ #include PostedCreatePostDialog::PostedCreatePostDialog(TokenQueue* tokenQ, RsPosted *posted, const RsGxsGroupId& grpId, QWidget *parent): - QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint), + QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint), mTokenQueue(tokenQ), mPosted(posted), mGrpId(grpId), ui(new Ui::PostedCreatePostDialog) { ui->setupUi(this); Settings->loadWidgetInformation(this); + connect(ui->submitButton, SIGNAL(clicked()), this, SLOT(createPost())); connect(ui->buttonBox, SIGNAL(rejected()), this, SLOT(close())); connect(ui->pushButton, SIGNAL(clicked() ), this , SLOT(addPicture())); - ui->headerFrame->setHeaderImage(QPixmap(":/images/posted_64.png")); - ui->headerFrame->setHeaderText(tr("Submit a new Post")); + ui->headerFrame->setHeaderImage(QPixmap(":/icons/png/postedlinks.png")); + ui->headerFrame->setHeaderText(tr("Create a new Post")); setAttribute ( Qt::WA_DeleteOnClose, true ); + ui->RichTextEditWidget->setPlaceHolderTextPosted(); + /* fill in the available OwnIds for signing */ ui->idChooser->loadIds(IDCHOOSER_ID_REQUIRED, RsGxsId()); } @@ -78,10 +84,21 @@ void PostedCreatePostDialog::createPost() RsPostedPost post; post.mMeta.mGroupId = mGrpId; post.mLink = std::string(ui->linkEdit->text().toUtf8()); - post.mNotes = std::string(ui->notesTextEdit->toPlainText().toUtf8()); - post.mMeta.mMsgName = std::string(ui->titleEdit->text().toUtf8()); - post.mMeta.mAuthorId = authorId; + QString text; + text = ui->RichTextEditWidget->toHtml(); + post.mNotes = std::string(text.toUtf8()); + + post.mMeta.mAuthorId = authorId; + + if(!ui->titleEdit->text().isEmpty()) + { + post.mMeta.mMsgName = std::string(ui->titleEdit->text().toUtf8()); + }else + { + post.mMeta.mMsgName = std::string(ui->titleEditLink->text().toUtf8()); + } + QByteArray ba; QBuffer buffer(&ba); @@ -94,7 +111,7 @@ void PostedCreatePostDialog::createPost() post.mImage.copy((uint8_t *) ba.data(), ba.size()); } - if(ui->titleEdit->text().isEmpty()) { + if(ui->titleEdit->text().isEmpty()&& ui->titleEditLink->text().isEmpty()) { /* error message */ QMessageBox::warning(this, "RetroShare", tr("Please add a Title"), QMessageBox::Ok, QMessageBox::Ok); return; //Don't add a empty title!! @@ -118,4 +135,19 @@ void PostedCreatePostDialog::addPicture() // to show the selected ui->imageLabel->setPixmap(picture); -} \ No newline at end of file +} + +void PostedCreatePostDialog::on_postButton_clicked() +{ + ui->stackedWidget->setCurrentIndex(0); +} + +void PostedCreatePostDialog::on_imageButton_clicked() +{ + ui->stackedWidget->setCurrentIndex(1); +} + +void PostedCreatePostDialog::on_linkButton_clicked() +{ + ui->stackedWidget->setCurrentIndex(2); +} diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h index 587b3f957..de13358fb 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h @@ -23,6 +23,7 @@ #include #include "retroshare/rsposted.h" +#include "util/RichTextEdit.h" class TokenQueue; @@ -41,13 +42,15 @@ public: */ explicit PostedCreatePostDialog(TokenQueue* tokenQ, RsPosted* posted, const RsGxsGroupId& grpId, QWidget *parent = 0); ~PostedCreatePostDialog(); - + QPixmap picture; private slots: void createPost(); void addPicture(); - + void on_postButton_clicked(); + void on_imageButton_clicked(); + void on_linkButton_clicked(); private: QString mLink; diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui index d9d909887..d64c3ad01 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui @@ -7,11 +7,11 @@ 0 0 575 - 467 + 429 - Submit Post + Create a Post @@ -121,24 +121,186 @@ QFrame::Box - You are submitting a link. The key to a successful submission is interesting content and a descriptive title. + You are submitting a post. The key to a successful submission is interesting content and a descriptive title. true + + + + 2 + + + + + Post + + + + :/images/post.png:/images/post.png + + + + 24 + 24 + + + + + + + + Image + + + + :/images/photo.png:/images/photo.png + + + + 24 + 24 + + + + + + + + Link + + + + :/images/link.png:/images/link.png + + + + 24 + 24 + + + + + + + + Qt::Horizontal + + + + 298 + 20 + + + + + + + + + + + + + 0 + 0 + + + + Post as + + + + + + + + 0 + 0 + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel + + + - + 0 - - - Picture - + + + + 0 + + + 6 + + + 0 + + + 0 + + + + + + + + Title + + + + + + - + + 0 + + + 0 + + + 0 + + Qt::Horizontal @@ -151,14 +313,7 @@ - - - - Add Picture - - - - + Preview @@ -186,8 +341,8 @@ - - + + Qt::Horizontal @@ -199,8 +354,8 @@ - - + + Qt::Horizontal @@ -215,34 +370,65 @@ + + + + Add Picture + + + + + + + Picture size is limited to 34 KB + + + - - - Notes - + + + 0 + + + 6 + + + 0 + + + + + Url + + + + + + + Qt::Vertical + + + + 20 + 248 + + + + - + + + Title + + - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + @@ -250,61 +436,14 @@ 0 + + + - Submit + Post - - - - - 0 - 0 - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel - - - - - - - - - Title - - - - - - - - - - Link - - - - - - - - - - - - - Post as - - - - - @@ -322,18 +461,23 @@
gui/common/HeaderFrame.h
1 - - MimeTextEdit - QTextEdit -
gui/common/MimeTextEdit.h
-
GxsIdChooser QComboBox
gui/gxs/GxsIdChooser.h
+ + RichTextEdit + QWidget +
util/RichTextEdit.h
+ 1 +
- + + + + + buttonBox diff --git a/retroshare-gui/src/gui/Posted/PostedItem.cpp b/retroshare-gui/src/gui/Posted/PostedItem.cpp index 6b26a1b0f..5d4e00a93 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.cpp +++ b/retroshare-gui/src/gui/Posted/PostedItem.cpp @@ -27,13 +27,15 @@ #include "gui/feeds/FeedHolder.h" #include "gui/gxs/GxsIdDetails.h" #include "util/misc.h" +#include "util/HandleRichText.h" #include "ui_PostedItem.h" #include - #include +#define LINK_IMAGE ":/images/thumb-link.png" + /** Constructor */ PostedItem::PostedItem(FeedHolder *feedHolder, uint32_t feedId, const RsGxsGroupId &groupId, const RsGxsMessageId &messageId, bool isHome, bool autoUpdate) : @@ -235,7 +237,7 @@ void PostedItem::loadComment(const uint32_t &token) if (comNb == 1) { sComButText = sComButText.append("(1)"); } else if (comNb > 1) { - sComButText = tr("Comments").append(" (%1)").arg(comNb); + sComButText = " " + tr("Comments").append(" (%1)").arg(comNb); } ui->commentButton->setText(sComButText); } @@ -253,22 +255,6 @@ void PostedItem::fill() int desired_height = 1.5*(ui->voteDownButton->height() + ui->voteUpButton->height() + ui->scoreLabel->height()); int desired_width = sqpixmap2.width()*desired_height/(float)sqpixmap2.height(); - if(mPost.mImage.mData != NULL) - { - QPixmap pixmap; - GxsIdDetails::loadPixmapFromData(mPost.mImage.mData, mPost.mImage.mSize, pixmap,GxsIdDetails::ORIGINAL); - // Wiping data - as its been passed to thumbnail. - - QPixmap sqpixmap = pixmap.scaled(desired_width,desired_height, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); - ui->thumbnailLabel->setPixmap(sqpixmap); - ui->pictureLabel->setPixmap(pixmap); - } - else - { - //ui->thumbnailLabel->setFixedSize(desired_width,desired_height); - ui->expandButton->setDisabled(true); - } - QDateTime qtime; qtime.setTime_t(mPost.mMeta.mPublishTs); QString timestamp = qtime.toString("hh:mm dd-MMM-yyyy"); @@ -317,6 +303,28 @@ void PostedItem::fill() } ui->siteLabel->setText(sitestr); + + if(mPost.mImage.mData != NULL) + { + QPixmap pixmap; + GxsIdDetails::loadPixmapFromData(mPost.mImage.mData, mPost.mImage.mSize, pixmap,GxsIdDetails::ORIGINAL); + // Wiping data - as its been passed to thumbnail. + + QPixmap sqpixmap = pixmap.scaled(desired_width,desired_height, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); + ui->thumbnailLabel->setPixmap(sqpixmap); + ui->pictureLabel->setPixmap(pixmap); + } + else if (urlOkay && (mPost.mImage.mData == NULL)) + { + ui->expandButton->setDisabled(true); + ui->thumbnailLabel->setPixmap(QPixmap(LINK_IMAGE)); + } + else + { + ui->expandButton->setDisabled(true); + ui->thumbnailLabel->setPixmap(sqpixmap2); + } + //QString score = "Hot" + QString::number(post.mHotScore); //score += " Top" + QString::number(post.mTopScore); @@ -327,7 +335,8 @@ void PostedItem::fill() ui->scoreLabel->setText(score); // FIX THIS UP LATER. - ui->notes->setText(QString::fromUtf8(mPost.mNotes.c_str())); + ui->notes->setText(RsHtml().formatText(NULL, QString::fromUtf8(mPost.mNotes.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS)); + if(ui->notes->text().isEmpty()) ui->notesButton->hide(); // differences between Feed or Top of Comment. diff --git a/retroshare-gui/src/gui/Posted/PostedItem.ui b/retroshare-gui/src/gui/Posted/PostedItem.ui index f8b19650c..898328677 100644 --- a/retroshare-gui/src/gui/Posted/PostedItem.ui +++ b/retroshare-gui/src/gui/Posted/PostedItem.ui @@ -652,7 +652,7 @@ 1 - + @@ -660,6 +660,12 @@ true + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + @@ -673,17 +679,17 @@ QLabel
gui/common/StyledLabel.h
- - GxsIdLabel - QLabel -
gui/gxs/GxsIdLabel.h
-
ElidedLabel QLabel
gui/common/ElidedLabel.h
1
+ + GxsIdLabel + QLabel +
gui/gxs/GxsIdLabel.h
+
diff --git a/retroshare-gui/src/gui/Posted/Posted_images.qrc b/retroshare-gui/src/gui/Posted/Posted_images.qrc index 0b9e06f2b..8c713b53f 100644 --- a/retroshare-gui/src/gui/Posted/Posted_images.qrc +++ b/retroshare-gui/src/gui/Posted/Posted_images.qrc @@ -17,7 +17,11 @@ images/up-arrow.png images/comments.png images/thumb-default.png + images/thumb-link.png images/share.png images/notes.png + images/link.png + images/post.png + images/photo.png diff --git a/retroshare-gui/src/gui/Posted/images/link.png b/retroshare-gui/src/gui/Posted/images/link.png new file mode 100644 index 000000000..260551cdf Binary files /dev/null and b/retroshare-gui/src/gui/Posted/images/link.png differ diff --git a/retroshare-gui/src/gui/Posted/images/photo.png b/retroshare-gui/src/gui/Posted/images/photo.png new file mode 100644 index 000000000..229214ecd Binary files /dev/null and b/retroshare-gui/src/gui/Posted/images/photo.png differ diff --git a/retroshare-gui/src/gui/Posted/images/post.png b/retroshare-gui/src/gui/Posted/images/post.png new file mode 100644 index 000000000..28d18c2b7 Binary files /dev/null and b/retroshare-gui/src/gui/Posted/images/post.png differ diff --git a/retroshare-gui/src/gui/Posted/images/thumb-link.png b/retroshare-gui/src/gui/Posted/images/thumb-link.png new file mode 100644 index 000000000..70c440f17 Binary files /dev/null and b/retroshare-gui/src/gui/Posted/images/thumb-link.png differ diff --git a/retroshare-gui/src/gui/connect/ConfCertDialog.cpp b/retroshare-gui/src/gui/connect/ConfCertDialog.cpp index c6be06b6e..fc56ebef5 100644 --- a/retroshare-gui/src/gui/connect/ConfCertDialog.cpp +++ b/retroshare-gui/src/gui/connect/ConfCertDialog.cpp @@ -306,11 +306,15 @@ QString ConfCertDialog::getCertificateDescription(const RsPeerDetails& detail,bo infotext += "
    " ; if(use_short_format) + { infotext += "
  • a Profile fingerprint"; + infotext += " (" + QString::fromUtf8(detail.name.c_str()) + "@" + detail.fpr.toStdString().c_str()+") " ; + } else - infotext += "
  • a Profile key"; - - infotext += " (" + QString::fromUtf8(detail.name.c_str()) + "@" + detail.gpg_id.toStdString().c_str()+") " ; + { + infotext += "
  • a Profile public key"; + infotext += " (" + QString::fromUtf8(detail.name.c_str()) + "@" + detail.gpg_id.toStdString().c_str()+") " ; + } if(signatures_included && !use_short_format) infotext += tr("with")+" "+QString::number(detail.gpgSigners.size()-1)+" "+tr("external signatures
  • ") ; diff --git a/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.cpp b/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.cpp index fa038f7fc..85f89f3dc 100644 --- a/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.cpp +++ b/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.cpp @@ -33,6 +33,7 @@ #include "util/HandleRichText.h" #include "util/misc.h" #include "util/rsdir.h" +#include "util/RichTextEdit.h" #include @@ -55,7 +56,7 @@ CreateGxsChannelMsg::CreateGxsChannelMsg(const RsGxsGroupId &cId, RsGxsMessageId Settings->loadWidgetInformation(this); mChannelQueue = new TokenQueue(rsGxsChannels->getTokenService(), this); - headerFrame->setHeaderImage(QPixmap(":/images/channels.png")); + headerFrame->setHeaderImage(QPixmap(":/icons/png/channel.png")); if(!existing_post.isNull()) headerFrame->setHeaderText(tr("Edit Channel Post")); @@ -64,17 +65,19 @@ CreateGxsChannelMsg::CreateGxsChannelMsg(const RsGxsGroupId &cId, RsGxsMessageId setAttribute ( Qt::WA_DeleteOnClose, true ); + buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Post")); + connect(buttonBox, SIGNAL(accepted()), this, SLOT(sendMsg())); connect(buttonBox, SIGNAL(rejected()), this, SLOT(cancelMsg())); connect(addFileButton, SIGNAL(clicked() ), this , SLOT(addExtraFile())); - connect(addfilepushButton, SIGNAL(clicked() ), this , SLOT(addExtraFile())); + connect(addfilepushButton, SIGNAL(clicked() ), this , SLOT(addExtraFile())); + connect(addThumbnailButton, SIGNAL(clicked() ), this , SLOT(addThumbnail())); connect(thumbNailCb, SIGNAL(toggled(bool)), this, SLOT(allowAutoMediaThumbNail(bool))); - connect(tabWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenu(QPoint))); + connect(stackedWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenu(QPoint))); connect(generateCheckBox, SIGNAL(toggled(bool)), generateSpinBox, SLOT(setEnabled(bool))); - connect(addPictureButton, SIGNAL(clicked()), this, SLOT(addPicture())); - connect(msgEdit, SIGNAL(textChanged()), this, SLOT(checkLength())); + generateSpinBox->setEnabled(false); thumbNailCb->setVisible(false); @@ -84,7 +87,6 @@ CreateGxsChannelMsg::CreateGxsChannelMsg(const RsGxsGroupId &cId, RsGxsMessageId thumbNailCb->setVisible(true); thumbNailCb->setEnabled(true); #endif - //buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); setAcceptDrops(true); @@ -95,27 +97,7 @@ CreateGxsChannelMsg::CreateGxsChannelMsg(const RsGxsGroupId &cId, RsGxsMessageId generateSpinBox->hide(); #endif } - -static const uint32_t MAX_ALLOWED_GXS_MESSAGE_SIZE = 199000; - -void CreateGxsChannelMsg::checkLength() -{ - QString text; - RsHtml::optimizeHtml(msgEdit, 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); - infoLabel->setStyleSheet("QLabel#infoLabel { }"); - }else{ - text = tr("Warning: This message is too big of %1 characters after HTML conversion.").arg((0-charRemains)); - infoLabel->setStyleSheet("QLabel#infoLabel {color: red; font: bold; }"); - } - buttonBox->button(QDialogButtonBox::Ok)->setToolTip(text); - buttonBox->button(QDialogButtonBox::Ok)->setEnabled(charRemains>=0); - infoLabel->setText(text); -} - + CreateGxsChannelMsg::~CreateGxsChannelMsg() { Settings->saveWidgetInformation(this); @@ -442,7 +424,7 @@ void CreateGxsChannelMsg::addSubject(const QString& text) void CreateGxsChannelMsg::addHtmlText(const QString& text) { - msgEdit->setHtml(text) ; + RichTextEditWidget->setText(text) ; } void CreateGxsChannelMsg::addAttachment(const std::string &path) @@ -650,8 +632,9 @@ void CreateGxsChannelMsg::sendMsg() /* construct message bits */ std::string subject = std::string(misc::removeNewLine(subjectEdit->text()).toUtf8()); + QString text; - RsHtml::optimizeHtml(msgEdit, text); + text = RichTextEditWidget->toHtml(); std::string msg = std::string(text.toUtf8()); std::list files; @@ -763,18 +746,6 @@ void CreateGxsChannelMsg::addThumbnail() thumbnail_label->setPixmap(picture); } -void CreateGxsChannelMsg::addPicture() -{ - QString file; - if (misc::getOpenFileName(window(), RshareSettings::LASTDIR_IMAGES, tr("Load Picture File"), "Pictures (*.png *.xpm *.jpg *.jpeg)", file)) { - QString encodedImage; - if (RsHtml::makeEmbeddedImage(file, encodedImage, 640*480, MAX_ALLOWED_GXS_MESSAGE_SIZE - 200)) { - QTextDocumentFragment fragment = QTextDocumentFragment::fromHtml(encodedImage); - msgEdit->textCursor().insertFragment(fragment); - } - } -} - void CreateGxsChannelMsg::loadChannelPostInfo(const uint32_t &token) { #ifdef DEBUG_CREATE_GXS_MSG @@ -801,13 +772,16 @@ void CreateGxsChannelMsg::loadChannelPostInfo(const uint32_t &token) } subjectEdit->setText(QString::fromUtf8(post.mMeta.mMsgName.c_str())) ; - msgEdit->setText(QString::fromUtf8(post.mMsg.c_str())) ; + RichTextEditWidget->setText(QString::fromUtf8(post.mMsg.c_str())); for(std::list::const_iterator it(post.mFiles.begin());it!=post.mFiles.end();++it) addAttachment(it->mHash,it->mName,it->mSize,true,RsPeerId(),true); - GxsIdDetails::loadPixmapFromData(post.mThumbnail.mData,post.mThumbnail.mSize,picture,GxsIdDetails::ORIGINAL); - thumbnail_label->setPixmap(picture); + if(post.mThumbnail.mData != NULL) + { + GxsIdDetails::loadPixmapFromData(post.mThumbnail.mData,post.mThumbnail.mSize,picture,GxsIdDetails::ORIGINAL); + thumbnail_label->setPixmap(picture); + } } void CreateGxsChannelMsg::loadChannelInfo(const uint32_t &token) @@ -856,3 +830,13 @@ void CreateGxsChannelMsg::loadRequest(const TokenQueue *queue, const TokenReques } } } + +void CreateGxsChannelMsg::on_channelpostButton_clicked() +{ + stackedWidget->setCurrentIndex(0); +} + +void CreateGxsChannelMsg::on_attachmentsButton_clicked() +{ + stackedWidget->setCurrentIndex(1); +} diff --git a/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.h b/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.h index 96b9dd6d3..1347a96c2 100644 --- a/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.h +++ b/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.h @@ -69,10 +69,10 @@ private slots: void contextMenu(QPoint) ; void addThumbnail(); - void addPicture(); - void checkLength(); void allowAutoMediaThumbNail(bool); + void on_channelpostButton_clicked(); + void on_attachmentsButton_clicked(); private: void loadChannelInfo(const uint32_t &token); void loadChannelPostInfo(const uint32_t &token); diff --git a/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.ui b/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.ui index 8b53c93d6..5086f4acb 100644 --- a/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.ui +++ b/retroshare-gui/src/gui/gxschannels/CreateGxsChannelMsg.ui @@ -37,7 +37,11 @@ 0 - + + + QFrame::Plain + + @@ -47,9 +51,56 @@ QFrame::Raised - + - + + + Channel Post + + + + :/icons/png/comment.png:/icons/png/comment.png + + + + 24 + 24 + + + + + + + + Attachments + + + + :/icons/png/attachements.png:/icons/png/attachements.png + + + + 24 + 24 + + + + + + + + Qt::Horizontal + + + + 486 + 20 + + + + + + true @@ -62,15 +113,138 @@ 0 - - - Channel Post - - - + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + 156 + 107 + + + + + 0 + 0 + + + + :/images/thumb-default-video.png + + + + + + + <!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;"> +<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:10pt; font-weight:600;">Attachments:</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/images/feedback_arrow.png" /><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Use Drag and Drop / Add Files button, to Hash new files.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/images/feedback_arrow.png" /><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Copy/Paste RetroShare links from your shares</span></p></body></html> + + + + + + + Add Channel Thumbnail + + + + :/icons/png/add-image.png:/icons/png/add-image.png + + + + 24 + 24 + + + + + + + + Add File to Attach + + + + :/icons/png/add-file.png:/icons/png/add-file.png + + + + 24 + 24 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + + + Message + + + + 0 + + + + + Title + + + + + + + + + + + + + 0 + 0 + + 75 @@ -94,138 +268,22 @@ - - - - - - Add File to Attach - - - - :/images/add-share24.png:/images/add-share24.png - - - - - - - Add Channel Thumbnail - - - - :/images/add_image24.png:/images/add_image24.png - - - - - - - Add Picture - - - - :/images/add_image24.png:/images/add_image24.png - - - - - - - <!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;"> -<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:10pt; font-weight:600;">Attachments:</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/images/feedback_arrow.png" /><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Use Drag and Drop / Add Files button, to Hash new files.</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><img src=":/images/feedback_arrow.png" /><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> Copy/Paste RetroShare links from your shares</span></p></body></html> - - - - - - - - - - 156 - 107 - - - - - 0 - 0 - - - - :/images/thumb-default-video.png - - - - - - - Qt::Horizontal - - - - 12 - 98 - - - - - - - - Message - - - - - - - - - 75 - true - - - - Subject : - - - - - - - - - - - - - - - - - - - - - - - - - :/images/attachment.png:/images/attachment.png - - - Attachments - + + + 0 + + + 0 + + + 0 + + + 0 + @@ -286,8 +344,8 @@ p, li { white-space: pre-wrap; } - - :/images/add-share24.png:/images/add-share24.png + + :/icons/png/add-file.png:/icons/png/add-file.png @@ -320,7 +378,7 @@ p, li { white-space: pre-wrap; } 0 0 - 812 + 81 24 @@ -371,7 +429,7 @@ p, li { white-space: pre-wrap; } - + @@ -392,6 +450,9 @@ p, li { white-space: pre-wrap; } + + + Qt::Horizontal @@ -408,19 +469,21 @@ p, li { white-space: pre-wrap; } - - MimeTextEdit - QTextEdit -
    gui/common/MimeTextEdit.h
    -
    HeaderFrame QFrame
    gui/common/HeaderFrame.h
    1
    + + RichTextEdit + QWidget +
    util/RichTextEdit.h
    + 1 +
    + diff --git a/retroshare-gui/src/gui/icons.qrc b/retroshare-gui/src/gui/icons.qrc index 5742fa715..81eeecb08 100644 --- a/retroshare-gui/src/gui/icons.qrc +++ b/retroshare-gui/src/gui/icons.qrc @@ -292,5 +292,24 @@ icons/png/exit2.png icons/svg/addstickers.svg icons/png/addstickers.png + icons/textedit/bold.png + icons/textedit/bullet-list.png + icons/textedit/italic.png + icons/textedit/left-indent.png + icons/textedit/link.png + icons/textedit/numberd-list.png + icons/textedit/photo-of-a-landscape.png + icons/textedit/right-indent.png + icons/textedit/strikethrough.png + icons/textedit/underline.png + icons/textedit/copy.png + icons/textedit/cut.png + icons/textedit/paste.png + icons/textedit/redo.png + icons/textedit/undo.png + icons/textedit/settings.png + icons/png/add-file.png + icons/png/add-image.png + icons/png/attachements.png diff --git a/retroshare-gui/src/gui/icons/png/add-file.png b/retroshare-gui/src/gui/icons/png/add-file.png new file mode 100644 index 000000000..e9574feaf Binary files /dev/null and b/retroshare-gui/src/gui/icons/png/add-file.png differ diff --git a/retroshare-gui/src/gui/icons/png/add-image.png b/retroshare-gui/src/gui/icons/png/add-image.png new file mode 100644 index 000000000..68c176be4 Binary files /dev/null and b/retroshare-gui/src/gui/icons/png/add-image.png differ diff --git a/retroshare-gui/src/gui/icons/png/attachements.png b/retroshare-gui/src/gui/icons/png/attachements.png new file mode 100644 index 000000000..1d0941a5d Binary files /dev/null and b/retroshare-gui/src/gui/icons/png/attachements.png differ diff --git a/retroshare-gui/src/gui/icons/textedit/bold.png b/retroshare-gui/src/gui/icons/textedit/bold.png new file mode 100644 index 000000000..27d27c21c Binary files /dev/null and b/retroshare-gui/src/gui/icons/textedit/bold.png differ diff --git a/retroshare-gui/src/gui/icons/textedit/bullet-list.png b/retroshare-gui/src/gui/icons/textedit/bullet-list.png new file mode 100644 index 000000000..313bf7d9c Binary files /dev/null and b/retroshare-gui/src/gui/icons/textedit/bullet-list.png differ diff --git a/retroshare-gui/src/gui/icons/textedit/copy.png b/retroshare-gui/src/gui/icons/textedit/copy.png new file mode 100644 index 000000000..47ecb252b Binary files /dev/null and b/retroshare-gui/src/gui/icons/textedit/copy.png differ diff --git a/retroshare-gui/src/gui/icons/textedit/cut.png b/retroshare-gui/src/gui/icons/textedit/cut.png new file mode 100644 index 000000000..1b4f8c128 Binary files /dev/null and b/retroshare-gui/src/gui/icons/textedit/cut.png differ diff --git a/retroshare-gui/src/gui/icons/textedit/italic.png b/retroshare-gui/src/gui/icons/textedit/italic.png new file mode 100644 index 000000000..446091b91 Binary files /dev/null and b/retroshare-gui/src/gui/icons/textedit/italic.png differ diff --git a/retroshare-gui/src/gui/icons/textedit/left-indent.png b/retroshare-gui/src/gui/icons/textedit/left-indent.png new file mode 100644 index 000000000..abc5edde0 Binary files /dev/null and b/retroshare-gui/src/gui/icons/textedit/left-indent.png differ diff --git a/retroshare-gui/src/gui/icons/textedit/link.png b/retroshare-gui/src/gui/icons/textedit/link.png new file mode 100644 index 000000000..14aa24901 Binary files /dev/null and b/retroshare-gui/src/gui/icons/textedit/link.png differ diff --git a/retroshare-gui/src/gui/icons/textedit/numberd-list.png b/retroshare-gui/src/gui/icons/textedit/numberd-list.png new file mode 100644 index 000000000..d470fa1ac Binary files /dev/null and b/retroshare-gui/src/gui/icons/textedit/numberd-list.png differ diff --git a/retroshare-gui/src/gui/icons/textedit/paste.png b/retroshare-gui/src/gui/icons/textedit/paste.png new file mode 100644 index 000000000..5671cea15 Binary files /dev/null and b/retroshare-gui/src/gui/icons/textedit/paste.png differ diff --git a/retroshare-gui/src/gui/icons/textedit/photo-of-a-landscape.png b/retroshare-gui/src/gui/icons/textedit/photo-of-a-landscape.png new file mode 100644 index 000000000..55f0488c8 Binary files /dev/null and b/retroshare-gui/src/gui/icons/textedit/photo-of-a-landscape.png differ diff --git a/retroshare-gui/src/gui/icons/textedit/redo.png b/retroshare-gui/src/gui/icons/textedit/redo.png new file mode 100644 index 000000000..185d1cc5d Binary files /dev/null and b/retroshare-gui/src/gui/icons/textedit/redo.png differ diff --git a/retroshare-gui/src/gui/icons/textedit/right-indent.png b/retroshare-gui/src/gui/icons/textedit/right-indent.png new file mode 100644 index 000000000..29b34498b Binary files /dev/null and b/retroshare-gui/src/gui/icons/textedit/right-indent.png differ diff --git a/retroshare-gui/src/gui/icons/textedit/settings.png b/retroshare-gui/src/gui/icons/textedit/settings.png new file mode 100644 index 000000000..2f30535c8 Binary files /dev/null and b/retroshare-gui/src/gui/icons/textedit/settings.png differ diff --git a/retroshare-gui/src/gui/icons/textedit/strikethrough.png b/retroshare-gui/src/gui/icons/textedit/strikethrough.png new file mode 100644 index 000000000..e05156e17 Binary files /dev/null and b/retroshare-gui/src/gui/icons/textedit/strikethrough.png differ diff --git a/retroshare-gui/src/gui/icons/textedit/underline.png b/retroshare-gui/src/gui/icons/textedit/underline.png new file mode 100644 index 000000000..5e6125054 Binary files /dev/null and b/retroshare-gui/src/gui/icons/textedit/underline.png differ diff --git a/retroshare-gui/src/gui/icons/textedit/undo.png b/retroshare-gui/src/gui/icons/textedit/undo.png new file mode 100644 index 000000000..ccc85ce28 Binary files /dev/null and b/retroshare-gui/src/gui/icons/textedit/undo.png differ diff --git a/retroshare-gui/src/gui/images.qrc b/retroshare-gui/src/gui/images.qrc index 8496f899b..a54d7fa26 100644 --- a/retroshare-gui/src/gui/images.qrc +++ b/retroshare-gui/src/gui/images.qrc @@ -487,12 +487,17 @@ images/textedit/editpaste.png images/textedit/editredo.png images/textedit/editundo.png + images/textedit/edit-image-face-add.png images/textedit/exportpdf.png images/textedit/filenew.png images/textedit/fileopen.png images/textedit/fileprint.png images/textedit/filesave.png images/textedit/format-text-color.png + images/textedit/format-text-strikethrough.png + images/textedit/format-indent-less.png + images/textedit/format-indent-more.png + images/textedit/insert-link.png images/textedit/format-list-ordered.png images/textedit/format-list-unordered.png images/textedit/zoomin.png diff --git a/retroshare-gui/src/gui/images/textedit/edit-image-face-add.png b/retroshare-gui/src/gui/images/textedit/edit-image-face-add.png new file mode 100644 index 000000000..2a3a46313 Binary files /dev/null and b/retroshare-gui/src/gui/images/textedit/edit-image-face-add.png differ diff --git a/retroshare-gui/src/gui/images/textedit/format-indent-less.png b/retroshare-gui/src/gui/images/textedit/format-indent-less.png new file mode 100644 index 000000000..23d53d029 Binary files /dev/null and b/retroshare-gui/src/gui/images/textedit/format-indent-less.png differ diff --git a/retroshare-gui/src/gui/images/textedit/format-indent-more.png b/retroshare-gui/src/gui/images/textedit/format-indent-more.png new file mode 100644 index 000000000..38ff8bb2a Binary files /dev/null and b/retroshare-gui/src/gui/images/textedit/format-indent-more.png differ diff --git a/retroshare-gui/src/gui/images/textedit/insert-link.png b/retroshare-gui/src/gui/images/textedit/insert-link.png new file mode 100644 index 000000000..f820657ef Binary files /dev/null and b/retroshare-gui/src/gui/images/textedit/insert-link.png differ diff --git a/retroshare-gui/src/gui/qss/stylesheet/Standard.qss b/retroshare-gui/src/gui/qss/stylesheet/Standard.qss index 75a23a3ef..282f4917f 100644 --- a/retroshare-gui/src/gui/qss/stylesheet/Standard.qss +++ b/retroshare-gui/src/gui/qss/stylesheet/Standard.qss @@ -866,3 +866,21 @@ PostedListWidget QTextBrowser#infoDescription { background: transparent; border: none; } + +PostedCreatePostDialog QPushButton#submitButton { + font: bold; + font-size: 15px; + color: white; + background: #0099cc; + border-radius: 4px; + max-height: 27px; + min-width: 4em; + padding: 2px; +} + +PostedCreatePostDialog QPushButton#submitButton:hover { + background: #03b1f3; + border-radius: 4px; + min-width: 4em; + padding: 2px; +} \ No newline at end of file diff --git a/retroshare-gui/src/gui/settings/CryptoPage.ui b/retroshare-gui/src/gui/settings/CryptoPage.ui index 50c0c84fb..bbda9302c 100755 --- a/retroshare-gui/src/gui/settings/CryptoPage.ui +++ b/retroshare-gui/src/gui/settings/CryptoPage.ui @@ -14,7 +14,7 @@ - 0 + 1 @@ -541,7 +541,7 @@ - + 0 0 @@ -569,6 +569,9 @@ + + <html><head/><body><p>This option includes all signatures of your profile key. Signatures are not mandatory, but only a way to express your trust in some particular profile.</p></body></html> + Include signatures @@ -576,6 +579,9 @@ + + <html><head/><body><p>The short format only contains the profile fingerprint, and authentication is based on the node ID (ID of the SSL key). If you choose the old (long) format, the certificate includes the full profile public key. There is no fundamental difference between making friends with either method, because the public profile keys will be exchanged and checked w.r.t. the fingerprint after connection.</p></body></html> + Short format @@ -601,7 +607,7 @@ - Save Key into a file + <html><head/><body><p>Saves your profile key pair into a file. This allows you to create a new node for the same profile, by importing this key pair on a different computer. Friends who already accept connections from you will automatically accept connections from that new node after you add them yourself. Your key is exported encrypted and you will need your login password to create a new profile.</p></body></html> Save certificate to file diff --git a/retroshare-gui/src/retroshare-gui.pro b/retroshare-gui/src/retroshare-gui.pro index d5099aa03..188bd9546 100644 --- a/retroshare-gui/src/retroshare-gui.pro +++ b/retroshare-gui/src/retroshare-gui.pro @@ -623,13 +623,14 @@ HEADERS += rshare.h \ gui/connect/ConnectProgressDialog.h \ gui/groups/CreateGroup.h \ gui/GetStartedDialog.h \ - gui/statistics/BWGraph.h \ - util/RsSyntaxHighlighter.h \ - util/imageutil.h \ - gui/NetworkDialog/pgpid_item_model.h \ - gui/NetworkDialog/pgpid_item_proxy.h \ - gui/common/RsCollection.h \ - util/retroshareWin32.h + gui/statistics/BWGraph.h \ + util/RsSyntaxHighlighter.h \ + util/imageutil.h \ + util/RichTextEdit.h \ + gui/NetworkDialog/pgpid_item_model.h \ + gui/NetworkDialog/pgpid_item_proxy.h \ + gui/common/RsCollection.h \ + util/retroshareWin32.h # gui/ForumsDialog.h \ # gui/forums/ForumDetails.h \ # gui/forums/EditForumDetails.h \ @@ -747,7 +748,8 @@ FORMS += gui/StartDialog.ui \ gui/statistics/StatisticsWindow.ui \ gui/statistics/BwCtrlWindow.ui \ gui/statistics/RttStatistics.ui \ - gui/GetStartedDialog.ui + gui/GetStartedDialog.ui \ + util/RichTextEdit.ui # gui/ForumsDialog.ui \ @@ -825,6 +827,7 @@ SOURCES += main.cpp \ util/HandleRichText.cpp \ util/ObjectPainter.cpp \ util/RsFile.cpp \ + util/RichTextEdit.cpp \ gui/profile/ProfileWidget.cpp \ gui/profile/StatusMessage.cpp \ gui/profile/ProfileManager.cpp \ diff --git a/retroshare-gui/src/util/RichTextEdit.cpp b/retroshare-gui/src/util/RichTextEdit.cpp new file mode 100644 index 000000000..541e6c3eb --- /dev/null +++ b/retroshare-gui/src/util/RichTextEdit.cpp @@ -0,0 +1,616 @@ +/******************************************************************************* + * util/RichTextEdit.cpp * + * * + * Copyright (c) 2019 Retroshare Team * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ + +#include "RichTextEdit.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "util/misc.h" +#include "util/HandleRichText.h" + +static const uint32_t MAX_ALLOWED_GXS_MESSAGE_SIZE = 199000; + +RichTextEdit::RichTextEdit(QWidget *parent) : QWidget(parent) { + setupUi(this); + m_lastBlockList = 0; + f_textedit->setTabStopWidth(40); + + connect(f_textedit, SIGNAL(currentCharFormatChanged(QTextCharFormat)), + this, SLOT(slotCurrentCharFormatChanged(QTextCharFormat))); + connect(f_textedit, SIGNAL(cursorPositionChanged()), + this, SLOT(slotCursorPositionChanged())); + + m_fontsize_h1 = 18; + m_fontsize_h2 = 16; + m_fontsize_h3 = 14; + m_fontsize_h4 = 12; + + fontChanged(f_textedit->font()); + bgColorChanged(f_textedit->textColor()); + + // paragraph formatting + + m_paragraphItems << tr("Standard") + << tr("Heading 1") + << tr("Heading 2") + << tr("Heading 3") + << tr("Heading 4") + << tr("Monospace"); + f_paragraph->addItems(m_paragraphItems); + + connect(f_paragraph, SIGNAL(activated(int)), + this, SLOT(textStyle(int))); + + // undo & redo + + f_undo->setShortcut(QKeySequence::Undo); + f_redo->setShortcut(QKeySequence::Redo); + + connect(f_textedit->document(), SIGNAL(undoAvailable(bool)), + f_undo, SLOT(setEnabled(bool))); + connect(f_textedit->document(), SIGNAL(redoAvailable(bool)), + f_redo, SLOT(setEnabled(bool))); + + f_undo->setEnabled(f_textedit->document()->isUndoAvailable()); + f_redo->setEnabled(f_textedit->document()->isRedoAvailable()); + + connect(f_undo, SIGNAL(clicked()), f_textedit, SLOT(undo())); + connect(f_redo, SIGNAL(clicked()), f_textedit, SLOT(redo())); + + // cut, copy & paste + + f_cut->setShortcut(QKeySequence::Cut); + f_copy->setShortcut(QKeySequence::Copy); + f_paste->setShortcut(QKeySequence::Paste); + + f_cut->setEnabled(false); + f_copy->setEnabled(false); + + connect(f_cut, SIGNAL(clicked()), f_textedit, SLOT(cut())); + connect(f_copy, SIGNAL(clicked()), f_textedit, SLOT(copy())); + connect(f_paste, SIGNAL(clicked()), f_textedit, SLOT(paste())); + + connect(f_textedit, SIGNAL(copyAvailable(bool)), f_cut, SLOT(setEnabled(bool))); + connect(f_textedit, SIGNAL(copyAvailable(bool)), f_copy, SLOT(setEnabled(bool))); + +#ifndef QT_NO_CLIPBOARD + connect(QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(slotClipboardDataChanged())); +#endif + + // link + + f_link->setShortcut(Qt::CTRL + Qt::Key_L); + + connect(f_link, SIGNAL(clicked(bool)), this, SLOT(textLink(bool))); + + // bold, italic & underline + + f_bold->setShortcut(Qt::CTRL + Qt::Key_B); + f_italic->setShortcut(Qt::CTRL + Qt::Key_I); + f_underline->setShortcut(Qt::CTRL + Qt::Key_U); + + connect(f_bold, SIGNAL(clicked()), this, SLOT(textBold())); + connect(f_italic, SIGNAL(clicked()), this, SLOT(textItalic())); + connect(f_underline, SIGNAL(clicked()), this, SLOT(textUnderline())); + connect(f_strikeout, SIGNAL(clicked()), this, SLOT(textStrikeout())); + + QAction *removeFormat = new QAction(tr("Remove character formatting"), this); + removeFormat->setShortcut(QKeySequence("CTRL+M")); + connect(removeFormat, SIGNAL(triggered()), this, SLOT(textRemoveFormat())); + f_textedit->addAction(removeFormat); + + QAction *removeAllFormat = new QAction(tr("Remove all formatting"), this); + connect(removeAllFormat, SIGNAL(triggered()), this, SLOT(textRemoveAllFormat())); + f_textedit->addAction(removeAllFormat); + + QAction *textsource = new QAction(tr("Edit document source"), this); + textsource->setShortcut(QKeySequence("CTRL+O")); + connect(textsource, SIGNAL(triggered()), this, SLOT(textSource())); + f_textedit->addAction(textsource); + + QMenu *menu = new QMenu(this); + menu->addAction(removeAllFormat); + menu->addAction(removeFormat); + menu->addAction(textsource); + f_menu->setMenu(menu); + f_menu->setPopupMode(QToolButton::InstantPopup); + + // lists + + f_list_bullet->setShortcut(Qt::CTRL + Qt::Key_Minus); + f_list_ordered->setShortcut(Qt::CTRL + Qt::Key_Equal); + + connect(f_list_bullet, SIGNAL(clicked(bool)), this, SLOT(listBullet(bool))); + connect(f_list_ordered, SIGNAL(clicked(bool)), this, SLOT(listOrdered(bool))); + + // indentation + + f_indent_dec->setShortcut(Qt::CTRL + Qt::Key_Comma); + f_indent_inc->setShortcut(Qt::CTRL + Qt::Key_Period); + + connect(f_indent_inc, SIGNAL(clicked()), this, SLOT(increaseIndentation())); + connect(f_indent_dec, SIGNAL(clicked()), this, SLOT(decreaseIndentation())); + + // font size + + QFontDatabase db; + foreach(int size, db.standardSizes()) + f_fontsize->addItem(QString::number(size)); + + connect(f_fontsize, SIGNAL(activated(QString)), + this, SLOT(textSize(QString))); + f_fontsize->setCurrentIndex(f_fontsize->findText(QString::number(QApplication::font() + .pointSize()))); + + // text foreground color + + QPixmap pix(16, 16); + pix.fill(QApplication::palette().foreground().color()); + f_fgcolor->setIcon(pix); + + connect(f_fgcolor, SIGNAL(clicked()), this, SLOT(textFgColor())); + + // text background color + + pix.fill(QApplication::palette().background().color()); + f_bgcolor->setIcon(pix); + + connect(f_bgcolor, SIGNAL(clicked()), this, SLOT(textBgColor())); + + // images + connect(f_image, SIGNAL(clicked()), this, SLOT(insertImage())); + + // check message length + connect(f_textedit, SIGNAL(textChanged()), this, SLOT(checkLength())); + +} + + +void RichTextEdit::textSource() { + QDialog *dialog = new QDialog(this); + QPlainTextEdit *pte = new QPlainTextEdit(dialog); + pte->setPlainText( f_textedit->toHtml() ); + QGridLayout *gl = new QGridLayout(dialog); + gl->addWidget(pte,0,0,1,1); + dialog->setWindowTitle(tr("Document source")); + dialog->setMinimumWidth (400); + dialog->setMinimumHeight(600); + dialog->exec(); + + f_textedit->setHtml(pte->toPlainText()); + + delete dialog; +} + + +void RichTextEdit::textRemoveFormat() { + QTextCharFormat fmt; + fmt.setFontWeight(QFont::Normal); + fmt.setFontUnderline (false); + fmt.setFontStrikeOut (false); + fmt.setFontItalic (false); + fmt.setFontPointSize (9); +// fmt.setFontFamily ("Helvetica"); +// fmt.setFontStyleHint (QFont::SansSerif); +// fmt.setFontFixedPitch (true); + + f_bold ->setChecked(false); + f_underline ->setChecked(false); + f_italic ->setChecked(false); + f_strikeout ->setChecked(false); + f_fontsize ->setCurrentIndex(f_fontsize->findText("9")); + +// QTextBlockFormat bfmt = cursor.blockFormat(); +// bfmt->setIndent(0); + + fmt.clearBackground(); + + mergeFormatOnWordOrSelection(fmt); +} + + +void RichTextEdit::textRemoveAllFormat() { + f_bold ->setChecked(false); + f_underline ->setChecked(false); + f_italic ->setChecked(false); + f_strikeout ->setChecked(false); + f_fontsize ->setCurrentIndex(f_fontsize->findText("9")); + QString text = f_textedit->toPlainText(); + f_textedit->setPlainText(text); +} + + +void RichTextEdit::textBold() { + QTextCharFormat fmt; + fmt.setFontWeight(f_bold->isChecked() ? QFont::Bold : QFont::Normal); + mergeFormatOnWordOrSelection(fmt); +} + + +void RichTextEdit::focusInEvent(QFocusEvent *) { + f_textedit->setFocus(Qt::TabFocusReason); +} + + +void RichTextEdit::textUnderline() { + QTextCharFormat fmt; + fmt.setFontUnderline(f_underline->isChecked()); + mergeFormatOnWordOrSelection(fmt); +} + +void RichTextEdit::textItalic() { + QTextCharFormat fmt; + fmt.setFontItalic(f_italic->isChecked()); + mergeFormatOnWordOrSelection(fmt); +} + +void RichTextEdit::textStrikeout() { + QTextCharFormat fmt; + fmt.setFontStrikeOut(f_strikeout->isChecked()); + mergeFormatOnWordOrSelection(fmt); +} + +void RichTextEdit::textSize(const QString &p) { + qreal pointSize = p.toFloat(); + if (p.toFloat() > 0) { + QTextCharFormat fmt; + fmt.setFontPointSize(pointSize); + mergeFormatOnWordOrSelection(fmt); + } +} + +void RichTextEdit::textLink(bool checked) { + bool unlink = false; + QTextCharFormat fmt; + if (checked) { + QString url = f_textedit->currentCharFormat().anchorHref(); + bool ok; + QString newUrl = QInputDialog::getText(this, tr("Create a link"), + tr("Link URL:"), QLineEdit::Normal, + url, + &ok); + if (ok) { + fmt.setAnchor(true); + fmt.setAnchorHref(newUrl); + fmt.setForeground(QApplication::palette().color(QPalette::Link)); + fmt.setFontUnderline(true); + } else { + unlink = true; + } + } else { + unlink = true; + } + if (unlink) { + fmt.setAnchor(false); + fmt.setForeground(QApplication::palette().color(QPalette::Text)); + fmt.setFontUnderline(false); + } + mergeFormatOnWordOrSelection(fmt); +} + +void RichTextEdit::textStyle(int index) { + QTextCursor cursor = f_textedit->textCursor(); + cursor.beginEditBlock(); + + // standard + if (!cursor.hasSelection()) { + cursor.select(QTextCursor::BlockUnderCursor); + } + QTextCharFormat fmt; + cursor.setCharFormat(fmt); + f_textedit->setCurrentCharFormat(fmt); + + if (index == ParagraphHeading1 + || index == ParagraphHeading2 + || index == ParagraphHeading3 + || index == ParagraphHeading4 ) { + if (index == ParagraphHeading1) { + fmt.setFontPointSize(m_fontsize_h1); + } + if (index == ParagraphHeading2) { + fmt.setFontPointSize(m_fontsize_h2); + } + if (index == ParagraphHeading3) { + fmt.setFontPointSize(m_fontsize_h3); + } + if (index == ParagraphHeading4) { + fmt.setFontPointSize(m_fontsize_h4); + } + if (index == ParagraphHeading2 || index == ParagraphHeading4) { + fmt.setFontItalic(true); + } + + fmt.setFontWeight(QFont::Bold); + } + if (index == ParagraphMonospace) { + fmt = cursor.charFormat(); + fmt.setFontFamily("Monospace"); + fmt.setFontStyleHint(QFont::Monospace); + fmt.setFontFixedPitch(true); + } + cursor.setCharFormat(fmt); + f_textedit->setCurrentCharFormat(fmt); + + cursor.endEditBlock(); +} + +void RichTextEdit::textFgColor() { + QColor col = QColorDialog::getColor(f_textedit->textColor(), this); + QTextCursor cursor = f_textedit->textCursor(); + if (!cursor.hasSelection()) { + cursor.select(QTextCursor::WordUnderCursor); + } + QTextCharFormat fmt = cursor.charFormat(); + if (col.isValid()) { + fmt.setForeground(col); + } else { + fmt.clearForeground(); + } + cursor.setCharFormat(fmt); + f_textedit->setCurrentCharFormat(fmt); + fgColorChanged(col); +} + +void RichTextEdit::textBgColor() { + QColor col = QColorDialog::getColor(f_textedit->textBackgroundColor(), this); + QTextCursor cursor = f_textedit->textCursor(); + if (!cursor.hasSelection()) { + cursor.select(QTextCursor::WordUnderCursor); + } + QTextCharFormat fmt = cursor.charFormat(); + if (col.isValid()) { + fmt.setBackground(col); + } else { + fmt.clearBackground(); + } + cursor.setCharFormat(fmt); + f_textedit->setCurrentCharFormat(fmt); + bgColorChanged(col); +} + +void RichTextEdit::listBullet(bool checked) { + if (checked) { + f_list_ordered->setChecked(false); + } + list(checked, QTextListFormat::ListDisc); +} + +void RichTextEdit::listOrdered(bool checked) { + if (checked) { + f_list_bullet->setChecked(false); + } + list(checked, QTextListFormat::ListDecimal); +} + +void RichTextEdit::list(bool checked, QTextListFormat::Style style) { + QTextCursor cursor = f_textedit->textCursor(); + cursor.beginEditBlock(); + if (!checked) { + QTextBlockFormat obfmt = cursor.blockFormat(); + QTextBlockFormat bfmt; + bfmt.setIndent(obfmt.indent()); + cursor.setBlockFormat(bfmt); + } else { + QTextListFormat listFmt; + if (cursor.currentList()) { + listFmt = cursor.currentList()->format(); + } + listFmt.setStyle(style); + cursor.createList(listFmt); + } + cursor.endEditBlock(); +} + +void RichTextEdit::mergeFormatOnWordOrSelection(const QTextCharFormat &format) { + QTextCursor cursor = f_textedit->textCursor(); + if (!cursor.hasSelection()) { + cursor.select(QTextCursor::WordUnderCursor); + } + cursor.mergeCharFormat(format); + f_textedit->mergeCurrentCharFormat(format); + f_textedit->setFocus(Qt::TabFocusReason); +} + +void RichTextEdit::slotCursorPositionChanged() { + QTextList *l = f_textedit->textCursor().currentList(); + if (m_lastBlockList && (l == m_lastBlockList || (l != 0 && m_lastBlockList != 0 + && l->format().style() == m_lastBlockList->format().style()))) { + return; + } + m_lastBlockList = l; + if (l) { + QTextListFormat lfmt = l->format(); + if (lfmt.style() == QTextListFormat::ListDisc) { + f_list_bullet->setChecked(true); + f_list_ordered->setChecked(false); + } else if (lfmt.style() == QTextListFormat::ListDecimal) { + f_list_bullet->setChecked(false); + f_list_ordered->setChecked(true); + } else { + f_list_bullet->setChecked(false); + f_list_ordered->setChecked(false); + } + } else { + f_list_bullet->setChecked(false); + f_list_ordered->setChecked(false); + } +} + +void RichTextEdit::fontChanged(const QFont &f) { + f_fontsize->setCurrentIndex(f_fontsize->findText(QString::number(f.pointSize()))); + f_bold->setChecked(f.bold()); + f_italic->setChecked(f.italic()); + f_underline->setChecked(f.underline()); + f_strikeout->setChecked(f.strikeOut()); + if (f.pointSize() == m_fontsize_h1) { + f_paragraph->setCurrentIndex(ParagraphHeading1); + } else if (f.pointSize() == m_fontsize_h2) { + f_paragraph->setCurrentIndex(ParagraphHeading2); + } else if (f.pointSize() == m_fontsize_h3) { + f_paragraph->setCurrentIndex(ParagraphHeading3); + } else if (f.pointSize() == m_fontsize_h4) { + f_paragraph->setCurrentIndex(ParagraphHeading4); + } else { + if (f.fixedPitch() && f.family() == "Monospace") { + f_paragraph->setCurrentIndex(ParagraphMonospace); + } else { + f_paragraph->setCurrentIndex(ParagraphStandard); + } + } + if (f_textedit->textCursor().currentList()) { + QTextListFormat lfmt = f_textedit->textCursor().currentList()->format(); + if (lfmt.style() == QTextListFormat::ListDisc) { + f_list_bullet->setChecked(true); + f_list_ordered->setChecked(false); + } else if (lfmt.style() == QTextListFormat::ListDecimal) { + f_list_bullet->setChecked(false); + f_list_ordered->setChecked(true); + } else { + f_list_bullet->setChecked(false); + f_list_ordered->setChecked(false); + } + } else { + f_list_bullet->setChecked(false); + f_list_ordered->setChecked(false); + } +} + +void RichTextEdit::fgColorChanged(const QColor &c) { + QPixmap pix(16, 16); + if (c.isValid()) { + pix.fill(c); + } else { + pix.fill(QApplication::palette().foreground().color()); + } + f_fgcolor->setIcon(pix); +} + +void RichTextEdit::bgColorChanged(const QColor &c) { + QPixmap pix(16, 16); + if (c.isValid()) { + pix.fill(c); + } else { + pix.fill(QApplication::palette().background().color()); + } + f_bgcolor->setIcon(pix); +} + +void RichTextEdit::slotCurrentCharFormatChanged(const QTextCharFormat &format) { + fontChanged(format.font()); + bgColorChanged((format.background().isOpaque()) ? format.background().color() : QColor()); + fgColorChanged((format.foreground().isOpaque()) ? format.foreground().color() : QColor()); + f_link->setChecked(format.isAnchor()); +} + +void RichTextEdit::slotClipboardDataChanged() { +#ifndef QT_NO_CLIPBOARD + if (const QMimeData *md = QApplication::clipboard()->mimeData()) + f_paste->setEnabled(md->hasText()); +#endif +} + +QString RichTextEdit::toHtml() const { + QString s = f_textedit->toHtml(); + // convert emails to links + s = s.replace(QRegExp("(<[^a][^>]+>(?:]+>)?|\\s)([a-zA-Z\\d]+@[a-zA-Z\\d]+\\.[a-zA-Z]+)"), "\\1\\2"); + // convert links + s = s.replace(QRegExp("(<[^a][^>]+>(?:]+>)?|\\s)((?:https?|ftp|file)://[^\\s'\"<>]+)"), "\\1\\2"); + // see also: Utils::linkify() + return s; +} + +void RichTextEdit::increaseIndentation() { + indent(+1); +} + +void RichTextEdit::decreaseIndentation() { + indent(-1); +} + +void RichTextEdit::indent(int delta) { + QTextCursor cursor = f_textedit->textCursor(); + cursor.beginEditBlock(); + QTextBlockFormat bfmt = cursor.blockFormat(); + int ind = bfmt.indent(); + if (ind + delta >= 0) { + bfmt.setIndent(ind + delta); + } + cursor.setBlockFormat(bfmt); + cursor.endEditBlock(); +} + +void RichTextEdit::setText(const QString& text) { + if (text.isEmpty()) { + setPlainText(text); + return; + } + if (text[0] == '<') { + setHtml(text); + } else { + setPlainText(text); + } +} + +void RichTextEdit::insertImage() { + QString file; + if (misc::getOpenFileName(window(), RshareSettings::LASTDIR_IMAGES, tr("Load Picture File"), "Pictures (*.png *.xpm *.jpg *.jpeg)", file)) { + QString encodedImage; + if (RsHtml::makeEmbeddedImage(file, encodedImage, 640*480, MAX_ALLOWED_GXS_MESSAGE_SIZE - 200)) { + QTextDocumentFragment fragment = QTextDocumentFragment::fromHtml(encodedImage); + f_textedit->textCursor().insertFragment(fragment); + } + } +} + +void RichTextEdit::checkLength(){ + QString text; + RsHtml::optimizeHtml(f_textedit, 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); + f_info->setStyleSheet("QLabel#f_info { }"); + }else{ + text = tr("Warning: This message is too big of %1 characters after HTML conversion.").arg((0-charRemains)); + f_info->setStyleSheet("QLabel#f_info {color: red; font: bold; }"); + } + //buttonBox->button(QDialogButtonBox::Ok)->setEnabled(charRemains>=0); + f_info->setText(text); +} + + +void RichTextEdit::setPlaceHolderTextPosted() { + f_textedit->setPlaceholderText(tr("Text (optional)")); +} diff --git a/retroshare-gui/src/util/RichTextEdit.h b/retroshare-gui/src/util/RichTextEdit.h new file mode 100644 index 000000000..8a4c95eba --- /dev/null +++ b/retroshare-gui/src/util/RichTextEdit.h @@ -0,0 +1,96 @@ +/******************************************************************************* + * util/RichTextEdit.h * + * * + * Copyright (c) 2019 Retroshare Team * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU Affero General Public License as * + * published by the Free Software Foundation, either version 3 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Affero General Public License for more details. * + * * + * You should have received a copy of the GNU Affero General Public License * + * along with this program. If not, see . * + * * + *******************************************************************************/ + +#ifndef _RICHTEXTEDIT_H_ +#define _RICHTEXTEDIT_H_ + +#include +#include "ui_RichTextEdit.h" + +/** + * @Brief A simple rich-text editor + */ +class RichTextEdit : public QWidget, protected Ui::RichTextEdit { + Q_OBJECT + public: + RichTextEdit(QWidget *parent = 0); + + QString toPlainText() const { return f_textedit->toPlainText(); } + QString toHtml() const; + QTextDocument *document() { return f_textedit->document(); } + QTextCursor textCursor() const { return f_textedit->textCursor(); } + void setTextCursor(const QTextCursor& cursor) { f_textedit->setTextCursor(cursor); } + + public slots: + void setText(const QString &text); + void setPlaceHolderTextPosted(); + + + protected slots: + void setPlainText(const QString &text) { f_textedit->setPlainText(text); } + void setHtml(const QString &text) { f_textedit->setHtml(text); } + void textRemoveFormat(); + void textRemoveAllFormat(); + void textBold(); + void textUnderline(); + void textStrikeout(); + void textItalic(); + void textSize(const QString &p); + void textLink(bool checked); + void textStyle(int index); + void textFgColor(); + void textBgColor(); + void listBullet(bool checked); + void listOrdered(bool checked); + void slotCurrentCharFormatChanged(const QTextCharFormat &format); + void slotCursorPositionChanged(); + void slotClipboardDataChanged(); + void increaseIndentation(); + void decreaseIndentation(); + void insertImage(); + void textSource(); + void checkLength(); + + protected: + void mergeFormatOnWordOrSelection(const QTextCharFormat &format); + void fontChanged(const QFont &f); + void fgColorChanged(const QColor &c); + void bgColorChanged(const QColor &c); + void list(bool checked, QTextListFormat::Style style); + void indent(int delta); + void focusInEvent(QFocusEvent *event); + + QStringList m_paragraphItems; + int m_fontsize_h1; + int m_fontsize_h2; + int m_fontsize_h3; + int m_fontsize_h4; + + enum ParagraphItems { ParagraphStandard = 0, + ParagraphHeading1, + ParagraphHeading2, + ParagraphHeading3, + ParagraphHeading4, + ParagraphMonospace }; + + QPointer m_lastBlockList; +}; + +#endif diff --git a/retroshare-gui/src/util/RichTextEdit.ui b/retroshare-gui/src/util/RichTextEdit.ui new file mode 100644 index 000000000..7b5ffc6ae --- /dev/null +++ b/retroshare-gui/src/util/RichTextEdit.ui @@ -0,0 +1,610 @@ + + + RichTextEdit + + + + 0 + 0 + 703 + 312 + + + + + + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + + + + 2 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::ClickFocus + + + Paragraph formatting + + + true + + + + + + + + MS Sans Serif + 10 + + + + Qt::ClickFocus + + + Font size + + + true + + + + + + + Qt::ClickFocus + + + Text foreground color + + + . + + + + 22 + 22 + + + + + + + + Qt::ClickFocus + + + Text background color + + + . + + + + 22 + 22 + + + + + + + + Qt::Vertical + + + + + + + false + + + Qt::ClickFocus + + + Undo (CTRL+Z) + + + Undo + + + + :/icons/textedit/undo.png:/icons/textedit/undo.png + + + + 22 + 22 + + + + + + + + false + + + Qt::ClickFocus + + + Redo + + + Redo + + + + :/icons/textedit/redo.png:/icons/textedit/redo.png + + + + 22 + 22 + + + + + + + + Qt::ClickFocus + + + Cut (CTRL+X) + + + Cut + + + + :/icons/textedit/cut.png:/icons/textedit/cut.png + + + + 22 + 22 + + + + + + + + Qt::ClickFocus + + + Copy (CTRL+C) + + + Copy + + + + :/icons/textedit/copy.png:/icons/textedit/copy.png + + + + 22 + 22 + + + + + + + + Qt::ClickFocus + + + Paste (CTRL+V) + + + Paste + + + + :/icons/textedit/paste.png:/icons/textedit/paste.png + + + + 22 + 22 + + + + + + + + Qt::Vertical + + + + + + + Qt::ClickFocus + + + Link (CTRL+L) + + + Link + + + + :/icons/textedit/link.png:/icons/textedit/link.png + + + + 22 + 22 + + + + true + + + + + + + Qt::Vertical + + + + + + + Qt::ClickFocus + + + Bold (CTRL+B) + + + Bold + + + + :/icons/textedit/bold.png:/icons/textedit/bold.png + + + + 22 + 22 + + + + true + + + + + + + Qt::ClickFocus + + + Italic (CTRL+I) + + + Italic + + + + :/icons/textedit/italic.png:/icons/textedit/italic.png + + + + 22 + 22 + + + + true + + + + + + + Qt::ClickFocus + + + Underline (CTRL+U) + + + Underline + + + + :/icons/textedit/underline.png:/icons/textedit/underline.png + + + + 22 + 22 + + + + true + + + + + + + + :/icons/textedit/strikethrough.png:/icons/textedit/strikethrough.png + + + + 22 + 22 + + + + true + + + + + + + Qt::Vertical + + + + + + + Qt::ClickFocus + + + Bullet list (CTRL+-) + + + Bullet list + + + + :/icons/textedit/bullet-list.png:/icons/textedit/bullet-list.png + + + + 22 + 22 + + + + true + + + + + + + Qt::ClickFocus + + + Ordered list (CTRL+=) + + + Ordered list + + + + :/icons/textedit/numberd-list.png:/icons/textedit/numberd-list.png + + + + 22 + 22 + + + + true + + + + + + + Qt::ClickFocus + + + Decrease indentation (CTRL+,) + + + + :/icons/textedit/left-indent.png:/icons/textedit/left-indent.png + + + + 22 + 22 + + + + + + + + Qt::ClickFocus + + + Increase indentation (CTRL+.) + + + + :/icons/textedit/right-indent.png:/icons/textedit/right-indent.png + + + + 22 + 22 + + + + + + + + Qt::Vertical + + + + + + + Attach a Picture + + + + :/icons/textedit/photo-of-a-landscape.png:/icons/textedit/photo-of-a-landscape.png + + + + 22 + 22 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + :/icons/textedit/settings.png:/icons/textedit/settings.png + + + + 22 + 22 + + + + + + f_paragraph + f_undo + f_redo + f_cut + f_copy + f_paste + line + f_link + line_3 + f_italic + f_underline + line_2 + line_5 + f_list_bullet + f_list_ordered + f_indent_dec + f_indent_inc + f_bold + f_strikeout + f_image + f_menu + f_fontsize + f_fgcolor + f_bgcolor + line_4 + + + + + + + MS Sans Serif + 9 + + + + QTextEdit::AutoNone + + + true + + + Text + + + + + + + TextLabel + + + + + + + + MimeTextEdit + QTextEdit +
    gui/common/MimeTextEdit.h
    +
    +
    + + f_textedit + f_strikeout + f_image + f_menu + + + + + + +