mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2025-09-13 20:23:04 +02:00
Update richtexteditor
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@3014 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
parent
aa6d7efd98
commit
38f1d820b1
BIN
ico/32x32/simplifyrichtext.png
Normal file
BIN
ico/32x32/simplifyrichtext.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
@ -227,5 +227,6 @@
|
|||||||
<file>ico/22x22/applications-development-translation.png</file>
|
<file>ico/22x22/applications-development-translation.png</file>
|
||||||
<file>ico/48x48/view-pim-journal.png</file>
|
<file>ico/48x48/view-pim-journal.png</file>
|
||||||
<file>ico/24x16/nl.png</file>
|
<file>ico/24x16/nl.png</file>
|
||||||
|
<file>ico/32x32/simplifyrichtext.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
@ -53,9 +53,9 @@
|
|||||||
#include <QtCore/QList>
|
#include <QtCore/QList>
|
||||||
#include <QtCore/QMap>
|
#include <QtCore/QMap>
|
||||||
#include <QtCore/QPointer>
|
#include <QtCore/QPointer>
|
||||||
#include <QtCore/QProcess>
|
#include <QtCore/QXmlStreamReader>
|
||||||
#include <QtCore/QTemporaryFile>
|
#include <QtCore/QXmlStreamWriter>
|
||||||
#include <QtCore/QDir>
|
#include <QtCore/QXmlStreamAttributes>
|
||||||
|
|
||||||
#include <QtGui/QAction>
|
#include <QtGui/QAction>
|
||||||
#include <QtGui/QColorDialog>
|
#include <QtGui/QColorDialog>
|
||||||
@ -78,10 +78,103 @@
|
|||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
//static const char *RichTextDialogC = "RichTextDialog";
|
static const char RichTextDialogGroupC[] = "RichTextDialog";
|
||||||
//static const char *Geometry = "Geometry";
|
static const char GeometryKeyC[] = "Geometry";
|
||||||
|
static const char TabKeyC[] = "Tab";
|
||||||
|
|
||||||
|
const bool simplifyRichTextDefault = true;
|
||||||
|
|
||||||
namespace qdesigner_internal {
|
namespace qdesigner_internal {
|
||||||
|
// Richtext simplification filter helpers: Elements to be discarded
|
||||||
|
static inline bool filterElement(const QStringRef &name)
|
||||||
|
{
|
||||||
|
return name != QLatin1String("meta") && name != QLatin1String("style");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Richtext simplification filter helpers: Filter attributes of elements
|
||||||
|
static inline void filterAttributes(const QStringRef &name,
|
||||||
|
QXmlStreamAttributes *atts,
|
||||||
|
bool *paragraphAlignmentFound)
|
||||||
|
{
|
||||||
|
typedef QXmlStreamAttributes::iterator AttributeIt;
|
||||||
|
|
||||||
|
if (atts->isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// No style attributes for <body>
|
||||||
|
if (name == QLatin1String("body")) {
|
||||||
|
atts->clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean out everything except 'align' for 'p'
|
||||||
|
if (name == QLatin1String("p")) {
|
||||||
|
for (AttributeIt it = atts->begin(); it != atts->end(); ) {
|
||||||
|
if (it->name() == QLatin1String("align")) {
|
||||||
|
++it;
|
||||||
|
*paragraphAlignmentFound = true;
|
||||||
|
} else {
|
||||||
|
it = atts->erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Richtext simplification filter helpers: Check for blank QStringRef.
|
||||||
|
static inline bool isWhiteSpace(const QStringRef &in)
|
||||||
|
{
|
||||||
|
const int count = in.size();
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
if (!in.at(i).isSpace())
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Richtext simplification filter: Remove hard-coded font settings,
|
||||||
|
// <style> elements, <p> attributes other than 'align' and
|
||||||
|
// and unnecessary meta-information.
|
||||||
|
QString simplifyRichTextFilter(const QString &in, bool *isPlainTextPtr = 0)
|
||||||
|
{
|
||||||
|
unsigned elementCount = 0;
|
||||||
|
bool paragraphAlignmentFound = false;
|
||||||
|
QString out;
|
||||||
|
QXmlStreamReader reader(in);
|
||||||
|
QXmlStreamWriter writer(&out);
|
||||||
|
writer.setAutoFormatting(false);
|
||||||
|
writer.setAutoFormattingIndent(0);
|
||||||
|
|
||||||
|
while (!reader.atEnd()) {
|
||||||
|
switch (reader.readNext()) {
|
||||||
|
case QXmlStreamReader::StartElement:
|
||||||
|
elementCount++;
|
||||||
|
if (filterElement(reader.name())) {
|
||||||
|
const QStringRef name = reader.name();
|
||||||
|
QXmlStreamAttributes attributes = reader.attributes();
|
||||||
|
filterAttributes(name, &attributes, ¶graphAlignmentFound);
|
||||||
|
writer.writeStartElement(name.toString());
|
||||||
|
if (!attributes.isEmpty())
|
||||||
|
writer.writeAttributes(attributes);
|
||||||
|
} else {
|
||||||
|
reader.readElementText(); // Skip away all nested elements and characters.
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case QXmlStreamReader::Characters:
|
||||||
|
if (!isWhiteSpace(reader.text()))
|
||||||
|
writer.writeCharacters(reader.text().toString());
|
||||||
|
break;
|
||||||
|
case QXmlStreamReader::EndElement:
|
||||||
|
writer.writeEndElement();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check for plain text (no spans, just <html><head><body><p>)
|
||||||
|
if (isPlainTextPtr)
|
||||||
|
*isPlainTextPtr = !paragraphAlignmentFound && elementCount == 4u; //
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
class RichTextEditor : public QTextEdit
|
class RichTextEditor : public QTextEdit
|
||||||
{
|
{
|
||||||
@ -91,6 +184,7 @@ public:
|
|||||||
void setDefaultFont(const QFont &font);
|
void setDefaultFont(const QFont &font);
|
||||||
|
|
||||||
QToolBar *createToolBar(QWidget *parent = 0);
|
QToolBar *createToolBar(QWidget *parent = 0);
|
||||||
|
bool simplifyRichText() const { return m_simplifyRichText; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setFontBold(bool b);
|
void setFontBold(bool b);
|
||||||
@ -100,6 +194,10 @@ public slots:
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
void stateChanged();
|
void stateChanged();
|
||||||
|
void simplifyRichTextChanged(bool);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_simplifyRichText;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AddLinkDialog : public QDialog
|
class AddLinkDialog : public QDialog
|
||||||
@ -293,7 +391,7 @@ private slots:
|
|||||||
void setVAlignSub(bool sub);
|
void setVAlignSub(bool sub);
|
||||||
void insertLink();
|
void insertLink();
|
||||||
void insertImage();
|
void insertImage();
|
||||||
void runXmlPatterns();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QAction *m_bold_action;
|
QAction *m_bold_action;
|
||||||
@ -307,7 +405,7 @@ private:
|
|||||||
QAction *m_align_justify_action;
|
QAction *m_align_justify_action;
|
||||||
QAction *m_link_action;
|
QAction *m_link_action;
|
||||||
QAction *m_image_action;
|
QAction *m_image_action;
|
||||||
QAction *m_xmlPatterns;
|
QAction *m_simplify_richtext_action;
|
||||||
ColorAction *m_color_action;
|
ColorAction *m_color_action;
|
||||||
QComboBox *m_font_size_input;
|
QComboBox *m_font_size_input;
|
||||||
|
|
||||||
@ -338,11 +436,6 @@ RichTextEditorToolBar::RichTextEditorToolBar(RichTextEditor *editor,
|
|||||||
m_editor(editor)
|
m_editor(editor)
|
||||||
{
|
{
|
||||||
|
|
||||||
m_xmlPatterns = new QAction("Run XMLPatterns", this);
|
|
||||||
connect(m_xmlPatterns, SIGNAL(triggered()), this, SLOT(runXmlPatterns()));
|
|
||||||
addAction(m_xmlPatterns);
|
|
||||||
m_xmlPatterns -> setVisible( false );
|
|
||||||
|
|
||||||
// Font size combo box
|
// Font size combo box
|
||||||
m_font_size_input->setEditable(false);
|
m_font_size_input->setEditable(false);
|
||||||
const QList<int> font_sizes = QFontDatabase::standardSizes();
|
const QList<int> font_sizes = QFontDatabase::standardSizes();
|
||||||
@ -353,7 +446,6 @@ RichTextEditorToolBar::RichTextEditorToolBar(RichTextEditor *editor,
|
|||||||
this, SLOT(sizeInputActivated(QString)));
|
this, SLOT(sizeInputActivated(QString)));
|
||||||
addWidget(m_font_size_input);
|
addWidget(m_font_size_input);
|
||||||
|
|
||||||
addSeparator();
|
|
||||||
|
|
||||||
// Bold, italic and underline buttons
|
// Bold, italic and underline buttons
|
||||||
|
|
||||||
@ -375,7 +467,6 @@ RichTextEditorToolBar::RichTextEditorToolBar(RichTextEditor *editor,
|
|||||||
m_underline_action->setShortcut(tr("CTRL+U"));
|
m_underline_action->setShortcut(tr("CTRL+U"));
|
||||||
addAction(m_underline_action);
|
addAction(m_underline_action);
|
||||||
|
|
||||||
addSeparator();
|
|
||||||
|
|
||||||
// Left, center, right and justified alignment buttons
|
// Left, center, right and justified alignment buttons
|
||||||
|
|
||||||
@ -407,7 +498,6 @@ RichTextEditorToolBar::RichTextEditorToolBar(RichTextEditor *editor,
|
|||||||
m_align_center_action -> setVisible( false );
|
m_align_center_action -> setVisible( false );
|
||||||
m_align_left_action -> setVisible( false );
|
m_align_left_action -> setVisible( false );
|
||||||
m_align_right_action -> setVisible( false );
|
m_align_right_action -> setVisible( false );
|
||||||
//addSeparator();
|
|
||||||
|
|
||||||
// Superscript and subscript buttons
|
// Superscript and subscript buttons
|
||||||
|
|
||||||
@ -426,8 +516,6 @@ RichTextEditorToolBar::RichTextEditorToolBar(RichTextEditor *editor,
|
|||||||
m_valign_sup_action -> setVisible( false );
|
m_valign_sup_action -> setVisible( false );
|
||||||
m_valign_sub_action -> setVisible( false );
|
m_valign_sub_action -> setVisible( false );
|
||||||
|
|
||||||
//addSeparator();
|
|
||||||
|
|
||||||
// Insert hyperlink and image buttons
|
// Insert hyperlink and image buttons
|
||||||
|
|
||||||
m_link_action->setText(tr("Ins\351rer un lien"));
|
m_link_action->setText(tr("Ins\351rer un lien"));
|
||||||
@ -446,6 +534,16 @@ RichTextEditorToolBar::RichTextEditorToolBar(RichTextEditor *editor,
|
|||||||
this, SLOT(colorChanged(QColor)));
|
this, SLOT(colorChanged(QColor)));
|
||||||
addAction(m_color_action);
|
addAction(m_color_action);
|
||||||
|
|
||||||
|
|
||||||
|
// Simplify rich text
|
||||||
|
m_simplify_richtext_action = createCheckableAction(
|
||||||
|
QIcon(":/ico/32x32/simplifyrichtext.png"),
|
||||||
|
tr("Simplify Rich Text"), editor, SLOT(setSimplifyRichText(bool)),this);
|
||||||
|
m_simplify_richtext_action->setChecked(editor->simplifyRichText());
|
||||||
|
connect(m_editor, SIGNAL(simplifyRichTextChanged(bool)),
|
||||||
|
m_simplify_richtext_action, SLOT(setChecked(bool)));
|
||||||
|
addAction(m_simplify_richtext_action);
|
||||||
|
|
||||||
connect(editor, SIGNAL(textChanged()), this, SLOT(updateActions()));
|
connect(editor, SIGNAL(textChanged()), this, SLOT(updateActions()));
|
||||||
connect(editor, SIGNAL(stateChanged()), this, SLOT(updateActions()));
|
connect(editor, SIGNAL(stateChanged()), this, SLOT(updateActions()));
|
||||||
|
|
||||||
@ -469,37 +567,8 @@ void RichTextEditorToolBar::alignmentActionTriggered(QAction *action)
|
|||||||
m_editor->setAlignment(new_alignment);
|
m_editor->setAlignment(new_alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString runXSLT(const QString &t)
|
|
||||||
{
|
|
||||||
QString pattern = QDir::tempPath();
|
|
||||||
if (!pattern.endsWith('/'))
|
|
||||||
pattern += '/';
|
|
||||||
pattern += "qt_tempXXXXXX.html";
|
|
||||||
QTemporaryFile tf(pattern);
|
|
||||||
if (!tf.open())
|
|
||||||
return QLatin1String("Open failure");
|
|
||||||
const QString tfName = tf.fileName();
|
|
||||||
tf.write(t.toUtf8());
|
|
||||||
tf.close();
|
|
||||||
QProcess p;
|
|
||||||
QStringList args;
|
|
||||||
args << "tohtml.xsl" << tfName;
|
|
||||||
p.start("xmlpatterns",args);
|
|
||||||
if (!p.waitForStarted() || !p.waitForFinished())
|
|
||||||
return QLatin1String("Run failure");
|
|
||||||
const QByteArray output = p.exitStatus() == QProcess::NormalExit &&
|
|
||||||
p.exitCode() == 0 ?
|
|
||||||
p.readAllStandardOutput() :
|
|
||||||
p.readAllStandardError();
|
|
||||||
return QString::fromUtf8(output);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void RichTextEditorToolBar::runXmlPatterns()
|
|
||||||
{
|
|
||||||
qWarning("%s", qPrintable(runXSLT(m_editor->text(Qt::RichText))));
|
|
||||||
}
|
|
||||||
|
|
||||||
void RichTextEditorToolBar::colorChanged(const QColor &color)
|
void RichTextEditorToolBar::colorChanged(const QColor &color)
|
||||||
{
|
{
|
||||||
m_editor->setTextColor(color);
|
m_editor->setTextColor(color);
|
||||||
@ -649,15 +718,16 @@ QString RichTextEditor::text(Qt::TextFormat format) const
|
|||||||
case Qt::PlainText:
|
case Qt::PlainText:
|
||||||
return toPlainText();
|
return toPlainText();
|
||||||
case Qt::RichText:
|
case Qt::RichText:
|
||||||
return toHtml();
|
return m_simplifyRichText ? simplifyRichTextFilter(toHtml()) : toHtml();
|
||||||
case Qt::AutoText:
|
case Qt::AutoText:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const QString html = toHtml();
|
const QString html = toHtml();
|
||||||
const QString plain = toPlainText();
|
bool isPlainText;
|
||||||
QTextEdit tester;
|
const QString simplifiedHtml = simplifyRichTextFilter(html, &isPlainText);
|
||||||
tester.setPlainText(plain);
|
if (isPlainText)
|
||||||
return tester.toHtml() == html ? plain : html;
|
return toPlainText();
|
||||||
|
return m_simplifyRichText ? simplifiedHtml : html;
|
||||||
}
|
}
|
||||||
|
|
||||||
RichTextEditorDialog::RichTextEditorDialog(QWidget *parent) :
|
RichTextEditorDialog::RichTextEditorDialog(QWidget *parent) :
|
||||||
@ -771,7 +841,6 @@ void RichTextEditorDialog::tabIndexChanged(int newIndex)
|
|||||||
|
|
||||||
if (newIndex == SourceIndex) {
|
if (newIndex == SourceIndex) {
|
||||||
const QString html = m_editor->text(Qt::RichText);
|
const QString html = m_editor->text(Qt::RichText);
|
||||||
qWarning("%s", qPrintable(runXSLT(html)));
|
|
||||||
m_text_edit->setPlainText(html);
|
m_text_edit->setPlainText(html);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
|
Loading…
x
Reference in New Issue
Block a user