mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-28 00:49:28 -05:00
Merge pull request #189 from hunbernd/feature/chat-enhancements
Chat enhancements
This commit is contained in:
commit
8e9fe6d800
@ -267,10 +267,12 @@ static QString getStyle(const QDir &styleDir, const QString &styleVariant, enumG
|
|||||||
|
|
||||||
QString ChatStyle::formatMessage(enumFormatMessage type, const QString &name, const QDateTime ×tamp, const QString &message, unsigned int flag)
|
QString ChatStyle::formatMessage(enumFormatMessage type, const QString &name, const QDateTime ×tamp, const QString &message, unsigned int flag)
|
||||||
{
|
{
|
||||||
|
bool me = false;
|
||||||
QDomDocument doc ;
|
QDomDocument doc ;
|
||||||
QString styleOptimized ;
|
QString styleOptimized ;
|
||||||
QString errorMsg ; int errorLine ; int errorColumn ;
|
QString errorMsg ; int errorLine ; int errorColumn ;
|
||||||
QString messageBody = message ;
|
QString messageBody = message ;
|
||||||
|
me = me || message.trimmed().startsWith("/me ");
|
||||||
if (doc.setContent(messageBody, &errorMsg, &errorLine, &errorColumn)) {
|
if (doc.setContent(messageBody, &errorMsg, &errorLine, &errorColumn)) {
|
||||||
QDomElement body = doc.documentElement();
|
QDomElement body = doc.documentElement();
|
||||||
if (!body.isNull()){
|
if (!body.isNull()){
|
||||||
@ -279,6 +281,12 @@ QString ChatStyle::formatMessage(enumFormatMessage type, const QString &name, co
|
|||||||
for (int curs = 0; curs < count; ++curs){
|
for (int curs = 0; curs < count; ++curs){
|
||||||
QDomNode it = body.childNodes().item(curs);
|
QDomNode it = body.childNodes().item(curs);
|
||||||
if (it.nodeName().toLower() != "style") {
|
if (it.nodeName().toLower() != "style") {
|
||||||
|
//find out if the message starts with /me
|
||||||
|
if(it.isText()){
|
||||||
|
me = me || it.toText().data().trimmed().startsWith("/me ");
|
||||||
|
}else if(it.isElement()){
|
||||||
|
me = me || it.toElement().text().trimmed().startsWith("/me ");
|
||||||
|
}
|
||||||
QString str;
|
QString str;
|
||||||
QTextStream stream(&str);
|
QTextStream stream(&str);
|
||||||
it.toElement().save(stream, -1);
|
it.toElement().save(stream, -1);
|
||||||
@ -354,7 +362,22 @@ QString ChatStyle::formatMessage(enumFormatMessage type, const QString &name, co
|
|||||||
QString strName = RsHtml::plainText(name).prepend(QString("<a name=\"name\">")).append(QString("</a>"));
|
QString strName = RsHtml::plainText(name).prepend(QString("<a name=\"name\">")).append(QString("</a>"));
|
||||||
QString strDate = DateTime::formatDate(timestamp.date()).prepend(QString("<a name=\"date\">")).append(QString("</a>"));
|
QString strDate = DateTime::formatDate(timestamp.date()).prepend(QString("<a name=\"date\">")).append(QString("</a>"));
|
||||||
QString strTime = DateTime::formatTime(timestamp.time()).prepend(QString("<a name=\"time\">")).append(QString("</a>"));
|
QString strTime = DateTime::formatTime(timestamp.time()).prepend(QString("<a name=\"time\">")).append(QString("</a>"));
|
||||||
|
|
||||||
|
int bi = name.lastIndexOf(QRegExp(" \\(.*\\)")); //trim location from the end
|
||||||
|
QString strShortName = RsHtml::plainText(name.left(bi)).prepend(QString("<a name=\"name\">")).append(QString("</a>"));
|
||||||
|
|
||||||
|
//handle /me
|
||||||
|
//%nome% and %me% for including formatting conditionally
|
||||||
|
//meName class for modifying the style of the name in the palce of /me
|
||||||
|
if(me){
|
||||||
|
messageBody = messageBody.replace(messageBody.indexOf("/me "), 3, strShortName.prepend(QString("<span class=\"meName\">")).append(QString("</span>"))); //replace only the first /me
|
||||||
|
style = style.remove(QRegExp("%nome%.*%/nome%")).remove("%me%").remove("%/me%");
|
||||||
|
} else {
|
||||||
|
style = style.remove(QRegExp("%me%.*%/me%")).remove("%nome%").remove("%/nome%");
|
||||||
|
}
|
||||||
|
|
||||||
QString formatMsg = style.replace("%name%", strName)
|
QString formatMsg = style.replace("%name%", strName)
|
||||||
|
.replace("%shortname%", strShortName)
|
||||||
.replace("%date%", strDate)
|
.replace("%date%", strDate)
|
||||||
.replace("%time%", strTime)
|
.replace("%time%", strTime)
|
||||||
#ifdef COLORED_NICKNAMES
|
#ifdef COLORED_NICKNAMES
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
#include "util/HandleRichText.h"
|
#include "util/HandleRichText.h"
|
||||||
#include "gui/chat/ChatUserNotify.h"//For BradCast
|
#include "gui/chat/ChatUserNotify.h"//For BradCast
|
||||||
#include "util/DateTime.h"
|
#include "util/DateTime.h"
|
||||||
|
#include "util/imageutil.h"
|
||||||
|
|
||||||
#include <retroshare/rsstatus.h>
|
#include <retroshare/rsstatus.h>
|
||||||
#include <retroshare/rsidentity.h>
|
#include <retroshare/rsidentity.h>
|
||||||
@ -125,6 +126,8 @@ ChatWidget::ChatWidget(QWidget *parent) :
|
|||||||
connect(ui->actionChooseFont, SIGNAL(triggered()), this, SLOT(chooseFont()));
|
connect(ui->actionChooseFont, SIGNAL(triggered()), this, SLOT(chooseFont()));
|
||||||
connect(ui->actionChooseColor, SIGNAL(triggered()), this, SLOT(chooseColor()));
|
connect(ui->actionChooseColor, SIGNAL(triggered()), this, SLOT(chooseColor()));
|
||||||
connect(ui->actionResetFont, SIGNAL(triggered()), this, SLOT(resetFont()));
|
connect(ui->actionResetFont, SIGNAL(triggered()), this, SLOT(resetFont()));
|
||||||
|
connect(ui->actionQuote, SIGNAL(triggered()), this, SLOT(quote()));
|
||||||
|
connect(ui->actionSave_image, SIGNAL(triggered()), this, SLOT(saveImage()));
|
||||||
|
|
||||||
connect(ui->hashBox, SIGNAL(fileHashingFinished(QList<HashedFile>)), this, SLOT(fileHashingFinished(QList<HashedFile>)));
|
connect(ui->hashBox, SIGNAL(fileHashingFinished(QList<HashedFile>)), this, SLOT(fileHashingFinished(QList<HashedFile>)));
|
||||||
|
|
||||||
@ -975,6 +978,14 @@ void ChatWidget::contextMenuTextBrowser(QPoint point)
|
|||||||
|
|
||||||
contextMnu->addSeparator();
|
contextMnu->addSeparator();
|
||||||
contextMnu->addAction(ui->actionClearChatHistory);
|
contextMnu->addAction(ui->actionClearChatHistory);
|
||||||
|
contextMnu->addAction(ui->actionQuote);
|
||||||
|
|
||||||
|
QTextCursor cursor = ui->textBrowser->cursorForPosition(point);
|
||||||
|
if(ImageUtil::checkImage(cursor))
|
||||||
|
{
|
||||||
|
ui->actionSave_image->setData(point);
|
||||||
|
contextMnu->addAction(ui->actionSave_image);
|
||||||
|
}
|
||||||
|
|
||||||
contextMnu->exec(ui->textBrowser->viewport()->mapToGlobal(point));
|
contextMnu->exec(ui->textBrowser->viewport()->mapToGlobal(point));
|
||||||
delete(contextMnu);
|
delete(contextMnu);
|
||||||
@ -1668,3 +1679,21 @@ bool ChatWidget::setStyle()
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChatWidget::quote()
|
||||||
|
{
|
||||||
|
QString text = ui->textBrowser->textCursor().selection().toPlainText();
|
||||||
|
if(text.length() > 0)
|
||||||
|
{
|
||||||
|
QStringList sl = text.split(QRegExp("[\r\n]"),QString::SkipEmptyParts);
|
||||||
|
text = sl.join("\n>");
|
||||||
|
emit ui->chatTextEdit->append(QString(">") + text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatWidget::saveImage()
|
||||||
|
{
|
||||||
|
QPoint point = ui->actionSave_image->data().toPoint();
|
||||||
|
QTextCursor cursor = ui->textBrowser->cursorForPosition(point);
|
||||||
|
ImageUtil::extractImage(window(), cursor);
|
||||||
|
}
|
||||||
|
@ -185,6 +185,9 @@ private slots:
|
|||||||
bool fileSave();
|
bool fileSave();
|
||||||
bool fileSaveAs();
|
bool fileSaveAs();
|
||||||
|
|
||||||
|
void quote();
|
||||||
|
void saveImage();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool findText(const QString& qsStringToFind);
|
bool findText(const QString& qsStringToFind);
|
||||||
bool findText(const QString& qsStringToFind, bool bBackWard, bool bForceMove);
|
bool findText(const QString& qsStringToFind, bool bBackWard, bool bForceMove);
|
||||||
|
@ -972,6 +972,23 @@ border-image: url(:/images/closepressed.png)
|
|||||||
<string>Search Box</string>
|
<string>Search Box</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionQuote">
|
||||||
|
<property name="text">
|
||||||
|
<string>Quote</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Quotes the selected text</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionSave_image">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../images.qrc">
|
||||||
|
<normaloff>:/images/document_save.png</normaloff>:/images/document_save.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Save image</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
|
@ -41,6 +41,7 @@ MimeTextEdit::MimeTextEdit(QWidget *parent)
|
|||||||
mCompleterKeyModifiers = Qt::ControlModifier;
|
mCompleterKeyModifiers = Qt::ControlModifier;
|
||||||
mCompleterKey = Qt::Key_Space;
|
mCompleterKey = Qt::Key_Space;
|
||||||
mForceCompleterShowNextKeyEvent = false;
|
mForceCompleterShowNextKeyEvent = false;
|
||||||
|
highliter = new RsSyntaxHighlighter(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MimeTextEdit::canInsertFromMimeData(const QMimeData* source) const
|
bool MimeTextEdit::canInsertFromMimeData(const QMimeData* source) const
|
||||||
@ -231,6 +232,8 @@ void MimeTextEdit::contextMenuEvent(QContextMenuEvent *e)
|
|||||||
|
|
||||||
/* Add actions for pasting links */
|
/* Add actions for pasting links */
|
||||||
contextMenu->addAction( tr("Paste as plain text"), this, SLOT(pastePlainText()));
|
contextMenu->addAction( tr("Paste as plain text"), this, SLOT(pastePlainText()));
|
||||||
|
QAction *spoilerAction = contextMenu->addAction(tr("Spoiler"), this, SLOT(spoiler()));
|
||||||
|
spoilerAction->setToolTip(tr("Select text to hide, then push this button"));
|
||||||
contextMenu->addSeparator();
|
contextMenu->addSeparator();
|
||||||
QAction *pasteLinkAction = contextMenu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste RetroShare Link"), this, SLOT(pasteLink()));
|
QAction *pasteLinkAction = contextMenu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste RetroShare Link"), this, SLOT(pasteLink()));
|
||||||
contextMenu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste my certificate link"), this, SLOT(pasteOwnCertificateLink()));
|
contextMenu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste my certificate link"), this, SLOT(pasteOwnCertificateLink()));
|
||||||
@ -268,3 +271,8 @@ void MimeTextEdit::pastePlainText()
|
|||||||
{
|
{
|
||||||
insertPlainText(QApplication::clipboard()->text());
|
insertPlainText(QApplication::clipboard()->text());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MimeTextEdit::spoiler()
|
||||||
|
{
|
||||||
|
RsHtml::insertSpoilerText(this->textCursor());
|
||||||
|
}
|
||||||
|
@ -24,11 +24,14 @@
|
|||||||
|
|
||||||
#include <QCompleter>
|
#include <QCompleter>
|
||||||
#include "RSTextEdit.h"
|
#include "RSTextEdit.h"
|
||||||
|
#include "util/RsSyntaxHighlighter.h"
|
||||||
|
|
||||||
class MimeTextEdit : public RSTextEdit
|
class MimeTextEdit : public RSTextEdit
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(QColor textColorQuote READ textColorQuote WRITE setTextColorQuote)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MimeTextEdit(QWidget *parent = 0);
|
MimeTextEdit(QWidget *parent = 0);
|
||||||
|
|
||||||
@ -44,6 +47,11 @@ public:
|
|||||||
// Add QAction to context menu (action won't be deleted)
|
// Add QAction to context menu (action won't be deleted)
|
||||||
void addContextMenuAction(QAction *action);
|
void addContextMenuAction(QAction *action);
|
||||||
|
|
||||||
|
QColor textColorQuote() const { return highliter->textColorQuote();}
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setTextColorQuote(QColor textColorQuote) { highliter->setTextColorQuote(textColorQuote);}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void calculateContextMenuActions();
|
void calculateContextMenuActions();
|
||||||
|
|
||||||
@ -59,6 +67,8 @@ private slots:
|
|||||||
void pasteLink();
|
void pasteLink();
|
||||||
void pasteOwnCertificateLink();
|
void pasteOwnCertificateLink();
|
||||||
void pastePlainText();
|
void pastePlainText();
|
||||||
|
void spoiler();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString textUnderCursor() const;
|
QString textUnderCursor() const;
|
||||||
|
|
||||||
@ -69,6 +79,7 @@ private:
|
|||||||
bool mForceCompleterShowNextKeyEvent;
|
bool mForceCompleterShowNextKeyEvent;
|
||||||
QString mCompleterStartString;
|
QString mCompleterStartString;
|
||||||
QList<QAction*> mContextMenuActions;
|
QList<QAction*> mContextMenuActions;
|
||||||
|
RsSyntaxHighlighter *highliter;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MIMETEXTEDIT_H
|
#endif // MIMETEXTEDIT_H
|
||||||
|
@ -14,6 +14,8 @@ RSTextBrowser::RSTextBrowser(QWidget *parent) :
|
|||||||
mImageBlockWidget = NULL;
|
mImageBlockWidget = NULL;
|
||||||
mLinkClickActive = true;
|
mLinkClickActive = true;
|
||||||
|
|
||||||
|
highliter = new RsSyntaxHighlighter(this);
|
||||||
|
|
||||||
connect(this, SIGNAL(anchorClicked(QUrl)), this, SLOT(linkClicked(QUrl)));
|
connect(this, SIGNAL(anchorClicked(QUrl)), this, SLOT(linkClicked(QUrl)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define RSTEXTBROWSER_H
|
#define RSTEXTBROWSER_H
|
||||||
|
|
||||||
#include <QTextBrowser>
|
#include <QTextBrowser>
|
||||||
|
#include "util/RsSyntaxHighlighter.h"
|
||||||
|
|
||||||
class RSImageBlockWidget;
|
class RSImageBlockWidget;
|
||||||
|
|
||||||
@ -9,6 +10,8 @@ class RSTextBrowser : public QTextBrowser
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(QColor textColorQuote READ textColorQuote WRITE setTextColorQuote)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit RSTextBrowser(QWidget *parent = 0);
|
explicit RSTextBrowser(QWidget *parent = 0);
|
||||||
|
|
||||||
@ -20,8 +23,11 @@ public:
|
|||||||
|
|
||||||
virtual QVariant loadResource(int type, const QUrl &name);
|
virtual QVariant loadResource(int type, const QUrl &name);
|
||||||
|
|
||||||
|
QColor textColorQuote() const { return highliter->textColorQuote();}
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void showImages();
|
void showImages();
|
||||||
|
void setTextColorQuote(QColor textColorQuote) { highliter->setTextColorQuote(textColorQuote);}
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void linkClicked(const QUrl &url);
|
void linkClicked(const QUrl &url);
|
||||||
@ -35,6 +41,7 @@ private:
|
|||||||
bool mShowImages;
|
bool mShowImages;
|
||||||
RSImageBlockWidget *mImageBlockWidget;
|
RSImageBlockWidget *mImageBlockWidget;
|
||||||
bool mLinkClickActive;
|
bool mLinkClickActive;
|
||||||
|
RsSyntaxHighlighter *highliter;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RSTEXTBROWSER_H
|
#endif // RSTEXTBROWSER_H
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
|
#include <QScrollBar>
|
||||||
|
|
||||||
#include "GxsForumThreadWidget.h"
|
#include "GxsForumThreadWidget.h"
|
||||||
#include "ui_GxsForumThreadWidget.h"
|
#include "ui_GxsForumThreadWidget.h"
|
||||||
@ -39,6 +40,7 @@
|
|||||||
#include "util/DateTime.h"
|
#include "util/DateTime.h"
|
||||||
#include "gui/common/UIStateHelper.h"
|
#include "gui/common/UIStateHelper.h"
|
||||||
#include "util/QtVersion.h"
|
#include "util/QtVersion.h"
|
||||||
|
#include "util/imageutil.h"
|
||||||
|
|
||||||
#include <retroshare/rsgxsforums.h>
|
#include <retroshare/rsgxsforums.h>
|
||||||
#include <retroshare/rsgrouter.h>
|
#include <retroshare/rsgrouter.h>
|
||||||
@ -135,6 +137,7 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget
|
|||||||
mThreadCompareRole->setRole(COLUMN_THREAD_DATE, ROLE_THREAD_SORT);
|
mThreadCompareRole->setRole(COLUMN_THREAD_DATE, ROLE_THREAD_SORT);
|
||||||
|
|
||||||
connect(ui->threadTreeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(threadListCustomPopupMenu(QPoint)));
|
connect(ui->threadTreeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(threadListCustomPopupMenu(QPoint)));
|
||||||
|
connect(ui->postText, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuTextBrowser(QPoint)));
|
||||||
|
|
||||||
ui->subscribeToolButton->hide() ;
|
ui->subscribeToolButton->hide() ;
|
||||||
connect(ui->subscribeToolButton, SIGNAL(subscribe(bool)), this, SLOT(subscribeGroup(bool)));
|
connect(ui->subscribeToolButton, SIGNAL(subscribe(bool)), this, SLOT(subscribeGroup(bool)));
|
||||||
@ -154,6 +157,8 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget
|
|||||||
connect(ui->filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterItems(QString)));
|
connect(ui->filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterItems(QString)));
|
||||||
connect(ui->filterLineEdit, SIGNAL(filterChanged(int)), this, SLOT(filterColumnChanged(int)));
|
connect(ui->filterLineEdit, SIGNAL(filterChanged(int)), this, SLOT(filterColumnChanged(int)));
|
||||||
|
|
||||||
|
connect(ui->actionSave_image, SIGNAL(triggered()), this, SLOT(saveImage()));
|
||||||
|
|
||||||
/* Set own item delegate */
|
/* Set own item delegate */
|
||||||
RSItemDelegate *itemDelegate = new RSItemDelegate(this);
|
RSItemDelegate *itemDelegate = new RSItemDelegate(this);
|
||||||
itemDelegate->setSpacing(QSize(0, 2));
|
itemDelegate->setSpacing(QSize(0, 2));
|
||||||
@ -497,7 +502,27 @@ void GxsForumThreadWidget::threadListCustomPopupMenu(QPoint /*point*/)
|
|||||||
contextMnu.addSeparator();
|
contextMnu.addSeparator();
|
||||||
contextMnu.addAction(replyauthorAct);
|
contextMnu.addAction(replyauthorAct);
|
||||||
|
|
||||||
contextMnu.exec(QCursor::pos());
|
contextMnu.exec(QCursor::pos());
|
||||||
|
}
|
||||||
|
|
||||||
|
void GxsForumThreadWidget::contextMenuTextBrowser(QPoint point)
|
||||||
|
{
|
||||||
|
QMatrix matrix;
|
||||||
|
matrix.translate(ui->postText->horizontalScrollBar()->value(), ui->postText->verticalScrollBar()->value());
|
||||||
|
|
||||||
|
QMenu *contextMnu = ui->postText->createStandardContextMenu(matrix.map(point));
|
||||||
|
|
||||||
|
contextMnu->addSeparator();
|
||||||
|
|
||||||
|
QTextCursor cursor = ui->postText->cursorForPosition(point);
|
||||||
|
if(ImageUtil::checkImage(cursor))
|
||||||
|
{
|
||||||
|
ui->actionSave_image->setData(point);
|
||||||
|
contextMnu->addAction(ui->actionSave_image);
|
||||||
|
}
|
||||||
|
|
||||||
|
contextMnu->exec(ui->postText->viewport()->mapToGlobal(point));
|
||||||
|
delete(contextMnu);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GxsForumThreadWidget::eventFilter(QObject *obj, QEvent *event)
|
bool GxsForumThreadWidget::eventFilter(QObject *obj, QEvent *event)
|
||||||
@ -1856,6 +1881,13 @@ void GxsForumThreadWidget::replyForumMessageData(const RsGxsForumMsg &msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GxsForumThreadWidget::saveImage()
|
||||||
|
{
|
||||||
|
QPoint point = ui->actionSave_image->data().toPoint();
|
||||||
|
QTextCursor cursor = ui->postText->cursorForPosition(point);
|
||||||
|
ImageUtil::extractImage(window(), cursor);
|
||||||
|
}
|
||||||
|
|
||||||
void GxsForumThreadWidget::changedViewBox()
|
void GxsForumThreadWidget::changedViewBox()
|
||||||
{
|
{
|
||||||
if (mInProcessSettings) {
|
if (mInProcessSettings) {
|
||||||
|
@ -70,6 +70,7 @@ protected:
|
|||||||
private slots:
|
private slots:
|
||||||
/** Create the context popup menu and it's submenus */
|
/** Create the context popup menu and it's submenus */
|
||||||
void threadListCustomPopupMenu(QPoint point);
|
void threadListCustomPopupMenu(QPoint point);
|
||||||
|
void contextMenuTextBrowser(QPoint point);
|
||||||
|
|
||||||
void changedThread();
|
void changedThread();
|
||||||
void clickedThread (QTreeWidgetItem *item, int column);
|
void clickedThread (QTreeWidgetItem *item, int column);
|
||||||
@ -80,7 +81,7 @@ private slots:
|
|||||||
void replyMessageData(const RsGxsForumMsg &msg);
|
void replyMessageData(const RsGxsForumMsg &msg);
|
||||||
void replyForumMessageData(const RsGxsForumMsg &msg);
|
void replyForumMessageData(const RsGxsForumMsg &msg);
|
||||||
|
|
||||||
|
void saveImage();
|
||||||
|
|
||||||
|
|
||||||
//void print();
|
//void print();
|
||||||
|
@ -453,10 +453,22 @@
|
|||||||
<verstretch>10</verstretch>
|
<verstretch>10</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="contextMenuPolicy">
|
||||||
|
<enum>Qt::CustomContextMenu</enum>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
<action name="actionSave_image">
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../images.qrc">
|
||||||
|
<normaloff>:/images/document_save.png</normaloff>:/images/document_save.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Save image</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
|
@ -27,8 +27,8 @@
|
|||||||
<table class='bubbleFooter' width='100%'>
|
<table class='bubbleFooter' width='100%'>
|
||||||
<tr>
|
<tr>
|
||||||
<td align='right'>
|
<td align='right'>
|
||||||
<span width='130' align='right' class='time'>%time% - </span>
|
<span width='130' align='right' class='time'>%time%%nome% - %/nome%</span>
|
||||||
<span class='name'>%name%</span>
|
<span class='name'>%nome%%name%%/nome%</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
<table class='bubbleFooter' width='100%'>
|
<table class='bubbleFooter' width='100%'>
|
||||||
<tr>
|
<tr>
|
||||||
<td align='left'>
|
<td align='left'>
|
||||||
<span class='name'> %name% - </span>
|
<span class='name'> %nome%%name% - %/nome%</span>
|
||||||
<span width='130' align='right' class='time'>%time%</span>
|
<span width='130' align='right' class='time'>%time%</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -28,8 +28,8 @@
|
|||||||
<table class='bubbleFooter' width='100%'>
|
<table class='bubbleFooter' width='100%'>
|
||||||
<tr>
|
<tr>
|
||||||
<td align='right'>
|
<td align='right'>
|
||||||
<span width='130' align='right' class='time'>%time% - </span>
|
<span width='130' align='right' class='time'>%time%%nome% - %/nome%</span>
|
||||||
<span class='name'>%name%</span>
|
<span class='name'>%nome%%name%%/nome%</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
<table class='bubbleFooter' width='100%'>
|
<table class='bubbleFooter' width='100%'>
|
||||||
<tr>
|
<tr>
|
||||||
<td align='left'>
|
<td align='left'>
|
||||||
<span class='name'> %name% - </span>
|
<span class='name'> %nome%%name% - %/nome%</span>
|
||||||
<span width='130' align='right' class='time'>%time%</span>
|
<span width='130' align='right' class='time'>%time%</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
<table class='bubbleFooter' width='100%'>
|
<table class='bubbleFooter' width='100%'>
|
||||||
<tr>
|
<tr>
|
||||||
<td align='left'>
|
<td align='left'>
|
||||||
<span class='name'> %name% - </span>
|
<span class='name'> %nome%%name% - %/nome%</span>
|
||||||
<span width='130' align='right' class='time'>%time%</span>
|
<span width='130' align='right' class='time'>%time%</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -3,5 +3,5 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<span class='hincomingTime'>%date% %time%</span>
|
<span class='hincomingTime'>%date% %time%</span>
|
||||||
<span class='name hincomingName'>%name%:</span>
|
<span class='name hincomingName'>%nome%%name%:%/nome%</span>
|
||||||
%message%
|
%message%
|
@ -3,5 +3,5 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<span class='houtgoingTime'>%date% %time%</span>
|
<span class='houtgoingTime'>%date% %time%</span>
|
||||||
<span class='name houtgoingName'>%name%:</span>
|
<span class='name houtgoingName'>%nome%%name%:%/nome%</span>
|
||||||
%message%
|
%message%
|
@ -3,5 +3,5 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<span class='incomingTime'>%time%</span>
|
<span class='incomingTime'>%time%</span>
|
||||||
<span class='name incomingName'>%name%:</span>
|
<span class='name incomingName'>%nome%%name%:%/nome%</span>
|
||||||
%message%
|
%message%
|
@ -25,3 +25,7 @@
|
|||||||
.systemTime {
|
.systemTime {
|
||||||
color:#808080;
|
color:#808080;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.meName {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
@ -3,5 +3,5 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<span class='ooutgoingTime'>%time%</span>
|
<span class='ooutgoingTime'>%time%</span>
|
||||||
<span class='name ooutgoingName'>%name%:</span>
|
<span class='name ooutgoingName'>%nome%%name%:%/nome%</span>
|
||||||
%message%
|
%message%
|
@ -3,5 +3,5 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<span class='outgoingTime'>%time%</span>
|
<span class='outgoingTime'>%time%</span>
|
||||||
<span class='name outgoingName'>%name%:</span>
|
<span class='name outgoingName'>%nome%%name%:%/nome%</span>
|
||||||
%message%
|
%message%
|
@ -3,5 +3,5 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<span class='hincomingTime'>%date% %time%</span>
|
<span class='hincomingTime'>%date% %time%</span>
|
||||||
<span class='name hincomingName'>%name%</span><br>
|
<span class='name hincomingName'>%nome%%name%%/nome%%me%*%/me%</span><br>
|
||||||
%message%
|
%message%
|
||||||
|
@ -3,5 +3,5 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<span class='houtgoingTime'>%date% %time%</span>
|
<span class='houtgoingTime'>%date% %time%</span>
|
||||||
<span class='name houtgoingName'>%name%</span><br>
|
<span class='name houtgoingName'>%nome%%name%%/nome%%me%*%/me%</span><br>
|
||||||
%message%
|
%message%
|
||||||
|
@ -3,5 +3,5 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<span class='incomingTime'>%time%</span>
|
<span class='incomingTime'>%time%</span>
|
||||||
<span class='name incomingName'>%name%</span><br>
|
<span class='name incomingName'>%nome%%name%%/nome%%me%*%/me%</span><br>
|
||||||
%message%
|
%message%
|
||||||
|
@ -47,3 +47,7 @@
|
|||||||
|
|
||||||
.systemName {
|
.systemName {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.meName {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
@ -3,5 +3,5 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<span class='ooutgoingTime'>%time%</span>
|
<span class='ooutgoingTime'>%time%</span>
|
||||||
<span class='name ooutgoingName'>%name%</span><br>
|
<span class='name ooutgoingName'>%nome%%name%%/nome%%me%*%/me%</span><br>
|
||||||
%message%
|
%message%
|
||||||
|
@ -3,5 +3,5 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<span class='outgoingTime'>%time%</span>
|
<span class='outgoingTime'>%time%</span>
|
||||||
<span class='name outgoingName'>%name%</span><br>
|
<span class='name outgoingName'>%nome%%name%%/nome%%me%*%/me%</span><br>
|
||||||
%message%
|
%message%
|
||||||
|
@ -188,6 +188,11 @@ NetworkDialog
|
|||||||
qproperty-backgroundColorDenied: lightGray;
|
qproperty-backgroundColorDenied: lightGray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RSTextBrowser, MimeTextEdit
|
||||||
|
{
|
||||||
|
qproperty-textColorQuote: rgb(120, 153, 34);
|
||||||
|
}
|
||||||
|
|
||||||
QLabel#headerTextLabel
|
QLabel#headerTextLabel
|
||||||
{
|
{
|
||||||
qproperty-fontSizeFactor: 225;
|
qproperty-fontSizeFactor: 225;
|
||||||
|
@ -338,6 +338,7 @@ void ChatPage::setPreviewMessages(QString &stylePath, QString styleVariant, QTex
|
|||||||
textBrowser->append(style.formatMessage(ChatStyle::FORMATMSG_OUTGOING, nameOutgoing, timestmp, tr("Outgoing message")));
|
textBrowser->append(style.formatMessage(ChatStyle::FORMATMSG_OUTGOING, nameOutgoing, timestmp, tr("Outgoing message")));
|
||||||
textBrowser->append(style.formatMessage(ChatStyle::FORMATMSG_OOUTGOING, nameOutgoing, timestmp, tr("Outgoing offline message")));
|
textBrowser->append(style.formatMessage(ChatStyle::FORMATMSG_OOUTGOING, nameOutgoing, timestmp, tr("Outgoing offline message")));
|
||||||
textBrowser->append(style.formatMessage(ChatStyle::FORMATMSG_SYSTEM, tr("System"), timestmp, tr("System message")));
|
textBrowser->append(style.formatMessage(ChatStyle::FORMATMSG_SYSTEM, tr("System"), timestmp, tr("System message")));
|
||||||
|
textBrowser->append(style.formatMessage(ChatStyle::FORMATMSG_OUTGOING, tr("UserName"), timestmp, tr("/me is sending a message with /me")));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatPage::fillPreview(QListWidget *listWidget, QComboBox *comboBox, QTextBrowser *textBrowser)
|
void ChatPage::fillPreview(QListWidget *listWidget, QComboBox *comboBox, QTextBrowser *textBrowser)
|
||||||
|
@ -523,7 +523,9 @@ HEADERS += rshare.h \
|
|||||||
gui/groups/CreateGroup.h \
|
gui/groups/CreateGroup.h \
|
||||||
gui/GetStartedDialog.h \
|
gui/GetStartedDialog.h \
|
||||||
gui/settings/WebuiPage.h \
|
gui/settings/WebuiPage.h \
|
||||||
gui/statistics/BWGraph.h
|
gui/statistics/BWGraph.h \
|
||||||
|
util/RsSyntaxHighlighter.h \
|
||||||
|
util/imageutil.h
|
||||||
|
|
||||||
# gui/ForumsDialog.h \
|
# gui/ForumsDialog.h \
|
||||||
# gui/forums/ForumDetails.h \
|
# gui/forums/ForumDetails.h \
|
||||||
@ -871,7 +873,9 @@ SOURCES += main.cpp \
|
|||||||
gui/statistics/StatisticsWindow.cpp \
|
gui/statistics/StatisticsWindow.cpp \
|
||||||
gui/statistics/BwCtrlWindow.cpp \
|
gui/statistics/BwCtrlWindow.cpp \
|
||||||
gui/statistics/RttStatistics.cpp \
|
gui/statistics/RttStatistics.cpp \
|
||||||
gui/statistics/BWGraph.cpp
|
gui/statistics/BWGraph.cpp \
|
||||||
|
util/RsSyntaxHighlighter.cpp \
|
||||||
|
util/imageutil.cpp
|
||||||
|
|
||||||
# gui/ForumsDialog.cpp \
|
# gui/ForumsDialog.cpp \
|
||||||
# gui/forums/ForumDetails.cpp \
|
# gui/forums/ForumDetails.cpp \
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QTextDocumentFragment>
|
#include <QTextDocumentFragment>
|
||||||
#include <qmath.h>
|
#include <qmath.h>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
#include "HandleRichText.h"
|
#include "HandleRichText.h"
|
||||||
#include "gui/RetroShareLink.h"
|
#include "gui/RetroShareLink.h"
|
||||||
@ -569,7 +570,6 @@ static void optimizeHtml(QDomDocument& doc
|
|||||||
, QHash<QString, QStringList*> &stylesList
|
, QHash<QString, QStringList*> &stylesList
|
||||||
, QHash<QString, QString> &knownStyle)
|
, QHash<QString, QString> &knownStyle)
|
||||||
{
|
{
|
||||||
bool bFirstP=true;
|
|
||||||
if (doc.documentElement().namedItem("style").toElement().attributeNode("RSOptimized").isAttr()) {
|
if (doc.documentElement().namedItem("style").toElement().attributeNode("RSOptimized").isAttr()) {
|
||||||
//Already optimized only get StyleList
|
//Already optimized only get StyleList
|
||||||
QDomElement styleElem = doc.documentElement().namedItem("style").toElement();
|
QDomElement styleElem = doc.documentElement().namedItem("style").toElement();
|
||||||
@ -611,51 +611,9 @@ static void optimizeHtml(QDomDocument& doc
|
|||||||
QDomNodeList children = currentElement.childNodes();
|
QDomNodeList children = currentElement.childNodes();
|
||||||
for (uint index = 0; index < children.length(); ) {
|
for (uint index = 0; index < children.length(); ) {
|
||||||
QDomNode node = children.item(index);
|
QDomNode node = children.item(index);
|
||||||
|
|
||||||
// Compress style attribute
|
|
||||||
styleNode = node.attributes().namedItem("style");
|
|
||||||
if (styleNode.isAttr()) {
|
|
||||||
QDomAttr styleAttr = styleNode.toAttr();
|
|
||||||
QString style = styleAttr.value().simplified().trimmed();
|
|
||||||
style.replace("margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px;", "margin:0px 0px 0px 0px;");
|
|
||||||
style.replace("; ", ";");
|
|
||||||
|
|
||||||
QString className = knownStyle.value(style);
|
|
||||||
if (className.isEmpty()) {
|
|
||||||
// Create a new class
|
|
||||||
className = QString("S%1").arg(knownStyle.count());
|
|
||||||
knownStyle.insert(style, className);
|
|
||||||
|
|
||||||
// Now add this for each attribute values
|
|
||||||
QStringList styles = style.split(';');
|
|
||||||
foreach (QString pair, styles) {
|
|
||||||
pair.replace(" ","");
|
|
||||||
if (!pair.isEmpty()) {
|
|
||||||
QStringList* stylesListItem = stylesList.value(pair);
|
|
||||||
if(!stylesListItem){
|
|
||||||
// If value doesn't exist create it
|
|
||||||
stylesListItem = new QStringList();
|
|
||||||
stylesList.insert(pair, stylesListItem);
|
|
||||||
}
|
|
||||||
//Add the new class to this value
|
|
||||||
stylesListItem->push_back(className);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
style.clear();
|
|
||||||
|
|
||||||
node.attributes().removeNamedItem("style");
|
|
||||||
styleNode.clear();
|
|
||||||
|
|
||||||
if (!className.isEmpty()) {
|
|
||||||
QDomNode classNode = doc.createAttribute("class");
|
|
||||||
classNode.setNodeValue(className);
|
|
||||||
node.attributes().setNamedItem(classNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node.isElement()) {
|
if (node.isElement()) {
|
||||||
QDomElement element = node.toElement();
|
QDomElement element = node.toElement();
|
||||||
|
styleNode = node.attributes().namedItem("style");
|
||||||
|
|
||||||
// not <p>
|
// not <p>
|
||||||
if (addBR && element.tagName().toLower() != "p") {
|
if (addBR && element.tagName().toLower() != "p") {
|
||||||
@ -686,19 +644,38 @@ static void optimizeHtml(QDomDocument& doc
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//hidden text in a
|
||||||
|
if (element.tagName().toLower() == "a") {
|
||||||
|
if(element.hasAttribute("href")){
|
||||||
|
QString href = element.attribute("href", "");
|
||||||
|
if(href.startsWith("hidden:")){
|
||||||
|
//this text should be hidden and appear in title
|
||||||
|
//we need this trick, because QTextEdit doesn't export the title attribute
|
||||||
|
QString title = href.remove(0, QString("hidden:").length());
|
||||||
|
QString text = element.text();
|
||||||
|
element.setTagName("span");
|
||||||
|
element.removeAttribute("href");
|
||||||
|
QDomNodeList c = element.childNodes();
|
||||||
|
for(int i = 0; i < c.count(); i++){
|
||||||
|
element.removeChild(c.at(i));
|
||||||
|
};
|
||||||
|
element.setAttribute(QString("title"), title);
|
||||||
|
QDomText textnode = doc.createTextNode(text);
|
||||||
|
element.appendChild(textnode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// iterate children
|
// iterate children
|
||||||
optimizeHtml(doc, element, stylesList, knownStyle);
|
optimizeHtml(doc, element, stylesList, knownStyle);
|
||||||
|
|
||||||
// <p>
|
// <p>
|
||||||
if (element.tagName().toLower() == "p") {
|
if (element.tagName().toLower() == "p") {
|
||||||
//If it's the first <p>, replace it as <span> otherwise make "\n" before first line
|
|
||||||
if (bFirstP) {
|
|
||||||
element.setTagName("span");
|
|
||||||
bFirstP = false;
|
|
||||||
}
|
|
||||||
// <p style="...">
|
// <p style="...">
|
||||||
if (element.attributes().size() == 1 && styleNode.isAttr()) {
|
if (styleNode.isAttr()) {
|
||||||
QString style = styleNode.toAttr().value().simplified();
|
QString style = styleNode.toAttr().value().simplified().trimmed();
|
||||||
|
style.replace("margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px;", "margin:0px 0px 0px 0px;");
|
||||||
|
style.replace("; ", ";");
|
||||||
if (style == "margin:0px 0px 0px 0px;-qt-block-indent:0;text-indent:0px;"
|
if (style == "margin:0px 0px 0px 0px;-qt-block-indent:0;text-indent:0px;"
|
||||||
|| style.startsWith("-qt-paragraph-type:empty;margin:0px 0px 0px 0px;-qt-block-indent:0;text-indent:0px;")) {
|
|| style.startsWith("-qt-paragraph-type:empty;margin:0px 0px 0px 0px;-qt-block-indent:0;text-indent:0px;")) {
|
||||||
|
|
||||||
@ -719,6 +696,46 @@ static void optimizeHtml(QDomDocument& doc
|
|||||||
}
|
}
|
||||||
addBR = false;
|
addBR = false;
|
||||||
}
|
}
|
||||||
|
// Compress style attribute
|
||||||
|
if (styleNode.isAttr()) {
|
||||||
|
QDomAttr styleAttr = styleNode.toAttr();
|
||||||
|
QString style = styleAttr.value().simplified().trimmed();
|
||||||
|
style.replace("margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px;", "margin:0px 0px 0px 0px;");
|
||||||
|
style.replace("; ", ";");
|
||||||
|
|
||||||
|
QString className = knownStyle.value(style);
|
||||||
|
if (className.isEmpty()) {
|
||||||
|
// Create a new class
|
||||||
|
className = QString("S%1").arg(knownStyle.count());
|
||||||
|
knownStyle.insert(style, className);
|
||||||
|
|
||||||
|
// Now add this for each attribute values
|
||||||
|
QStringList styles = style.split(';');
|
||||||
|
foreach (QString pair, styles) {
|
||||||
|
pair.replace(" ","");
|
||||||
|
if (!pair.isEmpty()) {
|
||||||
|
QStringList* stylesListItem = stylesList.value(pair);
|
||||||
|
if(!stylesListItem){
|
||||||
|
// If value doesn't exist create it
|
||||||
|
stylesListItem = new QStringList();
|
||||||
|
stylesList.insert(pair, stylesListItem);
|
||||||
|
}
|
||||||
|
//Add the new class to this value
|
||||||
|
stylesListItem->push_back(className);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
style.clear();
|
||||||
|
|
||||||
|
node.attributes().removeNamedItem("style");
|
||||||
|
styleNode.clear();
|
||||||
|
|
||||||
|
if (!className.isEmpty()) {
|
||||||
|
QDomNode classNode = doc.createAttribute("class");
|
||||||
|
classNode.setNodeValue(className);
|
||||||
|
node.attributes().setNamedItem(classNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
@ -1010,3 +1027,20 @@ QString RsHtml::makeQuotedText(RSTextBrowser *browser)
|
|||||||
text = sl.join("\n>");
|
text = sl.join("\n>");
|
||||||
return QString(">") + text;
|
return QString(">") + text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RsHtml::insertSpoilerText(QTextCursor cursor)
|
||||||
|
{
|
||||||
|
QString hiddentext = cursor.selection().toPlainText();
|
||||||
|
if(hiddentext.isEmpty()) return;
|
||||||
|
QString publictext = "*SPOILER*";
|
||||||
|
|
||||||
|
QString encoded = hiddentext;
|
||||||
|
encoded = encoded.replace(QChar('\"'), QString("""));
|
||||||
|
encoded = encoded.replace(QChar('\''), QString("'"));
|
||||||
|
encoded = encoded.replace(QChar('<'), QString("<"));
|
||||||
|
encoded = encoded.replace(QChar('>'), QString(">"));
|
||||||
|
encoded = encoded.replace(QChar('&'), QString("&"));
|
||||||
|
|
||||||
|
QString html = QString("<a href=\"hidden:%1\" title=\"%1\">%2</a>").arg(encoded, publictext);
|
||||||
|
cursor.insertHtml(html);
|
||||||
|
}
|
||||||
|
@ -53,6 +53,7 @@ class QDomDocument;
|
|||||||
class QDomElement;
|
class QDomElement;
|
||||||
class EmbedInHtml;
|
class EmbedInHtml;
|
||||||
class RetroShareLink;
|
class RetroShareLink;
|
||||||
|
class QTextCursor;
|
||||||
|
|
||||||
class RsHtml
|
class RsHtml
|
||||||
{
|
{
|
||||||
@ -75,6 +76,7 @@ public:
|
|||||||
static QString plainText(const std::string &text);
|
static QString plainText(const std::string &text);
|
||||||
|
|
||||||
static QString makeQuotedText(RSTextBrowser* browser);
|
static QString makeQuotedText(RSTextBrowser* browser);
|
||||||
|
static void insertSpoilerText(QTextCursor cursor);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void embedHtml(QTextDocument *textDocument, QDomDocument &doc, QDomElement ¤tElement, EmbedInHtml& embedInfos, ulong flag);
|
void embedHtml(QTextDocument *textDocument, QDomDocument &doc, QDomElement ¤tElement, EmbedInHtml& embedInfos, ulong flag);
|
||||||
|
45
retroshare-gui/src/util/RsSyntaxHighlighter.cpp
Normal file
45
retroshare-gui/src/util/RsSyntaxHighlighter.cpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#include "RsSyntaxHighlighter.h"
|
||||||
|
|
||||||
|
RsSyntaxHighlighter::RsSyntaxHighlighter(QTextEdit *parent)
|
||||||
|
: QSyntaxHighlighter(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void RsSyntaxHighlighter::highlightBlock(const QString &text)
|
||||||
|
{
|
||||||
|
QRegExp endl("[\\r\\n\\x2028]"); //Usually 0x2028 cahracter is used for newline, no idea why
|
||||||
|
int index = 0;
|
||||||
|
QStringList lines = text.split(endl);
|
||||||
|
foreach (const QString &line, lines) {
|
||||||
|
if(line.trimmed().startsWith('>')) {
|
||||||
|
setFormat(index, line.length(), quotationFormat);
|
||||||
|
}
|
||||||
|
index += line.length() + 1;
|
||||||
|
}
|
||||||
|
//Make it work with the compact chat style
|
||||||
|
if(lines.length() > 0){
|
||||||
|
int i = lines[0].indexOf(": >");
|
||||||
|
if(i != -1) {
|
||||||
|
setFormat(i+2, lines[0].length()-i-2, quotationFormat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RsSyntaxHighlighter::setTextColorQuote(QColor textColorQuote)
|
||||||
|
{
|
||||||
|
quotationFormat.setForeground(textColorQuote);
|
||||||
|
this->rehighlight();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Dumping the raw unicode string into the console in Base64 encoding
|
||||||
|
/*
|
||||||
|
QByteArray uniline;
|
||||||
|
const QChar* qca = line.unicode();
|
||||||
|
for(int i=0; qca[i]!='\0' ;++i)
|
||||||
|
{
|
||||||
|
uniline.append(qca[i].row());
|
||||||
|
uniline.append(qca[i].cell());
|
||||||
|
}
|
||||||
|
std::cout << "Line: " << uniline.toBase64().toStdString() << std::endl;
|
||||||
|
*/
|
31
retroshare-gui/src/util/RsSyntaxHighlighter.h
Normal file
31
retroshare-gui/src/util/RsSyntaxHighlighter.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#ifndef RSSYNTAXHIGHLIGHTER_H
|
||||||
|
#define RSSYNTAXHIGHLIGHTER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QSyntaxHighlighter>
|
||||||
|
#include <QTextEdit>
|
||||||
|
|
||||||
|
class RsSyntaxHighlighter : public QSyntaxHighlighter
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(QColor textColorQuote READ textColorQuote WRITE setTextColorQuote)
|
||||||
|
|
||||||
|
public:
|
||||||
|
RsSyntaxHighlighter(QTextEdit *parent = 0);
|
||||||
|
QColor textColorQuote() const { return quotationFormat.foreground().color(); };
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void highlightBlock(const QString &text);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QTextCharFormat quotationFormat;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setTextColorQuote(QColor textColorQuote);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RSSYNTAXHIGHLIGHTER_H
|
51
retroshare-gui/src/util/imageutil.cpp
Normal file
51
retroshare-gui/src/util/imageutil.cpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#include "imageutil.h"
|
||||||
|
#include "util/misc.h"
|
||||||
|
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QTextCursor>
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QString>
|
||||||
|
#include <QImage>
|
||||||
|
#include <QTextDocumentFragment>
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
ImageUtil::ImageUtil() {}
|
||||||
|
|
||||||
|
void ImageUtil::extractImage(QWidget *window, QTextCursor cursor)
|
||||||
|
{
|
||||||
|
cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1);
|
||||||
|
cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, 2);
|
||||||
|
QString imagestr = cursor.selection().toHtml();
|
||||||
|
bool success = false;
|
||||||
|
int start = imagestr.indexOf("base64,") + 7;
|
||||||
|
int stop = imagestr.indexOf("\"", start);
|
||||||
|
int length = stop - start;
|
||||||
|
if((start >= 0) && (length > 0))
|
||||||
|
{
|
||||||
|
QByteArray ba = QByteArray::fromBase64(imagestr.mid(start, length).toLatin1());
|
||||||
|
QImage image = QImage::fromData(ba);
|
||||||
|
if(!image.isNull())
|
||||||
|
{
|
||||||
|
QString file;
|
||||||
|
success = true;
|
||||||
|
if(misc::getSaveFileName(window, RshareSettings::LASTDIR_IMAGES, "Save Picture File", "Pictures (*.png *.xpm *.jpg)", file))
|
||||||
|
{
|
||||||
|
if(!image.save(file, 0, 100))
|
||||||
|
if(!image.save(file + ".png", 0, 100))
|
||||||
|
QMessageBox::warning(window, QApplication::translate("ImageUtil", "Save image"), QApplication::translate("ImageUtil", "Cannot save the image, invalid filename"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!success)
|
||||||
|
{
|
||||||
|
QMessageBox::warning(window, QApplication::translate("ImageUtil", "Save image"), QApplication::translate("ImageUtil", "Not an image"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImageUtil::checkImage(QTextCursor cursor)
|
||||||
|
{
|
||||||
|
cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1);
|
||||||
|
cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, 2);
|
||||||
|
QString imagestr = cursor.selection().toHtml();
|
||||||
|
return imagestr.indexOf("base64,") != -1;
|
||||||
|
}
|
17
retroshare-gui/src/util/imageutil.h
Normal file
17
retroshare-gui/src/util/imageutil.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef IMAGEUTIL_H
|
||||||
|
#define IMAGEUTIL_H
|
||||||
|
|
||||||
|
#include <QTextCursor>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
|
||||||
|
class ImageUtil
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ImageUtil();
|
||||||
|
|
||||||
|
static void extractImage(QWidget *window, QTextCursor cursor);
|
||||||
|
static bool checkImage(QTextCursor cursor);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // IMAGEUTIL_H
|
Loading…
Reference in New Issue
Block a user