From 47678b33a4e86e37bf3059e0d9f2d5ee4c7e595b Mon Sep 17 00:00:00 2001 From: defnax Date: Thu, 19 Dec 2019 19:05:13 +0100 Subject: [PATCH 1/5] Added new rich text editor & improved design for Create Post * Added new Rich Text Editor * Redesigned the Create Post Composer for Posted Links * When only link is added display different thumbnail --- .../src/gui/Posted/PostedCreatePostDialog.cpp | 50 +- .../src/gui/Posted/PostedCreatePostDialog.h | 7 +- .../src/gui/Posted/PostedCreatePostDialog.ui | 338 +++++++--- retroshare-gui/src/gui/Posted/PostedItem.cpp | 47 +- retroshare-gui/src/gui/Posted/PostedItem.ui | 18 +- .../src/gui/Posted/Posted_images.qrc | 4 + retroshare-gui/src/gui/Posted/images/link.png | Bin 0 -> 2598 bytes .../src/gui/Posted/images/photo.png | Bin 0 -> 1938 bytes retroshare-gui/src/gui/Posted/images/post.png | Bin 0 -> 1161 bytes .../src/gui/Posted/images/thumb-link.png | Bin 0 -> 8779 bytes retroshare-gui/src/gui/icons.qrc | 20 +- .../src/gui/icons/textedit/bold.png | Bin 0 -> 2075 bytes .../src/gui/icons/textedit/bullet-list.png | Bin 0 -> 541 bytes .../src/gui/icons/textedit/copy.png | Bin 0 -> 2332 bytes retroshare-gui/src/gui/icons/textedit/cut.png | Bin 0 -> 3066 bytes .../src/gui/icons/textedit/italic.png | Bin 0 -> 738 bytes .../src/gui/icons/textedit/left-indent.png | Bin 0 -> 991 bytes .../src/gui/icons/textedit/link.png | Bin 0 -> 2598 bytes .../src/gui/icons/textedit/numberd-list.png | Bin 0 -> 1709 bytes .../src/gui/icons/textedit/paste.png | Bin 0 -> 2593 bytes .../icons/textedit/photo-of-a-landscape.png | Bin 0 -> 1938 bytes .../src/gui/icons/textedit/redo.png | Bin 0 -> 2140 bytes .../src/gui/icons/textedit/right-indent.png | Bin 0 -> 988 bytes .../src/gui/icons/textedit/settings.png | Bin 0 -> 2768 bytes .../src/gui/icons/textedit/strikethrough.png | Bin 0 -> 2832 bytes .../src/gui/icons/textedit/underline.png | Bin 0 -> 1451 bytes .../src/gui/icons/textedit/undo.png | Bin 0 -> 2145 bytes retroshare-gui/src/gui/images.qrc | 5 + .../images/textedit/edit-image-face-add.png | Bin 0 -> 1118 bytes .../images/textedit/format-indent-less.png | Bin 0 -> 718 bytes .../images/textedit/format-indent-more.png | Bin 0 -> 701 bytes .../src/gui/images/textedit/insert-link.png | Bin 0 -> 1356 bytes .../src/gui/qss/stylesheet/Standard.qss | 18 + retroshare-gui/src/util/MRichTextEdit.cpp | 620 ++++++++++++++++++ retroshare-gui/src/util/MRichTextEdit.h | 101 +++ retroshare-gui/src/util/MRichTextEdit.ui | 598 +++++++++++++++++ 36 files changed, 1691 insertions(+), 135 deletions(-) create mode 100644 retroshare-gui/src/gui/Posted/images/link.png create mode 100644 retroshare-gui/src/gui/Posted/images/photo.png create mode 100644 retroshare-gui/src/gui/Posted/images/post.png create mode 100644 retroshare-gui/src/gui/Posted/images/thumb-link.png create mode 100644 retroshare-gui/src/gui/icons/textedit/bold.png create mode 100644 retroshare-gui/src/gui/icons/textedit/bullet-list.png create mode 100644 retroshare-gui/src/gui/icons/textedit/copy.png create mode 100644 retroshare-gui/src/gui/icons/textedit/cut.png create mode 100644 retroshare-gui/src/gui/icons/textedit/italic.png create mode 100644 retroshare-gui/src/gui/icons/textedit/left-indent.png create mode 100644 retroshare-gui/src/gui/icons/textedit/link.png create mode 100644 retroshare-gui/src/gui/icons/textedit/numberd-list.png create mode 100644 retroshare-gui/src/gui/icons/textedit/paste.png create mode 100644 retroshare-gui/src/gui/icons/textedit/photo-of-a-landscape.png create mode 100644 retroshare-gui/src/gui/icons/textedit/redo.png create mode 100644 retroshare-gui/src/gui/icons/textedit/right-indent.png create mode 100644 retroshare-gui/src/gui/icons/textedit/settings.png create mode 100644 retroshare-gui/src/gui/icons/textedit/strikethrough.png create mode 100644 retroshare-gui/src/gui/icons/textedit/underline.png create mode 100644 retroshare-gui/src/gui/icons/textedit/undo.png create mode 100644 retroshare-gui/src/gui/images/textedit/edit-image-face-add.png create mode 100644 retroshare-gui/src/gui/images/textedit/format-indent-less.png create mode 100644 retroshare-gui/src/gui/images/textedit/format-indent-more.png create mode 100644 retroshare-gui/src/gui/images/textedit/insert-link.png create mode 100644 retroshare-gui/src/util/MRichTextEdit.cpp create mode 100644 retroshare-gui/src/util/MRichTextEdit.h create mode 100644 retroshare-gui/src/util/MRichTextEdit.ui diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp index cd21d3b6c..2dea36101 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/MRichTextEdit.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->MRichTextEditWidget->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->MRichTextEditWidget->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..212faa159 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/MRichTextEdit.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..97ad94741 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
+ + MRichTextEdit + QWidget +
util/MRichTextEdit.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 0000000000000000000000000000000000000000..260551cdfad9bf9fba0f01111952d5b6a5db23b3 GIT binary patch literal 2598 zcmZ`(c|4SB8-8XFDWT&;4uvf9Wl3b2h%rSa5tZaf+HDnO2{WNADJ4s@FcnUbrGrD8 zr7s+13$utKTWGP1vCMqWJ39To?~m{Id*A1|pZmS;>%On+eSdG<-aR{{B^4zB0Md50 zHcoJ-A@?#2T&F(X62J|6(#qZnfIkzZ7CdqAtm8n`q(xPy>D7+^s|ps`4dn1jgVLHE#*d5QdoST10;W7Cn5phbYe zM|we%Sv)k81K7<-p3Vbl?+_~>147ON8Esew4^m;7VioX}iJ!t=FhDan(0mLFwi7FY zF9H!Iu0>$tn6YF67u*+%64Sy*h#VM0W<)81TuT14@-PhKy+dcPKSaS;+y#-zg`b;u2-i+S{RV08NHyJsn9HlnpIbH8Qn!u|buwR11Hl?jGxAAdb6TYEq?iN`LboS_P+?j zSi{A8*?PpLQ~NeHyF zrx5y_mFq_HKtojMq!}neX0yu-c82JPI8m&0Sd~> zO2Ou^mHaqbqSUq}6{mC8)j3(#$uUGKPyM>z{)?6G1ZjsKY91rf)sjbR1LF1qq0oeY21#e+Rlf8GC^-yh=c?(IYU z*jSdI`Aj&i6u%m;bY)^oO0tgc8{@VOIRj|HYB%RR+0xeSQq|*XI$Y^T4?ATl8dWR! zBIe9IFtWYsl|%gm_6S!Q^czod zRX#2YJv%W)(09RPETB5}f^T>%c*HqDW8c2YC-nG|6xAuz(!C{p)!Q{e^2zQJOYX~@Xzq+a06lReexqzk7sG^vD| zEt8c=zfAjS-3=@GK3(jf%X$!3f!@p-Uf)&33Nz5JxF$y}rTE_S+NpP;vcZFzWK?xU z?`wdJ@4$=Rpn}2%_KP<)qwbWj`Z+}pVO9pge^f2Pg*4<%t|E%6v)3;0yT_V?zC@>| z`+ss(Ge7Co`&`9alV~X*5!m620jE;+XoW?>;oyK->wZDQt)kL0>!_--7h59>c2pYb zq;-?>7Unl7U$A{4G8)Z2Sgx?)x~O6<)veUtX;JS?qh)-5e`UJ2(5PNCGj2~>utqKT z{3gtH6;h)LxuW)!S|m$G{Bn_4!%yz5~h!Qk48tR1#k2 zh~9SNGy7VG_}=7zxWmHa8`r4^FK(Qyo4c7PTYl0%a+VwI7&#&mrH=+0Opu$;jkTH9 zTAnnQ6M1Ej-6;Hb0^k@`BNWITCbqwsbP#^8w0PP>pc+OKR%(z04qw_n8>q}K*i}qF zzrr3Luxxwi_Qj&#qkk*$yQ#m>u%mVAiey9^9lwV(g|7`FuB%AQD3|~0M?C5mejs~l z_Vp9dTw>9DrBCkYxpY7F>}Qj{_-yNS@|Kae{b_!l5tQtR7*>4kLJMj*EcPWT8GfI? zVSTda7RPlY^ez`Jvqp_ktJZ%TGHT^((YS{@#HN&97bM(c^R*X+fVNV~jh+_E0M`C;*>dZwUo)CEiyhXa7^-SX99Z5<0|8Nrvq$9L^7^<1$poJS`@sy<}!(;>sy+ z2Fdak&W6K@h3}~Y4AB{_6#`<#diF|7&qT}lP&JuXG1xPqlh*<*stS|&`wpF$^ z<)6qMvKq9_Bb}CpyVeeuEAGNhqFVE9C}nQMh-RnfM@&>y$*Z&0p~7gEwRZ$p7e%M@ z>plCKlzvP1DBTUhjhPkF6Z@~GT<&hH#Mcxgn+wNc%yGRRc6J88)vUZS@RntfBFb58 z8PPC}xmo7o<~+_f&kBF>dzyL9!N|sy%E@6uW8dbkxKzbmCQm~$$D7W^)J^iKsEcoE z30OH48UDF70x1Urk9h_jH}g7w9ByEfzJcjRgH0O^^qmd1m>F#`Gc+aY>znE8>%<7U z{-?m#|JdmhA^*R?t;6alELekd*yn#DFv#=#aS#*~q~UTH^Cy`jBt-}U Nc9cCf1=dF*{{#FF*F69L literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..229214ecdae189d3a58c259b93260b2fd3da1cc5 GIT binary patch literal 1938 zcmZ`&dt8%c6h6B#m=j365JX}m5D0856%Y|{#FktZH$_(rVHipi?yyrdVdCqy>^L<|tCp=_6 z#f}01^VuwBBw8idV@^PJYV7a}v=Fxih6MtgEt&T+frR#siLA&lfNW=k%Lkaj@Q(m? z(g2?D0DLO|mIxG=KlTH_FXe< zUam7`O%apD%QXar7UTmU9U&?ZQiqpm5YgzHitC6n9hCPV7*cAk!Cn$KwGRn(vP?@9ZC^V z9jvAfD$&9FP_rNHiYSyndll+gkXf3SWtc!IV2@Irm+#G zPz%ZdQ`TgSdN2VbnT90A90Wibj9KFtu@Rx}D58PNA>-@Np{D4VBxN6hVKr-d&_F=a z0_CQO=`d|yk3;Q{=|w>Gt4X3QQPz)Tl><=OOH}p~rC2F+qf)35psdM9vgJA~Wttdj zWE>RAqEBP60RJmm&I=>Mqrfbp;==9n@R8xL?77{aY_Xo0T(C2%facHh%>{Fk?I*W$D~*Z0x{l&?x?s;AE{Z}_Gz^`(q(RGM_`3vs~b z!ET|XKmJ-#baUYw_|xs=Vr6>9_Nb}oS^HC7{MxoYy9f0r%l2%XUdebkU;W+r+*toZ z)raMr@I_l8X~SF>)^ zBpnXSPD(kp4 z)Mcycx^l`^y~wPL;BGAYdzdY|8)R-}yh=({k17Vdi*43;_}?5_y4FF+4tl^eQ1|)k zp+Gu07niMVKEh;W9;}pTK45I=7E6STkoZ<^S+$qr5nC6-O<7&aIp-b49UD4z)5GNx z6A!_13@i&*v?kr@?2@MU&a3BDUwgk{xmUbZYYo0IED&E;_}0lUc)xe#`niiYnGZ)kcVo#C@lM*fS^hU%v2+ z)#~fUyFzI-o9*D*JGcfA7O7Ql)pxFD*-+G>q|{jIz*eap-`%V(U8YUj$mIL>)@URD0cUy@yq*XMrJ%m}#gb|*)f^N^IB z(;9SrcMY|^f^A?TjR00s@a9-wwUK1N+PC4WOIw} zjqv>5dDFqddyq2Ku-J)MtGal`uqikGOpLDu*;|ay`?i*KdaaNHojBKUp9dU{g@78M zq7E*cV&KAq9w`pesy3fkO09FEs4m{ZjorR$j=!_>)-*vO3Z{;^1y2z==)*1yoF|w0 zjKGb|cFi~Q_H>%Xon{i%g_Gp=Qm$6JV_$#spcF#W|KMBhx8GBFDec}?n6iz7z1<^o z86(qocHJl-QAhbt$W5YkpS4`rzP*ubl_3dn`brNaYpnGU@gZGO*IhBYzw6LrvTcs1 zmEb3i+Nz+uLM++HKPRzWu7_j&XtO$<4_!_EDU9oM{nhri=2FSBhojZ8GMfJC#91HW z*q6!&VhNsnB7R`YqCniZ)NKamUp2EoA~oAOU@#;`563zBApfDyBwq0`)9n|ZHi^60 zA5;FRZX6Z4hAIvFl6lb-^ANFfqHa`q_I@E$srSa^ioWRP-Y2zsX=V=DB*V+(PaKEg z7Xgr8zpWcLZcQjTOdAb3u-d6MDn6iPZe42l+&9~D3yMnLb(o!B`F!Q28U2rjrycgi z$B19f7+#2N#zRwk=i>eBHY@TE7_X3@b9G(wio^>;+32raE)3ozOiB>)eG@bJXaNR| z?&Cpcc+giz(^vV@eSF`ixzlLAG#Z_E@AiKPpQk6KB=7luLcrQ&0V2GKb%;t&7K#!w j`5+RBJX6wkWF;mD_@3#R+vJmeb_fLQ;Be;YAYR_TxN%Ml literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..28d18c2b7222fb1950e0a8d9bec208ac22a6d1f7 GIT binary patch literal 1161 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSEX7WqAsj$Z!;#Vf4nJ zFmDB6My|T7XrQ2EiEBhjaDG}zd16s2LwR|*US?i)adKios$PCk`s{Z$Qb2>)JY5_^ zD(1YsYrjG!ROI-_`#U%L_a^uVe`>$c!S7fo%&g?d;U*wxm?12n<8y+|WuuRB(j}FZ ze}h$|n#1@Z>sGj!t?~S7u8J{qwuUez-{p-(zKPmNRPVH#y+kc<+ z!A-U3MP(}=MV#5Sf}yERd}BvC+m&U{3%=c+y2&+=(c{A2v)`R{Z#Nx0^*6QqkshO# zwN!q4l)1yU%{jhLeCOV~U1EI2?rf>|O{sfVm;0Q0e_NuVnCE~c+XETqf<8uz;|z0> z8O|9pJO>IhU-l2L)s#PBzO4F1gU)dYxA=9Yybet?ZU~>O6RqVQf zhCX&bXfeH4eQSK)1isn>uO|C42Rv{*eO^6|=?=t_oP4H6eTF}Id)oCXm>gdIe;mzr z`#m$qy?OGob(uTc^-dhS?9XV**)SdK9&FC^na?72VDinMC(VE^YPw~^%CbhDRXg4; zw--szoVVgmF7A#`7rm6z(r74We6#u9aiyF8v>84<&N2COu82Q0(fG2q z#^jGqnJu$NJJ*+#!jg(zryO|{7`fJTzqtJQ;yYo1m0zsCT(g&O{Q8&o=yQ%AJ8smx zJpAaw!ae6ab(nW3xfVt^?MU6x{%_)<8J>l*-(z<6&2s*4KbgVh$)}oW@&{H|d&!4h zD%x7df8b%c_iDz1A9pWDG04=JZxv!_zaQ((-*EW-wxw)9$@`a>9(?$ns0mc^cjE^J zi$8Ud89;^qb#xf`_RkjsDUa`E1}a$_2ok=^*KpY1c`Z;~NeGDPy%fm&;=+F5;c`tq phETryTg&zCXYOTHf`Y7P_WO?M`0_W2Z2%S<44$rjF6*2UngDH&`wjpA literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..70c440f173c5af1140ec3ccdfbfaa1122e84d32b GIT binary patch literal 8779 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 B)WHA% literal 0 HcmV?d00001 diff --git a/retroshare-gui/src/gui/icons.qrc b/retroshare-gui/src/gui/icons.qrc index cdf09929b..b513696b2 100644 --- a/retroshare-gui/src/gui/icons.qrc +++ b/retroshare-gui/src/gui/icons.qrc @@ -116,7 +116,7 @@ icons/png/newsfeed-notify.png icons/png/newsfeed.png icons/png/options.png - icons/png/pencil-edit-button.png + icons/png/pencil-edit-button.png icons/png/people-notify.png icons/png/people.png icons/png/person.png @@ -134,7 +134,7 @@ icons/png/thumbs-down.png icons/png/thumbs-neutral.png icons/png/thumbs-up.png - icons/png/typing.png + icons/png/typing.png icons/png/video.png icons/posted_128.png icons/posted_red_128.png @@ -290,5 +290,21 @@ icons/png/bandwidth.png icons/png/options2.png icons/png/exit2.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 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 0000000000000000000000000000000000000000..27d27c21c11132cfd4dc79580bfbe98f5bd7ca1b GIT binary patch literal 2075 zcmZ`)X;>528a_jSum+?>Hp^laQxqDa$YMaiAcPuj1f)Q@mNjl{0HI=^_37MxHb**@MZ&$Y7TKZ04x*u zNdS(~0C*k@fI~3=da-94_c8!bu;%RXb%OvtCgKbKdgFguVz>auF)RrQy5&Uqny1Gg%<%$9kIFX+eiDk%!}u5N<&&feg=wmkcR4ECb_mCy)kCAQdzZ6A9ZwQEq?8%xoqN1Y;ViHIv5#t%+d%_@2N8PzZF)^oph3){9e+Q~odPMzuVA={YDE4o+R zH`zQe33)V7?D{~Z4Hkife&x;t0;SJ9;6gRlBOo3C3f!QyAw`=hMleWDV6olEBN{qd znx^B)P2u)BPCRDRluW#RpD;cc-`gEzcKM+OowL0u<8sNnEn0v3GR9=6 zzqNp_SR9xcKfX-vexS1GbKGT4uh_L%X{CBN_XB=i;cT5V zez5nUG$IvYzPe{ax?8_K@Jp1+{ecVmGi*o)_g&!vx2i`Pr8jNPAfv`L2F|LD$jNe} z6J?2MZ3s2M)-<|`3w|gjUx_dA{_zkGOc`88oK{yd4u(g1a{cPh1Umv+fW0_K_l~lD zbAZIimW7l^fLXm_7pSk|pm)_Js_Xnwm7ecF{c+@yshAw;PHLkVb5zJ}HKCn)El8-< z4krz**^tfyBS`zoh7&)R6)S}^uW5P?14;Fgj^NzWMd=|h{j6i=yfSzf6|`Lw*hZ(@ z8*BGC=}xzh()(Yhy#@=>pO()?hw5Fa&OG|vjJCME&p*poqbe4}cQBsgJMU|{n2aO%j$T924Smi)ir29s<3!cQ-fw@seI)U<_l^DN-0sn;+sDJnk+eyZ?Y~$aNU6F-=5sXIBMPvrIgwaAe zU&~INMc34KZDj=ezTKGIyZtnewU{0CteM2K%Q?1uwr* z2X`XXQ!(XRsXe4#6p>7&JGF-*FJm?=^>6fWPR^NUesc;%=!4vju4mYw3rJDwnd$Ty zn_}9S>_I*_NbLhyyD5p8C)w*K)l|P&H%TIemZiA|H*X4X(l>plaS7?yJcIn}O*+-| ztB9(#Dpc=*+Z{-&x$m2!;OAdFmuSw<1%Xa#vtyN^PAatO`4KgJ($p2OyT3v6sd&E*vBQf3Q!m=MJa_C-3d=TpfxH{$j_qeP&{P$`F>2yZ) ztFXMCg=y|36`_bUGX+7!V3RG2Dctkhlntl$2z3DEdfz bSV(MyRZQH0l2;5v2m&lOFJ`rCaQ1%z#eS%< literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..313bf7d9c832df17e833b0de73daee36232ad7fa GIT binary patch literal 541 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H3?#oinD`S&v7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xB0oAoIF#H0kf5E^|YQVtoDuIE)Y6b&?c)^@qfi^%1`v9L1S0LTq)zjY9*U{C} z(bLn`-QCgM-PSg#y}chO($>}2*4fkE+1=66(Fzm?v3pv(x`4`nxteU6Y~VZm#8R-T8LE-?xA@IRJG>$L-#~-;R}`prSrsZhP!c z{y)7y*Ql1bMwFx^mZVxG7o`Fz1|tJQOI<@FT|6=og@3#dU7WJ7R%T1k0gQ7S`udAVL@UUqSEVnM22eo^}DcQ#T$MGT&< KelF{r5}E)SU$b`r literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..47ecb252b7addd3cf4d62056d9984ae4f63d97e4 GIT binary patch literal 2332 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..446091b91f8857f4bd56c6170392143f434e7515 GIT binary patch literal 738 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 MB^x7*0!5Zm6v3Dl zMMNG^&{(t%kRV8_Pz1$+;=rd+L80lniT?0M@AKU=?)QH0`+nzKEI80-5!ILqLC_*U zUuGzn^NCko35?TYC39d>j$;HcAn2S>W1gb|_RFJuLjxe_fCa#DA?PE4pMaoDIt0Di z4MEP85M-Eg^iqf`1d-kae;4Kj02qcLd_KbCqdb09RTY8=5gZ3w1QQVBmjGD=m&0&? zlmp}`lqUeGBBDf)FMkl6Snzl}@DYYfQCy%XM0hyNQ*a7k7zQwc9OnZA7$$^?H4ds2 ziYQtP@I^u)m(PcB97teTG4KXsa!UdMDz^uO5Dd_Q_-s`Uz)@flGzA`DPmTm6a^|m^ zf_Xgtm)=nn1ppktxdMTLnK&-cFYt*Ggr%jW#BpIbZ~~CPKLDU8 zpJ0;%00yXhwucZ@L@jYv<=o<8;#5HZA>xz-az)@!vA|*A4FkO^r1>(Lj7TZ)U?hAJ zRf?-2B!D7ehTv3G5h<{hI{|lH?igtXruvM~Ko+#ffqh72B{R0<^2on)xx=5D@SfK{ z-<7UwC#&bFuCmq-FBe~E;BQ}CHhaQ&&0p@c@%J_oqh(GV>z4-)+6gD9+1*7oV`0aC z*`#~@=)&Gc*2$?CA6=H*Ptq>d=sKr#Z9wmd$*EVC({%1zwU8`jiupG_riJql+zL9) zChZ?^g^k{vVunXIhsHMa{2JDg|xA-t2 zRK>&>Y$z$d>~sjyx=y^Lax1N+;GC`Cs^?gt zAxmy18*`|tk3&~RH`r8r9f=L~Kf+#{pqpgDj;(vv@9}WY5&f!|wxKH>d99DyrOLG% z?0a2qR`tH9IQX_8dsHe(8GTl$quE8*fV~o4;t8bzTY8MPIGnfUMK++)h*(zR3f*Qa zszx8xI!pAlkK&ug9vdZR8+29HxL=8+Sxd-7xZ5`W_G^otg`?=Miio@~M|ztqt8nKu zYE=YEI`7bxyXcx-)|$L+XW2W$TlVJY2F$~PhM~Ldt%-{nxpU7iE--oxrVmN~;F|c~ za7-+Ca?-8;A9gK^9Yc#m_)U-4<0IzXBL_&UK5#G4@6YAlyx0`{?wY;`;n+S6^X$~# zUPpo#ejHGrA%zzlp2}>dq*WguEVR-=hP9hKqsdKu@Ba*@wBGLJFwBB;m5oW-CHa;b z&wUOTdXGIwb=tflUODj2jIWb`H`@pGmSlMcRv#;5N*YE=T%=Sz5(}}GW>WMD z`m))XyL8ORDlskUKFR`j;kMa>vXl_ZvBZu1c9Q`kibnXWfqTNW63{T+Sn2!26*+l1 z)Bcw@l9{s+-9mBAiAkG{v4-@0+g}^E^!6k_@-U?Nx}Lh6qqeio@pSqJ(=(EkFoVnw zK2Irve#B}DQtkGv(76^NnoL#k<}`cut`aR9r!s3rx6XPo9(FCvZ8EiOjeIaE(F{61 z=x;uDr%hxsOe>N&AoZ*>$iJ!64Li)U4wxP+&a*`gr><7k=?DMR!O$zHC@VA9YG17; zzO@N1(T(psu~Y5$=pdOzM{X1iV~}+AThWbjPKBX8(3Y#CWgtMOsi%3 ztcKH;jW>{`_hfF%Uj}`$TfcSIVWJ+3qroel8O8}$YvUh{Ji!ldp5e74Bbt*D;~bS1 z1189xZs%lUXK!QoZJ6B#XAty_R&=^Eoz4o=9R8{xDLFbJHv9hzR#IByK!FjVz)FtI p$l|2MKv`K?>k{_nYojjIg=)$vv=21)}R8|>ui3PH)bz>fk!3$Xtu2s&*9L7xL4 z$RZDd)QFdwJoZ2kGK1jaZ4Vr1G#;JFrZHJGc!j4}<jD36a>UIWC8(%NbKn>7M%|BXNYV0#Q{_SJFxQe^FdL3J|8B`0G@P#K=2C=q=iwqzzB}O z%;52;09rx@U`b?ng$svEW5b|ymUv}y=yWcX$`@zj0M3%MaHYT#u7yn(rv?5%rLx60 z370P+&&*&lB_SDrx!5SaJ#nYRDtyXfg8>B4DbNcV1KcDV5CbK{QU9R|1dtzG3&;r= z!jr`UHv&V$D%=H_t@r^@Kto}MFkvz|2doV71CX4;M@%+okfhz9SxhDqfYQZpLlQ*; z%voYSaIwE`47|X456m*yUd4O5c|q9d%AT?5fj`fhTHIKAdIX_x>F0gDjomZOI{*A2 zD82c%v-GX({&UT%ww}P?8Mh{;Qgl)4j|~ei_^1|rF;)~UHh3WQ8)II&WGr-4uTg7l zqrKO5)Y$cX-?Nsy49t`H&S@kFGXet~J->%Z@h5K+N z@=06?C+S+m7P;cE+k1`XGHvLu?+h898T5UqT)^|ssyVsG_V`Hc$8A9-ed*?!Rj=Y@ z3_R!8aT5e9|FW0&zMlJag;|BGI*HYF`h^3v{N3kv-YqQn#X*Q5XGc4TF1_9fC~`z6 z-#7?b)e3)zob9XD0V6sd?`n@8TDe9+L4!C@SPntbB)pxCcVh2&!IHnSy=I$Qs--fw zbJf@bTMxn}x-B;atHpJ*#2OjUncnY}Im&k0I$fnt(05F1A8aUnP)TtbM{K=`zKK3V zy0~24a=Rek^7!w^6GmoVIe-7LZsy|mlmY#O9UWtpI#Y-H&d*Wo6!f!qhkxEFT}eLR zR!6QlaQCU;$l}+x(PTpSKNcUKHA-c6kjioMYj+^3H1jP!Ji93WDaTZA78#f77dp~v zac)Cq&3v7zk5Iv=U*+wh-#S~U&%gv{xLk;=&*u9!);>}hJCstBALP||Vv1k3Ibvv} zFD!T7HP@i6soH0&NOUy0+0lMc@M=1DA=SxuzH`8&Y^r)1Gq1h&Ud6%3NMZJymM7Br`%cux7Zk#(0OL6wkpp$xYYuhk6*Pb7*W)PuJsP zR0S^GeGorO7`}*qxgZ~a89Yd-VdQmHf1y-{In^*=oNo)}XS)6rdSUNYZY zIAVSxt^e|yhP%5FTGeHFoJrw=<>OQO1_J4ex;U4}O=j=i%BLJn~Dq0+-RXU*l>c z)uKeWE>896wxq<>V<&9mIKLyp4WrH++c1E(oGo%dAPt2LY9HT)^u$=<2g{CXo+e|7 z3JvS|Y8ABgYMCfyRVD0E72Cl>3VDW3gSEe<9E)irCS4m zY%};QE%X>ib}wm6Besb2zcgG)8T=Nm;?&|$pNQTyq2d1iZCH`(A3|)e401ARC^#iw zPvL8|L+bY~!k)Lq#R40daSdrIHZS5JIdtQsOf<3_J9kg%Nv`alXM0gH*hkBLK_y*( zjfF=eG3M7RE@=}*a&t{q^d?J}4KKY0TX@3K>zB4(c-M*{6qd@XiFOww*WYOKFOOI1 z!MCF)ww*;C5}|5Gs*P2OCJnitHd*)kk4=fUMV}Xrfk zpGU~TTA66c+8mj_Le;N`f>9<&cLs(8+<&0Dr5I^@BgK4)SWHOu=sg;<`K)H0e@p#` z#lo3nIj5=?%BcU=Y{Qgov+O6VpMMiCjO}Wwk*1Qh17y{a%a(}uG52~f`pY*ur{0YC zQ%D-=Ln}vhh=GeTH+!@e6)j)Pm*J2j_4|7c7t6dT?)Jg#q}5e+)s^e)>Wb<{_-P}z zX0F)Ve3w3NA8T}pTv35%*q3YVOV|O5mCn6Z z=d8zBEdQsY<9GU=shj@cmM%2R(&FtJ*im|zDCm8Pcdah15ZQU+HMG>VvEKxHTc;vl zUOST-Ys#C+^xAaQWw^ktRdB~;;lc)dVD^wNRrljbG{Vc}u_Isc*d>ZOstugxop#?C!jGD)i_S8fD<&YR=y zed0p`<3lZiV?)6PnHU-GHZV3ZFy8HLY-RzbiP?4|BMT!V_iP8Z{|Sgb6%u|t>Hi1p z>-;$l0@lI^UZ;-7Cj`cZLJ0{8xbTyaalwJaP~555u!4y_8o&v{+q>CS?+-}(H_Thj Ax&QzG literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..55f0488c8617810140416107e4f598c0fa1f1c00 GIT binary patch literal 1938 zcmZ`(ZB!Fi8omKSAV#2oNTIA)%11#U#8Lq%0u4*De5HITnwB60i&8$LQD{R1GMULt z2*#rlD-TUS@7#Bi8Vsvwxen**h`HIRs+N>v?#Lkx}*gaT6|xEZ5X;^d&X zxI$5nqIDEkt-x`WN=1Ig2n@qaCX@0N1rl+DfJqH32m@+{FcecOD7;yuSulwtrINis zz=;zl{#OL{2$3Y1>I=gNSQAmHbvhj-fPezbr3ivhDwWhJP%WX=YEg4RbDOWaraVy* zwa^M!7KIH`29j?{{Zvgg6hk^j(kYjq6_jQYfJ28VPjEG9H379j7>*!XvY;7{;TQ(% ztDz^PX*fZuQff#5#f29k*OGV`2!c>~^YxLc$WxT0X($T2rp_YUS0n0IR|fCJ%%x^h zKdF{N!tcg3M-&d1bCT5LG+>?5aQ?eP$rIyA6-&E6+~P1Z>$tPL@7m9gjXN?{+w*dz z{P(+FT;#fRURW78bw9}U;ZJYSu4mmI@q4?dgh^=F`lrt?C4AXd`0}vj0bSm~Pi4`c z#Q7)EfB9_~?7 zWyP-_jn%&M?AEeoE6?e_p0TwXy5ZC<9NsYL`(}8gYBV49xx5f_4woTwbS~*sGE0Jz2_m}$3EbiST#{b zfaqqIvMO$O@8|N$R88{XcQ{)HWpW88KD$S#Z3*_=@9Jy1dAP0Mtj`X0Uqb)L{P>}n znMc5G3fQ4*dh%}d59o@AmbHsouCMLz4$ijkIco8JXj?n4Jh~K{%qafVQB4~elK(tA z#7Uxcmh~UFGJedv*`oEh!BN1cr5D(2vhG-O$F9Aasn4|4U$x9krJWoGnWv8{E}ehI z>xu9eU1s)JFZK!DJ^Z3AR~YnfwD+&$IWY~1^ukQm=vJMZIKa9-gCl0ZMw=LSy1}PuFHLYRK-642@tb_tn^3B&hY{SNwa~&>TR;~IAr%juxvQKA3*fPRo7S&(1@=m=c5rBT0Uvl^Zfxxze z6|HBDInQxu$+6Q%RP5%>$5yf0yqNk6-_oYO`_abY*3NI|Essd!SX2ISbC!J}a)fNGPwogSoY|a6*07jI{yV)RP%x&rLe*wdMrM}2)+;)W25eVEDz4knD4#t zv`aR~|A6_Qmd;73Ut*)FCSR1!w27Db@>p1F^LX2agBD(R<#!u#}|;Nb<_DIdJd z|Il+B{8R!M{~r#W8@J|Y_OU19mFv7()3T$lENv)EUixxd6@t~j<*~TD>3QhI1>@gL zPy5`}2dzF^FujmDJxnYdTFQ=e+kB)J{@ub6|BtGXfn}J?Igt;4mEMxLO_IDEi8vy+ zObi#mVTXhVhHwHy!qP)RBi3>vLe~bc*%54ZMnbLg?+Bk1=N07d`D4OcE|Gdjc%3{U rtvFvI%_$QDsZ<(NP_&~wH>X4#R9v?0^Vvu@2m<`LWbUb0QT2ZTJx*yJ literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..185d1cc5dbc178c505711e0f004d2770936a0e4c GIT binary patch literal 2140 zcmZ`(X;@Qd7XHEx0-|6k&;kQOEr<7cC*}su*gnO z)^UK^0#!sn)M61_SfscX9Kd1UWHmt2?@Q=B&-|GCJokS0oV@3K-*Zk9hKHMzf}FY> z06>B4O!9&!72Pu8@VWFp^AkKILhW4b0I1_^+X$3|vG!SKFINCA=|fy906c^r2jC(R zfXM&=Eb;+RjViwDX$63opNET&BLpxQ42;R9<19Lp1z#{6r)FhQsZ@-~qM?i^kJD%z z8Utl$Ot$ceW2~(ZW1tL%VWN-dI8MV^RBDc}JRN}%Nfx|*3 zlPN^9(l}5EW>AtwOBY&VVA1)t8`_}L*>pM! z6FP^AX-sCS&_fDhKqMHO4dny^0c@X6r=!ePn=Be?L_{T0fd)jnC`2RLQin(u9OGZQ ztm^9Ow6qN55HaA85P~5FW*`ibAWKLc7v-V!U$ezo&>kE$GPBhYd`Gi_8OR{?Luat* zaAhpG8aNr@+?Y6A9BLNsLO2|>O$^N(Z5DYzHd0};Laj6*26CbhZ6AkhqV1poGFks! z2Mu0AQ3eBfK!$~85VNQp^^RsJqGB+RZTP)SFW{CKZ2LQyRC(@bQ( zw%@{;zD9$o@7$`D1IAp-vYM^J*#o;x*@mKE>3#y{(E$8!}D?_-}Hxz zBZp=4UT*WRTYhWd^v{iVM6IR2m3HW#BeZDFpDvj2%(POzgtzEw=gtk2u zSG_>8KPmC3`HN($Cj(N)5%aOYsV-O5|U*)&JAVl$qIJ&#d3kc4c|Ka72)z+>#>#}p6qre@3*upnton9 z@_H;Lq~t(z5x287B?GPqU0s4?&KzhS?Zf>IfiY6 zSg;<~`uwh$qNDqLro6rAUY9g#UeYI?RWcJdBOX4U@*X}BylggLq<@mX%v>j!c`})w+FVR$zwlXJ#*_ z6sqL%Ppoe9=yHqnO?$037ckcSj*$T3I-8btQhprGX>aKBiyb)y1}u*9c~a9FQQLJ} zJ$i#82^s?Hr25RdOonw|f9h)arpt!(irl#84*azCgci?EiXURHaEO~E=m`vL^Ze<~ zU=~|O#c-BmVgIp+V^FJV_)5xP+WpYse%+}H-Tygn?x_{~@#Xt;`!a0&USaJSw-s9BI|cQ(1X0n{nBhNa40lfRYF^gf93c}5!+3F>zpPAE z>AZ`#r>-ceE3w<9n4qCOZq3y!-MeEmg?8pE2O^@q@ zb2cj0mHGcJn7T3M<@TaQyMI_d=EkKjc0FINjqeq^t{k4aS&(owre)g3;6u)Cn@dLH zKP=|PDxN$|Hg<^4?sK<2J@01k+FB86UXwjomB?9@b`GyUj@O)fTQVu}HJcitKF=5L zYn~lYtQj>nvkut&?pDdu4?B7f3Y_OGS^eL)ubs87TP*LM<*(>tSC$?<6XbL@WuLm& z#QVymMG$+hc}?TBrh~(t`>%&whI+DP$8w`W4~E-JQskmanzYPkq^|tDYWYX9Kjs83 zGbR_E_@nQgWD^Nj7Up&P-(J75^bgbJk}4u?aK5NRyvNlq>{#B!_5-b=-y~BmlrQF; zV8346pM=5x13ikPFC{3D5^QlcIv5^cKhfCS$auezvAK`2nT3g&g{i3_k!V3A?(Li2 z_CE#ZBZI<168?X|Nsdn=EKoxV-jN}cxWMRO5EmD>FDxQF=4@b8@V?0C(4tu@bqE4v MM>o<<`+(#>0h`wTga7~l literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..29b34498b97a4da6c4587f220b1bfa13ed29104b GIT binary patch literal 988 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 EH{_HxvH$=8 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..e05156e170c1c434e3575e3da8a366474550e57d GIT binary patch literal 2832 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 J)GSN=;4cPahjjn| literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..ccc85ce283b2a1d6b93e7e82226f3e2315167b4b GIT binary patch literal 2145 zcmZ`(dpuNm8~+)`J-H4^5s^#U8H$%&%P`g@mm!ykM5EO<%g80w=w)tahDOLOTWqaM z^-66hmc$la?Bn=?5G3qcqhj+i`b#X@)t z1|#Qhjj%J5htfcaakv>-S&##y1SO-~kpIer8Br3UXG8f26BfcMlrWD0g|Oii$OmN$ z^Y9RBfukT2N@Jlgbc@aAvY2!~KhVYOBh%hSC)O zomjWm|L%;~rYN`?xOe!^#$#$S>^pvh?y2<6WoA2`-28Uw%Lbiy%H;$7iwEN~p0>DhI?wqe$}A3}@1>M%N&=j@$$ zbmTWV7yC_FmJWSBZ)+I~RrI$OCrxqX){d9(A>R>%_RbIFpkH-xsZfdirWT z9wT#IO}!LyBEL4sHIJ6dyL{Cpqa&~nzb%wcx;Ojaf?;UweC_Eqyydl`so~RI4VKF# zj~9o#x)w+0ryGV+x=zbDxrvYIW`hbhDv8n+UMARJpIVOK%biJQzgM2!e#qtQnCz@k z&gnF=BW=fEn~kFp&YnG~tvjaMw5i4NT*UbU4oU*e@Bh)y)yFaviR#7??q9p|F^~L| zvGPH@NMpZr9Y@WO~=|{e>Ij6bv`~#rm5WW zj*)kfong(&fPd`b-a;#TyB*d(A5$h``h-d`&q_3O>B518p7uJ+q){PuwS5R@^qD`e zALsjXz?riTk2p>anH;Jmhcym&K1$Z+eYBsbKFVsI_cS z%5lOvN_ckY$$FYhQ+zx_N>0rQC^f}B&7nE7LPb-ywV+gLE!z{}Q=AGO#%7-RY9+De zK&+V#e#v9^@x2>ASo9wvTKQ-(r7j$=Of<>rZawN~938Re#ncgMg=;5Jx)e{S$Wy1c z8JI4=@!YPPXGOPv)-9(Icd7XOjhmAZ%5w2K-9LL&)^%u8Zu@=`)Zd^l-lXk|O24>g zLAqu(_ZR6OHKeXog~W#B{&ai7b7~;Lv@4)#A?{;iYvXKd^O()9toq#4!hvy48F(Fb zO_lPPdLr7mJ^2-HrV|4OGVfxxSbIx)AfZlCj zITVZqb7Q`PpB=B@0A;DEAxa(D+SgHMovkIMSMlTdzXIiyhXf}h`&{3Wfh#&^P^FGVrZ!yTI| zzqo4O0R;>GWBRz}sL#7Ttx5*#<%hMfdmpX_m@XR((8tcbbU0%qpEh9xaDvv+wgX_0 zr2B*Qcj{o~;Nf)JQp~SQ&)xJcRs-^xWt{P}8TdHLYv1?+^Xt>>J#I5dj;niyky3T!G)aN%5!`f_zSQ`^I*{O@t~_{u)a~ZJ1&QN*iFap+0js(m zhRqjOg|Q{(JHyvM)5pB#`7QExf&|KT_y=J~BL>lqM$)2fqvE6C4Orj_Hs%BibAk<- zU}Z}n*zU0~!{cr7c>i{){r?o4IC(TSCguMZ=odUmhXtF^3H~QzXi1Ur(I6=)X;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 0000000000000000000000000000000000000000..2a3a4631371a93837d690dc26b0701352284925d GIT binary patch literal 1118 zcmV-k1flzhP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L0109M0109NV%yJ*00007bV*G`2ipS- z0tyDHQyTRE00Z7hL_t(I%cYfXXq8nQ$3N$s=U%rty>2lHbr!zJbR|+0p@R5AgVadO zjs9sb${;94fmB#8q|nNmVh-OZM1~-x7??&_41`I!C1VSeso?b9F?Ij$?w{vA=bT?J z?%l1e36?)N{LYJq51;epcg~|48X8PbPtP16#{a20DiXUA%`56xEFa7cCfmE)_pqIl z0Q2M?>Y-x`rKRsvNoKFhksAm7y0dGAeQXYZIKc4mFh=YDB)g|;FH#xOmHL*A)f>2! zJgJl#5E80I0SiRra(Z->S9TtwA|9X>c;R1NDG&i&+Wc7mA?@ouuu;UDPgP*> zIP1uhW>fnCs^be;)wzbtwIiy2c>WGnbD#`XO5vU3^R_%%9PukZ@xqpuh*c*@rTQ5h z=*Jd9_WU|TF0?r3aMls|Jj>dexv;pG>nr-$n%sH~ijfz=S`k^xJ1Z*~%SXhbG&T3t zv9Ym{XP$3jL*qs$WO-}lECN+D_O7(NBa*^|i3!SJ6yh8^PYt1+Wx?E8c<(R>5``cR z@s8c6Q{+O6cMd@i0cRZ|6GyRZEFxIz*!FY{nOw*@{{%XJ8^RGJ93~tYARQ{2SKp68 zu-=udJHX^TJ zRuG_#L9}97{07nV1n26OG7w7?b1g-2M`I97W`sq5o zQk@)~y&NkVL5jw52V2xY8P<4OM`N$EeJwxk)7eQDi3z zPmE&!p7!8Fw;P%zd!FydPg$YrF{J zJyPnCwah4u+dsvo1nWtU{5V*=XZ%`;_vPuC44Mio0I}Fz{POPNn;;0v;8bgC>uY0U kW14%cAPDI0?*19zFHskQ6W0-3AOHXW07*qoM6N<$g0dw9pa1{> literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..23d53d0291c524fccf2261a81f9b56ce6ae6cbc3 GIT binary patch literal 718 zcmeAS@N?(olHy`uVBq!ia0vp^Vj#@H3?x5i&EW)6%*9TgAsieWw;%dH0CG7CJR*yM z%CCbkqm#z$3ZS55iEBhjaDG}zd16s2LwR|*US?i)adKios$PCk`s{Z$QVa}?E&)Cv zuK)l44-E}%U|`tKz>tuTkjcPsn1P|4fng&9LmUIc9tMU&28MkM46$GZ6B!s5GcZ&$ zFzjGp2nq@+Dk{nVi-&}S6c!c&%_%4-fRI3`HU@_E3=FeiCIAhY#K^Fmg*lypp^=Gk zFE?j!a4=9KP;i!3Ap6jlS`U6Y#2M-=ROpSh|!1w6UqsPWd zkIht`MteVf`t(_H$g|9-XL)hYo;`bBnDo3P^?7;r3k9K<3c@cdvR=M?`MSR7?c2BS zYJkU_wV0-{`~pp&!2yaiU-O%M1X;=SrX(I z%)rdTA|NQJqGD-lZ|@!u7S`IjWXY;kt5?!v-}Gj>#Fk^5PRFTw-U|oS`s#Mzhh8 zb!RN%clg?PozpaPhzgSCQ90Oj#!2elNzQ8-%Zg6ic01zM9=WKCYlT%?I}1B&1j9|E zT?z`!LSY-qi@$#O^4+*KVx|Nw!OGyU XRV{t{F=thvml!-<{an^LB{Ts5Ew~Ul literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..38ff8bb2afa441d3691b08660e880b8e84495744 GIT binary patch literal 701 zcmeAS@N?(olHy`uVBq!ia0vp^Vj#@H3?x5i&EW)6%*9TgAsieWw;%dH0CG7CJR*yM z%CCbkqm#z$3ZS55iEBhjaDG}zd16s2LwR|*US?i)adKios$PCk`s{Z$QVa}?rU5=7 zuK)l4XK-L}XmH^7ma}QMk%>_@YA~|uHe<0D74Vg@>@v0NF=Mk8R!mjbDc2DVlQ(NK z2?`1-Dk|c3m9XeB3keAUvO_~d3knK=YzPA=A{nP-P;aP~rzPMkZP9JUL?LEt1Qg&z`&31n7Xm!a|_c#mhL#m#UU8Q!Zbw zUa^*^Y8_|w#_-y8iY;5@+IDeu?2?_l&wc7Xzv%~)W*!Qeb0lW&(Z~hI<5r)`*>JIV z^OdS24`GUNKYwGSRVc=YJe)2C0LJ$v@@<;%Bk-+uo5`RC7{fByWDUMRQ)7|I$Y zL4LsuEG&Y8Dk_$?_V(@pVPUPUOO~u!wR-i&jXQwgF2squ)fzWrA=%kDTHi)TMdN~JD}QLj z^~-k;U)Mk2D0gC785?8fgbjVYy^FW+-)f|Pm_{sjfr};#^0a zTVdlI$GGBFiW*1KR!NqinY5u|9aXB)bCK)x3@kgePwG>I@>GLzu$y7A^ z&b+fT`@Zkz{r5f>MiWp8g^+|$$ZU}0fF?CR=z9)~iqS1K?L znWUto(+JKP7#O%aGc&U+5{Xs{3JM-IH8rhFO-*e$I5>P|V`F3Z;<;Bs!^6YR78e&^ zM^)={b8~;y)zx)}hKBxDTU)y|Iy(9+ARyqbySuv;v0rL%P*4yvKR^HG+S=OA>f!YCbUVWTSAq$pxRHqmD-pVjpSutl85xiN(HRWJ zc`VRPyr8MEv2nJmt4n}3x#i~O9y=0z0CjeDK7;DMSz229TPPIHq4E?ChoeNS(`YoZ zsi~=cOiaudXw52*$7@PSNiikP9SJ5DF+Nto!NJ#vqV)Ck&3JozCu5A>IoJ~t5~7IE zkpBMudw8)VCnqNbMX3L;$C%4=2;m9@g4O2c=HH#1oD#6wN-yO2I6@=4ySs&*uxU z240DYiN}uwYinyO>FVkRVb~WsIyz=8EiDtQtgO@yd}Fa#ik_aH;TW}ku~_^R6EPUo z64YYbX1M9!eOAJot-keAFoi;S+r`D@`uzO-6I5D`>P#adBIJlQv_jU-&h8?Y%jKh| zk1HxFe!*h8ncjL=GQKnpq9q~tc6=l`1jccUN~Kz(Uqd*=zP`ToWo2cR85tSgsPqJ0 z6joAF@-y~=ouZt=b1AKAY*nBz+@(t<~N)$FJ1u8(zrvRfw2Y55Lfj4~{tScG7M7Tpe1K4+% zo7eux_?m>lR}Kseyom97I59D?)!N#+i;ZRvRX@fY&tccPVPaz9B!5|6QYt6~?yp?9 zD!K|4<2WbEpz3}(+_+x})e~H})Rzd3-`m3{{L>PWzrVk6LqkK{*x1-SHk48$Bcsb2 z8XAR|lwutn9S=P{Jzc^s*+NOZz z+%W>`Xu$lACb9dGo=h4Z9`;0~ANcwCsbC|Kk+$)xMv%d_%>dYa=0M9< zKU_RiNyqRjOApO`4Ios77DI&(o9N)zdkVC&DTl%MFyt_oQY(drPH%2+M`-E9p4d5A zr2}T)o&?ILikpYP7`1(<^pj}l5prtjiiK~bsctD}lQ$I#-pKgxzJCC4mTTbe88fl~ O0000 +** +** Copyright (C) 2013 Jiří Procházka (Hobrasoft) +** Contact: http://www.hobrasoft.cz/ +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file is under the terms of the GNU Lesser General Public License +** version 2.1 as published by the Free Software Foundation and appearing +** in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the +** GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +*/ + +#include "MRichTextEdit.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; + +MRichTextEdit::MRichTextEdit(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 MRichTextEdit::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 MRichTextEdit::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 MRichTextEdit::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 MRichTextEdit::textBold() { + QTextCharFormat fmt; + fmt.setFontWeight(f_bold->isChecked() ? QFont::Bold : QFont::Normal); + mergeFormatOnWordOrSelection(fmt); +} + + +void MRichTextEdit::focusInEvent(QFocusEvent *) { + f_textedit->setFocus(Qt::TabFocusReason); +} + + +void MRichTextEdit::textUnderline() { + QTextCharFormat fmt; + fmt.setFontUnderline(f_underline->isChecked()); + mergeFormatOnWordOrSelection(fmt); +} + +void MRichTextEdit::textItalic() { + QTextCharFormat fmt; + fmt.setFontItalic(f_italic->isChecked()); + mergeFormatOnWordOrSelection(fmt); +} + +void MRichTextEdit::textStrikeout() { + QTextCharFormat fmt; + fmt.setFontStrikeOut(f_strikeout->isChecked()); + mergeFormatOnWordOrSelection(fmt); +} + +void MRichTextEdit::textSize(const QString &p) { + qreal pointSize = p.toFloat(); + if (p.toFloat() > 0) { + QTextCharFormat fmt; + fmt.setFontPointSize(pointSize); + mergeFormatOnWordOrSelection(fmt); + } +} + +void MRichTextEdit::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 MRichTextEdit::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 MRichTextEdit::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 MRichTextEdit::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 MRichTextEdit::listBullet(bool checked) { + if (checked) { + f_list_ordered->setChecked(false); + } + list(checked, QTextListFormat::ListDisc); +} + +void MRichTextEdit::listOrdered(bool checked) { + if (checked) { + f_list_bullet->setChecked(false); + } + list(checked, QTextListFormat::ListDecimal); +} + +void MRichTextEdit::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 MRichTextEdit::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 MRichTextEdit::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 MRichTextEdit::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 MRichTextEdit::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 MRichTextEdit::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 MRichTextEdit::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 MRichTextEdit::slotClipboardDataChanged() { +#ifndef QT_NO_CLIPBOARD + if (const QMimeData *md = QApplication::clipboard()->mimeData()) + f_paste->setEnabled(md->hasText()); +#endif +} + +QString MRichTextEdit::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 MRichTextEdit::increaseIndentation() { + indent(+1); +} + +void MRichTextEdit::decreaseIndentation() { + indent(-1); +} + +void MRichTextEdit::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 MRichTextEdit::setText(const QString& text) { + if (text.isEmpty()) { + setPlainText(text); + return; + } + if (text[0] == '<') { + setHtml(text); + } else { + setPlainText(text); + } +} + +void MRichTextEdit::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 MRichTextEdit::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 MRichTextEdit::setPlaceHolderTextPosted() { + f_textedit->setPlaceholderText(tr("Text (optional)")); +} diff --git a/retroshare-gui/src/util/MRichTextEdit.h b/retroshare-gui/src/util/MRichTextEdit.h new file mode 100644 index 000000000..68ca1dd40 --- /dev/null +++ b/retroshare-gui/src/util/MRichTextEdit.h @@ -0,0 +1,101 @@ +/* +** Copyright (C) 2019 by defnax +** +** Copyright (C) 2013 Jiří Procházka (Hobrasoft) +** Contact: http://www.hobrasoft.cz/ +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file is under the terms of the GNU Lesser General Public License +** version 2.1 as published by the Free Software Foundation and appearing +** in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the +** GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +*/ + +#ifndef _MRICHTEXTEDIT_H_ +#define _MRICHTEXTEDIT_H_ + +#include +#include "ui_MRichTextEdit.h" + +/** + * @Brief A simple rich-text editor + */ +class MRichTextEdit : public QWidget, protected Ui::MRichTextEdit { + Q_OBJECT + public: + MRichTextEdit(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/MRichTextEdit.ui b/retroshare-gui/src/util/MRichTextEdit.ui new file mode 100644 index 000000000..27c63689f --- /dev/null +++ b/retroshare-gui/src/util/MRichTextEdit.ui @@ -0,0 +1,598 @@ + + + MRichTextEdit + + + + 0 + 0 + 699 + 312 + + + + + + + + 1 + + + 1 + + + 1 + + + 1 + + + 1 + + + + + + 2 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::ClickFocus + + + Paragraph formatting + + + true + + + + + + + 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 + + + + + + QTextEdit::AutoNone + + + true + + + Text + + + + + + + TextLabel + + + + + + + + MimeTextEdit + QTextEdit +
gui/common/MimeTextEdit.h
+
+
+ + f_textedit + f_strikeout + f_image + f_menu + + + + + + +
From 096de94b00b53626511063500a151e5c2c044f35 Mon Sep 17 00:00:00 2001 From: defnax Date: Thu, 19 Dec 2019 20:02:02 +0100 Subject: [PATCH 2/5] forget to commit this --- retroshare-gui/src/retroshare-gui.pro | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/retroshare-gui/src/retroshare-gui.pro b/retroshare-gui/src/retroshare-gui.pro index d5099aa03..7f79672ff 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/MRichTextEdit.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/MRichTextEdit.ui # gui/ForumsDialog.ui \ @@ -825,6 +827,7 @@ SOURCES += main.cpp \ util/HandleRichText.cpp \ util/ObjectPainter.cpp \ util/RsFile.cpp \ + util/MRichTextEdit.cpp \ gui/profile/ProfileWidget.cpp \ gui/profile/StatusMessage.cpp \ gui/profile/ProfileManager.cpp \ From dc3624945fc22551d9478f59aae26debb2f34ec1 Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 23 Dec 2019 11:52:32 +0100 Subject: [PATCH 3/5] fixed uninitialized memory read and inconsistent initialization of mReputationScore in GxsReputation --- libretroshare/src/services/p3gxsreputation.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) 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(); From 824fc5049bdc7796778320ef91c2ef047ba257ec Mon Sep 17 00:00:00 2001 From: defnax Date: Mon, 23 Dec 2019 21:26:54 +0100 Subject: [PATCH 4/5] update the licence & added the changes for Channel message composer --- .../src/gui/Posted/PostedCreatePostDialog.cpp | 6 +- .../src/gui/Posted/PostedCreatePostDialog.h | 2 +- .../src/gui/Posted/PostedCreatePostDialog.ui | 6 +- .../gui/gxschannels/CreateGxsChannelMsg.cpp | 72 ++-- .../src/gui/gxschannels/CreateGxsChannelMsg.h | 4 +- .../gui/gxschannels/CreateGxsChannelMsg.ui | 357 ++++++++++-------- retroshare-gui/src/gui/icons.qrc | 7 +- retroshare-gui/src/gui/icons/png/add-file.png | Bin 0 -> 2106 bytes .../src/gui/icons/png/add-image.png | Bin 0 -> 2557 bytes .../src/gui/icons/png/attachements.png | Bin 0 -> 2554 bytes retroshare-gui/src/retroshare-gui.pro | 6 +- .../{MRichTextEdit.cpp => RichTextEdit.cpp} | 112 +++--- .../util/{MRichTextEdit.h => RichTextEdit.h} | 55 ++- .../{MRichTextEdit.ui => RichTextEdit.ui} | 18 +- 14 files changed, 349 insertions(+), 296 deletions(-) create mode 100644 retroshare-gui/src/gui/icons/png/add-file.png create mode 100644 retroshare-gui/src/gui/icons/png/add-image.png create mode 100644 retroshare-gui/src/gui/icons/png/attachements.png rename retroshare-gui/src/util/{MRichTextEdit.cpp => RichTextEdit.cpp} (85%) rename retroshare-gui/src/util/{MRichTextEdit.h => RichTextEdit.h} (55%) rename retroshare-gui/src/util/{MRichTextEdit.ui => RichTextEdit.ui} (97%) diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp index 2dea36101..c822bb492 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.cpp @@ -25,7 +25,7 @@ #include "util/misc.h" #include "util/TokenQueue.h" -#include "util/MRichTextEdit.h" +#include "util/RichTextEdit.h" #include "gui/feeds/SubFileItem.h" #include "util/rsdir.h" @@ -51,7 +51,7 @@ PostedCreatePostDialog::PostedCreatePostDialog(TokenQueue* tokenQ, RsPosted *pos setAttribute ( Qt::WA_DeleteOnClose, true ); - ui->MRichTextEditWidget->setPlaceHolderTextPosted(); + ui->RichTextEditWidget->setPlaceHolderTextPosted(); /* fill in the available OwnIds for signing */ ui->idChooser->loadIds(IDCHOOSER_ID_REQUIRED, RsGxsId()); @@ -86,7 +86,7 @@ void PostedCreatePostDialog::createPost() post.mLink = std::string(ui->linkEdit->text().toUtf8()); QString text; - text = ui->MRichTextEditWidget->toHtml(); + text = ui->RichTextEditWidget->toHtml(); post.mNotes = std::string(text.toUtf8()); post.mMeta.mAuthorId = authorId; diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h index 212faa159..de13358fb 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.h @@ -23,7 +23,7 @@ #include #include "retroshare/rsposted.h" -#include "util/MRichTextEdit.h" +#include "util/RichTextEdit.h" class TokenQueue; diff --git a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui index 97ad94741..d64c3ad01 100644 --- a/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui +++ b/retroshare-gui/src/gui/Posted/PostedCreatePostDialog.ui @@ -278,7 +278,7 @@ 0 - + @@ -467,9 +467,9 @@
gui/gxs/GxsIdChooser.h
- MRichTextEdit + RichTextEdit QWidget -
util/MRichTextEdit.h
+
util/RichTextEdit.h
1
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 b513696b2..04a6702b1 100644 --- a/retroshare-gui/src/gui/icons.qrc +++ b/retroshare-gui/src/gui/icons.qrc @@ -116,7 +116,7 @@ icons/png/newsfeed-notify.png icons/png/newsfeed.png icons/png/options.png - icons/png/pencil-edit-button.png + icons/png/pencil-edit-button.png icons/png/people-notify.png icons/png/people.png icons/png/person.png @@ -134,7 +134,7 @@ icons/png/thumbs-down.png icons/png/thumbs-neutral.png icons/png/thumbs-up.png - icons/png/typing.png + icons/png/typing.png icons/png/video.png icons/posted_128.png icons/posted_red_128.png @@ -306,5 +306,8 @@ 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 0000000000000000000000000000000000000000..e9574feaf4e3202499950b3e8e38cbc31b0207e5 GIT binary patch literal 2106 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..1d0941a5dadaf72e575b82a8c5d57b2ecf63d078 GIT binary patch literal 2554 zcmZ`*c|4SB8-8Z9lO#l03N0f`CRuU}jTj+KiYbMn!71xVNHc1(o~#vShJ<{Qt&~Jb zN2!x38Dklp#IzT(R%AKPJ38O@*Z2E9@B2Q_{ap8TU-$LA@BAj&&DB9(MqLH~AWwEA zQQ(t_Tv8Z#pB%`Xh7T;w*2NZp>*=zyzBstnKI}+w0U$;n;#dI8Aoz~}L>dF|*#`j2 zTmV!4p(3ryE>)jcl>u9KnDb zA>blg|Bh}@@)9iuLktW`aJxaC5M;dsoDM9z6B0rym%*EzI01S4)UeIg-;w|%6?`SAhY%c^OM!|N(0Hn0IH7v9`zZWjC2moO~ z=FmVm;UZKBQXGeN!3eU;7JK;b3n0NkoPh&yp$TwTd^)h5MM;Zq0%TY`WdJICU0UI* z)<&ne?gm>gz5em#VT7D)=|_91pRSqX8d@_s-w!JU4i~u_C`+!ijCs_v6oqdZ!k%#& zIWBEhC!u$DyY``}jMn?a%6y#Z=&aE#%%AuABdzDC&$)3g4ICAQ zMWN%-s1&s5c2NBL%N{%Y{}?#%G)etP`i)b?wtHN<|Gq{G@b*d$&h33=I9a8nnb3Eq zZCmJr58;#_Oyny>9opeQ0!g@4j&LCz>PU?MK;a>Bp)TMRG+(^LVA6Mx@6u530<_zw)}7pt^)bkH zFgM9=YdeLhDQMkQ?^|3_9c;H=U>2K)K3esVKDIF+;9BtQs9VSIo26^wB!fkJ)np{y zY)&?OUGXgY!aVI67?_*Z{$rTr-AXiwagEp_r_zZj`ymVPI^(uC-G8Q@C{QOp^9E9X zt%)4&B}!+EE^*4z+04{Fl3?c>Jye8ooSzc_(Ri;5PFuL34_=IyT|p_%eb2?ZY4CBL z1}k4yZc{)#oO`8114{E;Q$S|WfbM)6aGc8r8Pirk`}=Jz;*ibqF@`AC_xH1Lz=;v8 zbyVRn?Ify5RfsP65n=S;TU+mnmNnM{Y<4r<7d+fVd&tjFj&~FOJaeb|e*9^}C-(w1 ziJ!E76IjV4xA5DVEuXB+WP}>Nt;>^8qgXBE8C7lwP894CuKlSqrJ^!$OwDpTw#Kqh z#PFK$uzgoP(E4KP!9fF}H|=NuS89Nj!l)A!JXUw?{(9c8Ki)a>>DuOY$)4QwLun`kB9`cmNu)_ZGEwf6}*`{dcbc3t1-vhT&g+p z)}1E83uz%nZHN`lyj~q6>X@$1R{uQcoGLZ&c6-x2WowobZ=b@bi$R#hQgWnF6HHc= z>MbSv*H7$16@FMfPtsj3Y*BH$n(SHzewd{Yf~1>&0k?Muyi4~dhpzq6IDX!OO)+5PWf_T!gUkSY4nLOir51x7SDY_cd zW|%PEHLS;Dc>;nHWn6`48?m_JtKxQ5R{a1a?^IbZF+5Vsrg)KGe0k zIG@V|W;`|fYemiZK3N4d>5yTy**yhSW)CVFlbz=5145#c`#p5sUn|e#f4lG3Z^2TMEX~x@lO z<4t<`E%Co7J-WRo-OrcqZ+SS}A3ne)V-t&wCYv^HGIlpHw -** -** Copyright (C) 2013 Jiří Procházka (Hobrasoft) -** Contact: http://www.hobrasoft.cz/ -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file is under the terms of the GNU Lesser General Public License -** version 2.1 as published by the Free Software Foundation and appearing -** in the file LICENSE.LGPL included in the packaging of this file. -** Please review the following information to ensure the -** GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -*/ +/******************************************************************************* + * 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 "MRichTextEdit.h" +#include "RichTextEdit.h" #include #include #include @@ -47,7 +42,7 @@ static const uint32_t MAX_ALLOWED_GXS_MESSAGE_SIZE = 199000; -MRichTextEdit::MRichTextEdit(QWidget *parent) : QWidget(parent) { +RichTextEdit::RichTextEdit(QWidget *parent) : QWidget(parent) { setupUi(this); m_lastBlockList = 0; f_textedit->setTabStopWidth(40); @@ -196,14 +191,14 @@ MRichTextEdit::MRichTextEdit(QWidget *parent) : QWidget(parent) { // images connect(f_image, SIGNAL(clicked()), this, SLOT(insertImage())); - + // check message length connect(f_textedit, SIGNAL(textChanged()), this, SLOT(checkLength())); } -void MRichTextEdit::textSource() { +void RichTextEdit::textSource() { QDialog *dialog = new QDialog(this); QPlainTextEdit *pte = new QPlainTextEdit(dialog); pte->setPlainText( f_textedit->toHtml() ); @@ -220,7 +215,7 @@ void MRichTextEdit::textSource() { } -void MRichTextEdit::textRemoveFormat() { +void RichTextEdit::textRemoveFormat() { QTextCharFormat fmt; fmt.setFontWeight(QFont::Normal); fmt.setFontUnderline (false); @@ -246,7 +241,7 @@ void MRichTextEdit::textRemoveFormat() { } -void MRichTextEdit::textRemoveAllFormat() { +void RichTextEdit::textRemoveAllFormat() { f_bold ->setChecked(false); f_underline ->setChecked(false); f_italic ->setChecked(false); @@ -257,37 +252,37 @@ void MRichTextEdit::textRemoveAllFormat() { } -void MRichTextEdit::textBold() { +void RichTextEdit::textBold() { QTextCharFormat fmt; fmt.setFontWeight(f_bold->isChecked() ? QFont::Bold : QFont::Normal); mergeFormatOnWordOrSelection(fmt); } -void MRichTextEdit::focusInEvent(QFocusEvent *) { +void RichTextEdit::focusInEvent(QFocusEvent *) { f_textedit->setFocus(Qt::TabFocusReason); } -void MRichTextEdit::textUnderline() { +void RichTextEdit::textUnderline() { QTextCharFormat fmt; fmt.setFontUnderline(f_underline->isChecked()); mergeFormatOnWordOrSelection(fmt); } -void MRichTextEdit::textItalic() { +void RichTextEdit::textItalic() { QTextCharFormat fmt; fmt.setFontItalic(f_italic->isChecked()); mergeFormatOnWordOrSelection(fmt); } -void MRichTextEdit::textStrikeout() { +void RichTextEdit::textStrikeout() { QTextCharFormat fmt; fmt.setFontStrikeOut(f_strikeout->isChecked()); mergeFormatOnWordOrSelection(fmt); } -void MRichTextEdit::textSize(const QString &p) { +void RichTextEdit::textSize(const QString &p) { qreal pointSize = p.toFloat(); if (p.toFloat() > 0) { QTextCharFormat fmt; @@ -296,7 +291,7 @@ void MRichTextEdit::textSize(const QString &p) { } } -void MRichTextEdit::textLink(bool checked) { +void RichTextEdit::textLink(bool checked) { bool unlink = false; QTextCharFormat fmt; if (checked) { @@ -325,7 +320,7 @@ void MRichTextEdit::textLink(bool checked) { mergeFormatOnWordOrSelection(fmt); } -void MRichTextEdit::textStyle(int index) { +void RichTextEdit::textStyle(int index) { QTextCursor cursor = f_textedit->textCursor(); cursor.beginEditBlock(); @@ -371,7 +366,7 @@ void MRichTextEdit::textStyle(int index) { cursor.endEditBlock(); } -void MRichTextEdit::textFgColor() { +void RichTextEdit::textFgColor() { QColor col = QColorDialog::getColor(f_textedit->textColor(), this); QTextCursor cursor = f_textedit->textCursor(); if (!cursor.hasSelection()) { @@ -388,7 +383,7 @@ void MRichTextEdit::textFgColor() { fgColorChanged(col); } -void MRichTextEdit::textBgColor() { +void RichTextEdit::textBgColor() { QColor col = QColorDialog::getColor(f_textedit->textBackgroundColor(), this); QTextCursor cursor = f_textedit->textCursor(); if (!cursor.hasSelection()) { @@ -405,21 +400,21 @@ void MRichTextEdit::textBgColor() { bgColorChanged(col); } -void MRichTextEdit::listBullet(bool checked) { +void RichTextEdit::listBullet(bool checked) { if (checked) { f_list_ordered->setChecked(false); } list(checked, QTextListFormat::ListDisc); } -void MRichTextEdit::listOrdered(bool checked) { +void RichTextEdit::listOrdered(bool checked) { if (checked) { f_list_bullet->setChecked(false); } list(checked, QTextListFormat::ListDecimal); } -void MRichTextEdit::list(bool checked, QTextListFormat::Style style) { +void RichTextEdit::list(bool checked, QTextListFormat::Style style) { QTextCursor cursor = f_textedit->textCursor(); cursor.beginEditBlock(); if (!checked) { @@ -438,7 +433,7 @@ void MRichTextEdit::list(bool checked, QTextListFormat::Style style) { cursor.endEditBlock(); } -void MRichTextEdit::mergeFormatOnWordOrSelection(const QTextCharFormat &format) { +void RichTextEdit::mergeFormatOnWordOrSelection(const QTextCharFormat &format) { QTextCursor cursor = f_textedit->textCursor(); if (!cursor.hasSelection()) { cursor.select(QTextCursor::WordUnderCursor); @@ -448,7 +443,7 @@ void MRichTextEdit::mergeFormatOnWordOrSelection(const QTextCharFormat &format) f_textedit->setFocus(Qt::TabFocusReason); } -void MRichTextEdit::slotCursorPositionChanged() { +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()))) { @@ -473,7 +468,7 @@ void MRichTextEdit::slotCursorPositionChanged() { } } -void MRichTextEdit::fontChanged(const QFont &f) { +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()); @@ -512,7 +507,7 @@ void MRichTextEdit::fontChanged(const QFont &f) { } } -void MRichTextEdit::fgColorChanged(const QColor &c) { +void RichTextEdit::fgColorChanged(const QColor &c) { QPixmap pix(16, 16); if (c.isValid()) { pix.fill(c); @@ -522,7 +517,7 @@ void MRichTextEdit::fgColorChanged(const QColor &c) { f_fgcolor->setIcon(pix); } -void MRichTextEdit::bgColorChanged(const QColor &c) { +void RichTextEdit::bgColorChanged(const QColor &c) { QPixmap pix(16, 16); if (c.isValid()) { pix.fill(c); @@ -532,21 +527,21 @@ void MRichTextEdit::bgColorChanged(const QColor &c) { f_bgcolor->setIcon(pix); } -void MRichTextEdit::slotCurrentCharFormatChanged(const QTextCharFormat &format) { +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 MRichTextEdit::slotClipboardDataChanged() { +void RichTextEdit::slotClipboardDataChanged() { #ifndef QT_NO_CLIPBOARD if (const QMimeData *md = QApplication::clipboard()->mimeData()) f_paste->setEnabled(md->hasText()); #endif } -QString MRichTextEdit::toHtml() const { +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"); @@ -556,15 +551,15 @@ QString MRichTextEdit::toHtml() const { return s; } -void MRichTextEdit::increaseIndentation() { +void RichTextEdit::increaseIndentation() { indent(+1); } -void MRichTextEdit::decreaseIndentation() { +void RichTextEdit::decreaseIndentation() { indent(-1); } -void MRichTextEdit::indent(int delta) { +void RichTextEdit::indent(int delta) { QTextCursor cursor = f_textedit->textCursor(); cursor.beginEditBlock(); QTextBlockFormat bfmt = cursor.blockFormat(); @@ -576,7 +571,7 @@ void MRichTextEdit::indent(int delta) { cursor.endEditBlock(); } -void MRichTextEdit::setText(const QString& text) { +void RichTextEdit::setText(const QString& text) { if (text.isEmpty()) { setPlainText(text); return; @@ -588,7 +583,7 @@ void MRichTextEdit::setText(const QString& text) { } } -void MRichTextEdit::insertImage() { +void RichTextEdit::insertImage() { QString file; if (misc::getOpenFileName(window(), RshareSettings::LASTDIR_IMAGES, tr("Load Picture File"), "Pictures (*.png *.xpm *.jpg *.jpeg)", file)) { QString encodedImage; @@ -599,7 +594,7 @@ void MRichTextEdit::insertImage() { } } -void MRichTextEdit::checkLength(){ +void RichTextEdit::checkLength(){ QString text; RsHtml::optimizeHtml(f_textedit, text); std::wstring msg = text.toStdWString(); @@ -615,6 +610,7 @@ void MRichTextEdit::checkLength(){ f_info->setText(text); } -void MRichTextEdit::setPlaceHolderTextPosted() { + +void RichTextEdit::setPlaceHolderTextPosted() { f_textedit->setPlaceholderText(tr("Text (optional)")); } diff --git a/retroshare-gui/src/util/MRichTextEdit.h b/retroshare-gui/src/util/RichTextEdit.h similarity index 55% rename from retroshare-gui/src/util/MRichTextEdit.h rename to retroshare-gui/src/util/RichTextEdit.h index 68ca1dd40..8a4c95eba 100644 --- a/retroshare-gui/src/util/MRichTextEdit.h +++ b/retroshare-gui/src/util/RichTextEdit.h @@ -1,41 +1,36 @@ -/* -** Copyright (C) 2019 by defnax -** -** Copyright (C) 2013 Jiří Procházka (Hobrasoft) -** Contact: http://www.hobrasoft.cz/ -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file is under the terms of the GNU Lesser General Public License -** version 2.1 as published by the Free Software Foundation and appearing -** in the file LICENSE.LGPL included in the packaging of this file. -** Please review the following information to ensure the -** GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -*/ +/******************************************************************************* + * 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 _MRICHTEXTEDIT_H_ -#define _MRICHTEXTEDIT_H_ +#ifndef _RICHTEXTEDIT_H_ +#define _RICHTEXTEDIT_H_ #include -#include "ui_MRichTextEdit.h" +#include "ui_RichTextEdit.h" /** * @Brief A simple rich-text editor */ -class MRichTextEdit : public QWidget, protected Ui::MRichTextEdit { +class RichTextEdit : public QWidget, protected Ui::RichTextEdit { Q_OBJECT public: - MRichTextEdit(QWidget *parent = 0); + RichTextEdit(QWidget *parent = 0); QString toPlainText() const { return f_textedit->toPlainText(); } QString toHtml() const; @@ -47,7 +42,7 @@ class MRichTextEdit : public QWidget, protected Ui::MRichTextEdit { 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); } diff --git a/retroshare-gui/src/util/MRichTextEdit.ui b/retroshare-gui/src/util/RichTextEdit.ui similarity index 97% rename from retroshare-gui/src/util/MRichTextEdit.ui rename to retroshare-gui/src/util/RichTextEdit.ui index 27c63689f..7b5ffc6ae 100644 --- a/retroshare-gui/src/util/MRichTextEdit.ui +++ b/retroshare-gui/src/util/RichTextEdit.ui @@ -1,12 +1,12 @@ - MRichTextEdit - + RichTextEdit + 0 0 - 699 + 703 312 @@ -62,6 +62,12 @@
+ + + MS Sans Serif + 10 + + Qt::ClickFocus @@ -557,6 +563,12 @@ + + + MS Sans Serif + 9 + + QTextEdit::AutoNone From f45a04b3d5b83a90cf3d2fb5e0eacef6bef6c062 Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 24 Dec 2019 11:48:50 +0100 Subject: [PATCH 5/5] fixed key list not properly updating when importing new key in GenCertDialog, and improved tooltips --- retroshare-gui/src/gui/GenCertDialog.cpp | 15 ++++++++++++--- retroshare-gui/src/gui/connect/ConfCertDialog.cpp | 10 +++++++--- retroshare-gui/src/gui/settings/CryptoPage.ui | 12 +++++++++--- 3 files changed, 28 insertions(+), 9 deletions(-) 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/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/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