- enhancement: Print current selection can be used in the print dialog.
- enhancement: Print syntax colored content. - enhancement: Correctly handle tab in the exported RTF.
This commit is contained in:
parent
17160b7c3d
commit
b01a51ab91
2
NEWS.md
2
NEWS.md
|
@ -15,6 +15,8 @@ Red Panda C++ Version 2.8
|
||||||
- enhancement: Let encoding options in the statusbar more explicit.
|
- enhancement: Let encoding options in the statusbar more explicit.
|
||||||
- fix: Crash when find occurrences in a project that has missing files.
|
- fix: Crash when find occurrences in a project that has missing files.
|
||||||
- enhancement: Print current selection can be used in the print dialog.
|
- enhancement: Print current selection can be used in the print dialog.
|
||||||
|
- enhancement: Print syntax colored content.
|
||||||
|
- enhancement: Correctly handle tab in the exported RTF.
|
||||||
|
|
||||||
Red Panda C++ Version 2.7
|
Red Panda C++ Version 2.7
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,9 @@
|
||||||
#include <QMimeData>
|
#include <QMimeData>
|
||||||
#include "qsynedit/syntaxer/cpp.h"
|
#include "qsynedit/syntaxer/cpp.h"
|
||||||
#include "syntaxermanager.h"
|
#include "syntaxermanager.h"
|
||||||
#include "qsynedit/exporter/synrtfexporter.h"
|
#include "qsynedit/exporter/rtfexporter.h"
|
||||||
#include "qsynedit/exporter/synhtmlexporter.h"
|
#include "qsynedit/exporter/htmlexporter.h"
|
||||||
|
#include "qsynedit/exporter/qtsupportedhtmlexporter.h"
|
||||||
#include "qsynedit/Constants.h"
|
#include "qsynedit/Constants.h"
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
|
@ -1482,10 +1483,9 @@ void Editor::copyAsHTML()
|
||||||
{
|
{
|
||||||
if (!selAvail())
|
if (!selAvail())
|
||||||
return;
|
return;
|
||||||
QSynedit::SynHTMLExporter exporter(tabWidth(), pCharsetInfoManager->getDefaultSystemEncoding());
|
QSynedit::HTMLExporter exporter(tabWidth(), pCharsetInfoManager->getDefaultSystemEncoding());
|
||||||
|
|
||||||
exporter.setTitle(QFileInfo(mFilename).fileName());
|
exporter.setTitle(QFileInfo(mFilename).fileName());
|
||||||
exporter.setExportAsText(false);
|
|
||||||
exporter.setUseBackground(pSettings->editor().copyHTMLUseBackground());
|
exporter.setUseBackground(pSettings->editor().copyHTMLUseBackground());
|
||||||
exporter.setFont(font());
|
exporter.setFont(font());
|
||||||
QSynedit::PSyntaxer hl = syntaxer();
|
QSynedit::PSyntaxer hl = syntaxer();
|
||||||
|
@ -1504,7 +1504,7 @@ void Editor::copyAsHTML()
|
||||||
));
|
));
|
||||||
exporter.setCreateHTMLFragment(true);
|
exporter.setCreateHTMLFragment(true);
|
||||||
|
|
||||||
exporter.ExportRange(document(),blockBegin(),blockEnd());
|
exporter.exportRange(document(),blockBegin(),blockEnd());
|
||||||
|
|
||||||
//clipboard takes the owner ship
|
//clipboard takes the owner ship
|
||||||
QMimeData * mimeData = new QMimeData;
|
QMimeData * mimeData = new QMimeData;
|
||||||
|
@ -2956,43 +2956,52 @@ void Editor::print()
|
||||||
dialog.setWindowTitle(tr("Print Document"));
|
dialog.setWindowTitle(tr("Print Document"));
|
||||||
dialog.setOption(QAbstractPrintDialog::PrintCurrentPage,false);
|
dialog.setOption(QAbstractPrintDialog::PrintCurrentPage,false);
|
||||||
dialog.setOption(QAbstractPrintDialog::PrintPageRange,false);
|
dialog.setOption(QAbstractPrintDialog::PrintPageRange,false);
|
||||||
|
|
||||||
if (selAvail())
|
if (selAvail())
|
||||||
dialog.setOption(QAbstractPrintDialog::PrintSelection);
|
dialog.setOption(QAbstractPrintDialog::PrintSelection,true);
|
||||||
|
|
||||||
if (dialog.exec() != QDialog::Accepted) {
|
if (dialog.exec() != QDialog::Accepted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QTextDocument doc;
|
|
||||||
QStringList lst;
|
QSynedit::QtSupportedHtmlExporter exporter(tabWidth(), pCharsetInfoManager->getDefaultSystemEncoding());
|
||||||
|
|
||||||
|
exporter.setTitle(QFileInfo(mFilename).fileName());
|
||||||
|
exporter.setUseBackground(pSettings->editor().copyHTMLUseBackground());
|
||||||
|
|
||||||
|
exporter.setFont(font());
|
||||||
|
QSynedit::PSyntaxer hl = syntaxer();
|
||||||
|
if (!pSettings->editor().copyHTMLUseEditorColor()) {
|
||||||
|
hl = syntaxerManager.copy(syntaxer());
|
||||||
|
syntaxerManager.applyColorScheme(hl,pSettings->editor().copyHTMLColorScheme());
|
||||||
|
}
|
||||||
|
exporter.setSyntaxer(hl);
|
||||||
|
exporter.setOnFormatToken(std::bind(&Editor::onExportedFormatToken,
|
||||||
|
this,
|
||||||
|
std::placeholders::_1,
|
||||||
|
std::placeholders::_2,
|
||||||
|
std::placeholders::_3,
|
||||||
|
std::placeholders::_4,
|
||||||
|
std::placeholders::_5
|
||||||
|
));
|
||||||
|
|
||||||
if (dialog.testOption(QAbstractPrintDialog::PrintSelection))
|
if (dialog.testOption(QAbstractPrintDialog::PrintSelection))
|
||||||
lst = textToLines(selText());
|
exporter.exportRange(document(),blockBegin(),blockEnd());
|
||||||
else
|
else
|
||||||
lst = contents();
|
exporter.exportAll(document());
|
||||||
for (int i=0;i<lst.length();i++) {
|
|
||||||
int columns = 0;
|
QString html = exporter.text();
|
||||||
QString line = lst[i];
|
QTextDocument doc;
|
||||||
QString newLine;
|
|
||||||
for (QChar ch:line) {
|
|
||||||
if (ch=='\t') {
|
|
||||||
int charCol = tabWidth() - (columns % tabWidth());
|
|
||||||
newLine += QString(charCol,' ');
|
|
||||||
columns += charCol;
|
|
||||||
} else {
|
|
||||||
newLine+=ch;
|
|
||||||
columns+=charColumns(ch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lst[i]=newLine;
|
|
||||||
}
|
|
||||||
doc.setDefaultFont(font());
|
doc.setDefaultFont(font());
|
||||||
doc.setPlainText(lst.join(lineBreak()));
|
doc.setHtml(html);
|
||||||
doc.print(&printer);
|
doc.print(&printer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::exportAsRTF(const QString &rtfFilename)
|
void Editor::exportAsRTF(const QString &rtfFilename)
|
||||||
{
|
{
|
||||||
QSynedit::SynRTFExporter exporter(pCharsetInfoManager->getDefaultSystemEncoding());
|
QSynedit::RTFExporter exporter(tabWidth(), pCharsetInfoManager->getDefaultSystemEncoding());
|
||||||
exporter.setTitle(extractFileName(rtfFilename));
|
exporter.setTitle(extractFileName(rtfFilename));
|
||||||
exporter.setExportAsText(true);
|
|
||||||
exporter.setUseBackground(pSettings->editor().copyRTFUseBackground());
|
exporter.setUseBackground(pSettings->editor().copyRTFUseBackground());
|
||||||
exporter.setFont(font());
|
exporter.setFont(font());
|
||||||
QSynedit::PSyntaxer hl = syntaxer();
|
QSynedit::PSyntaxer hl = syntaxer();
|
||||||
|
@ -3009,15 +3018,14 @@ void Editor::exportAsRTF(const QString &rtfFilename)
|
||||||
std::placeholders::_4,
|
std::placeholders::_4,
|
||||||
std::placeholders::_5
|
std::placeholders::_5
|
||||||
));
|
));
|
||||||
exporter.ExportAll(document());
|
exporter.exportAll(document());
|
||||||
exporter.SaveToFile(rtfFilename);
|
exporter.saveToFile(rtfFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::exportAsHTML(const QString &htmlFilename)
|
void Editor::exportAsHTML(const QString &htmlFilename)
|
||||||
{
|
{
|
||||||
QSynedit::SynHTMLExporter exporter(tabWidth(), pCharsetInfoManager->getDefaultSystemEncoding());
|
QSynedit::HTMLExporter exporter(tabWidth(), pCharsetInfoManager->getDefaultSystemEncoding());
|
||||||
exporter.setTitle(extractFileName(htmlFilename));
|
exporter.setTitle(extractFileName(htmlFilename));
|
||||||
exporter.setExportAsText(false);
|
|
||||||
exporter.setUseBackground(pSettings->editor().copyHTMLUseBackground());
|
exporter.setUseBackground(pSettings->editor().copyHTMLUseBackground());
|
||||||
exporter.setFont(font());
|
exporter.setFont(font());
|
||||||
QSynedit::PSyntaxer hl = syntaxer();
|
QSynedit::PSyntaxer hl = syntaxer();
|
||||||
|
@ -3034,8 +3042,8 @@ void Editor::exportAsHTML(const QString &htmlFilename)
|
||||||
std::placeholders::_4,
|
std::placeholders::_4,
|
||||||
std::placeholders::_5
|
std::placeholders::_5
|
||||||
));
|
));
|
||||||
exporter.ExportAll(document());
|
exporter.exportAll(document());
|
||||||
exporter.SaveToFile(htmlFilename);
|
exporter.saveToFile(htmlFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Editor::showCompletion(const QString& preWord,bool autoComplete, CodeCompletionType type)
|
void Editor::showCompletion(const QString& preWord,bool autoComplete, CodeCompletionType type)
|
||||||
|
|
|
@ -27,9 +27,10 @@ SOURCES += qsynedit/CodeFolding.cpp \
|
||||||
qsynedit/SynEdit.cpp \
|
qsynedit/SynEdit.cpp \
|
||||||
qsynedit/TextBuffer.cpp \
|
qsynedit/TextBuffer.cpp \
|
||||||
qsynedit/TextPainter.cpp \
|
qsynedit/TextPainter.cpp \
|
||||||
qsynedit/exporter/synexporter.cpp \
|
qsynedit/exporter/exporter.cpp \
|
||||||
qsynedit/exporter/synhtmlexporter.cpp \
|
qsynedit/exporter/htmlexporter.cpp \
|
||||||
qsynedit/exporter/synrtfexporter.cpp \
|
qsynedit/exporter/qtsupportedhtmlexporter.cpp \
|
||||||
|
qsynedit/exporter/rtfexporter.cpp \
|
||||||
qsynedit/syntaxer/asm.cpp \
|
qsynedit/syntaxer/asm.cpp \
|
||||||
qsynedit/syntaxer/cpp.cpp \
|
qsynedit/syntaxer/cpp.cpp \
|
||||||
qsynedit/syntaxer/customhighlighterv1.cpp \
|
qsynedit/syntaxer/customhighlighterv1.cpp \
|
||||||
|
@ -53,9 +54,10 @@ HEADERS += qsynedit/Search.h \
|
||||||
qsynedit/TextBuffer.h \
|
qsynedit/TextBuffer.h \
|
||||||
qsynedit/TextPainter.h \
|
qsynedit/TextPainter.h \
|
||||||
qsynedit/Types.h \
|
qsynedit/Types.h \
|
||||||
qsynedit/exporter/synexporter.h \
|
qsynedit/exporter/exporter.h \
|
||||||
qsynedit/exporter/synhtmlexporter.h \
|
qsynedit/exporter/htmlexporter.h \
|
||||||
qsynedit/exporter/synrtfexporter.h \
|
qsynedit/exporter/qtsupportedhtmlexporter.h \
|
||||||
|
qsynedit/exporter/rtfexporter.h \
|
||||||
qsynedit/syntaxer/asm.h \
|
qsynedit/syntaxer/asm.h \
|
||||||
qsynedit/syntaxer/cpp.h \
|
qsynedit/syntaxer/cpp.h \
|
||||||
qsynedit/syntaxer/customhighlighterv1.h \
|
qsynedit/syntaxer/customhighlighterv1.h \
|
||||||
|
|
|
@ -0,0 +1,378 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include "exporter.h"
|
||||||
|
|
||||||
|
#include <QClipboard>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QGuiApplication>
|
||||||
|
#include <QMimeData>
|
||||||
|
#include <QTextCodec>
|
||||||
|
|
||||||
|
namespace QSynedit {
|
||||||
|
|
||||||
|
Exporter::Exporter(int tabSize, const QByteArray charset):
|
||||||
|
mTabSize(tabSize),
|
||||||
|
mCharset(charset)
|
||||||
|
{
|
||||||
|
mFont = QGuiApplication::font();
|
||||||
|
mBackgroundColor = QGuiApplication::palette().color(QPalette::Base);
|
||||||
|
mForegroundColor = QGuiApplication::palette().color(QPalette::Text);
|
||||||
|
mUseBackground = false;
|
||||||
|
mFileEndingType = NewlineType::Windows;
|
||||||
|
clear();
|
||||||
|
setTitle("");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Exporter::clear()
|
||||||
|
{
|
||||||
|
mText.clear();
|
||||||
|
mLastStyle = FontStyle::fsNone;
|
||||||
|
mLastBG = QGuiApplication::palette().color(QPalette::Base);
|
||||||
|
mLastFG = QGuiApplication::palette().color(QPalette::Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Exporter::exportAll(const PDocument& doc)
|
||||||
|
{
|
||||||
|
exportRange(doc, BufferCoord{1, 1}, BufferCoord{INT_MAX, INT_MAX});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Exporter::exportRange(const PDocument& doc, BufferCoord start, BufferCoord stop)
|
||||||
|
{
|
||||||
|
// abort if not all necessary conditions are met
|
||||||
|
if (!doc || !mSyntaxer || (doc->count() == 0))
|
||||||
|
return;
|
||||||
|
stop.line = std::max(1, std::min(stop.line, doc->count()));
|
||||||
|
stop.ch = std::max(1, std::min(stop.ch, doc->getString(stop.line - 1).length() + 1));
|
||||||
|
start.line = std::max(1, std::min(start.line, doc->count()));
|
||||||
|
start.ch = std::max(1, std::min(start.ch, doc->getString(start.line - 1).length() + 1));
|
||||||
|
if ( (start.line > doc->count()) || (start.line > stop.line) )
|
||||||
|
return;
|
||||||
|
if ((start.line == stop.line) && (start.ch >= stop.ch))
|
||||||
|
return;
|
||||||
|
// initialization
|
||||||
|
mText.clear();
|
||||||
|
// export all the lines into fBuffer
|
||||||
|
mFirstAttribute = true;
|
||||||
|
|
||||||
|
if (start.line == 1)
|
||||||
|
mSyntaxer->resetState();
|
||||||
|
else
|
||||||
|
mSyntaxer->setState(doc->ranges(start.line-2));
|
||||||
|
for (int i = start.line; i<=stop.line; i++) {
|
||||||
|
QString Line = doc->getString(i-1);
|
||||||
|
// order is important, since Start.Y might be equal to Stop.Y
|
||||||
|
// if (i == Stop.Line)
|
||||||
|
// Line.remove(Stop.Char-1, INT_MAX);
|
||||||
|
// if ( (i = Start.Line) && (Start.Char > 1))
|
||||||
|
// Line.remove(0, Start.Char - 1);
|
||||||
|
// export the line
|
||||||
|
mSyntaxer->setLine(Line, i);
|
||||||
|
while (!mSyntaxer->eol()) {
|
||||||
|
PTokenAttribute attri = mSyntaxer->getTokenAttribute();
|
||||||
|
int startPos = mSyntaxer->getTokenPos();
|
||||||
|
QString token = mSyntaxer->getToken();
|
||||||
|
if (i==start.line && (startPos+token.length() < start.ch)) {
|
||||||
|
mSyntaxer->next();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (i==stop.line && (startPos >= stop.ch-1)) {
|
||||||
|
mSyntaxer->next();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (i==stop.line && (startPos+token.length() > stop.ch)) {
|
||||||
|
token = token.remove(stop.ch - startPos - 1);
|
||||||
|
}
|
||||||
|
if (i==start.line && startPos < start.ch-1) {
|
||||||
|
token = token.mid(start.ch-1-startPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Token = replaceReservedChars(token);
|
||||||
|
if (mOnFormatToken)
|
||||||
|
mOnFormatToken(mSyntaxer, i, mSyntaxer->getTokenPos()+1, mSyntaxer->getToken(),attri);
|
||||||
|
setTokenAttribute(attri);
|
||||||
|
formatToken(Token);
|
||||||
|
mSyntaxer->next();
|
||||||
|
}
|
||||||
|
if (i!=stop.line)
|
||||||
|
formatNewLine();
|
||||||
|
}
|
||||||
|
if (!mFirstAttribute)
|
||||||
|
formatAfterLastAttribute();
|
||||||
|
// insert header
|
||||||
|
insertData(0, getHeader());
|
||||||
|
// add footer
|
||||||
|
addData(getFooter());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Exporter::saveToFile(const QString &filename)
|
||||||
|
{
|
||||||
|
QFile file(filename);
|
||||||
|
if (file.open(QIODevice::WriteOnly)) {
|
||||||
|
writeToStream(file);
|
||||||
|
} else {
|
||||||
|
throw FileError(QObject::tr("Can't open file '%1' to write!").arg(filename));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Exporter::writeToStream(QIODevice &stream)
|
||||||
|
{
|
||||||
|
QTextCodec *codec=getCodec();
|
||||||
|
if (stream.write(codec->fromUnicode(mText))<0) {
|
||||||
|
throw FileError(QObject::tr("Failed to write data."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QFont Exporter::font() const
|
||||||
|
{
|
||||||
|
return mFont;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Exporter::setFont(const QFont &font)
|
||||||
|
{
|
||||||
|
mFont = font;
|
||||||
|
}
|
||||||
|
|
||||||
|
PSyntaxer Exporter::syntaxer() const
|
||||||
|
{
|
||||||
|
return mSyntaxer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Exporter::setSyntaxer(PSyntaxer value)
|
||||||
|
{
|
||||||
|
if (mSyntaxer != value) {
|
||||||
|
mSyntaxer = value;
|
||||||
|
clear();
|
||||||
|
if ((mSyntaxer) && (mSyntaxer->whitespaceAttribute()) && mUseBackground)
|
||||||
|
mBackgroundColor = mSyntaxer->whitespaceAttribute()->background();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Exporter::title() const
|
||||||
|
{
|
||||||
|
return mTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Exporter::setTitle(const QString &Value)
|
||||||
|
{
|
||||||
|
if (mTitle != Value) {
|
||||||
|
if (!Value.isEmpty())
|
||||||
|
mTitle = Value;
|
||||||
|
else
|
||||||
|
mTitle = "Untitled";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Exporter::useBackground() const
|
||||||
|
{
|
||||||
|
return mUseBackground;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Exporter::setUseBackground(bool Value)
|
||||||
|
{
|
||||||
|
if (mUseBackground != Value) {
|
||||||
|
mUseBackground = Value;
|
||||||
|
clear();
|
||||||
|
if ((mSyntaxer) && (mSyntaxer->whitespaceAttribute()) && mUseBackground)
|
||||||
|
mBackgroundColor = mSyntaxer->whitespaceAttribute()->background();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NewlineType Exporter::fileEndingType() const
|
||||||
|
{
|
||||||
|
return mFileEndingType;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Exporter::setFileEndingType(const NewlineType &fileEndingType)
|
||||||
|
{
|
||||||
|
mFileEndingType = fileEndingType;
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor Exporter::foregroundColor() const
|
||||||
|
{
|
||||||
|
return mForegroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Exporter::setForegroundColor(const QColor &value)
|
||||||
|
{
|
||||||
|
if (mForegroundColor != value) {
|
||||||
|
mForegroundColor = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor Exporter::backgroundColor() const
|
||||||
|
{
|
||||||
|
return mBackgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Exporter::setBackgroundColor(const QColor &value)
|
||||||
|
{
|
||||||
|
if (mBackgroundColor != value) {
|
||||||
|
mBackgroundColor = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray Exporter::charset() const
|
||||||
|
{
|
||||||
|
return mCharset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Exporter::setCharset(const QByteArray &charset)
|
||||||
|
{
|
||||||
|
mCharset = charset;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Exporter::defaultFilter() const
|
||||||
|
{
|
||||||
|
return mDefaultFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Exporter::setDefaultFilter(const QString &defaultFilter)
|
||||||
|
{
|
||||||
|
mDefaultFilter = defaultFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Exporter::addData(const QString &text)
|
||||||
|
{
|
||||||
|
if (!text.isEmpty()) {
|
||||||
|
mText.append(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Exporter::addDataNewLine(const QString &text)
|
||||||
|
{
|
||||||
|
addData(text);
|
||||||
|
addNewLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Exporter::addNewLine()
|
||||||
|
{
|
||||||
|
addData(lineBreak());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Exporter::formatToken(const QString &token)
|
||||||
|
{
|
||||||
|
addData(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Exporter::getBufferSize() const
|
||||||
|
{
|
||||||
|
return mText.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextCodec * Exporter::getCodec() const {
|
||||||
|
QTextCodec* codec = QTextCodec::codecForName(mCharset);
|
||||||
|
if (codec == nullptr)
|
||||||
|
codec = QTextCodec::codecForLocale();
|
||||||
|
return codec;
|
||||||
|
}
|
||||||
|
void Exporter::insertData(int pos, const QString &text)
|
||||||
|
{
|
||||||
|
if (!text.isEmpty()) {
|
||||||
|
mText.insert(pos,text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Exporter::replaceReservedChars(const QString &token)
|
||||||
|
{
|
||||||
|
if (token.isEmpty())
|
||||||
|
return "";
|
||||||
|
QString result;
|
||||||
|
for (QChar ch:token) {
|
||||||
|
if (mReplaceReserved.contains(ch)) {
|
||||||
|
result += mReplaceReserved[ch];
|
||||||
|
} else {
|
||||||
|
result += ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QColor ValidatedColor(const QColor& color, const QColor& defaultColor) {
|
||||||
|
if (color.isValid())
|
||||||
|
return color;
|
||||||
|
else
|
||||||
|
return defaultColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Exporter::setTokenAttribute(PTokenAttribute attri)
|
||||||
|
{
|
||||||
|
if (mFirstAttribute) {
|
||||||
|
mFirstAttribute = false;
|
||||||
|
mLastBG = ValidatedColor(attri->background(), mBackgroundColor);
|
||||||
|
mLastFG = ValidatedColor(attri->foreground(), mForegroundColor);
|
||||||
|
mLastStyle = attri->styles();
|
||||||
|
formatBeforeFirstAttribute(
|
||||||
|
mUseBackground && (mLastBG != mBackgroundColor),
|
||||||
|
mLastFG != mForegroundColor, attri->styles());
|
||||||
|
} else {
|
||||||
|
bool ChangedBG = mUseBackground &&
|
||||||
|
(mLastBG != ValidatedColor(attri->background(), mBackgroundColor));
|
||||||
|
bool ChangedFG = (mLastFG != ValidatedColor(attri->foreground(), mForegroundColor));
|
||||||
|
if (ChangedBG || ChangedFG || (mLastStyle != attri->styles())) {
|
||||||
|
// which font style bits are to reset?
|
||||||
|
FontStyles ChangedStyles = mLastStyle & ~(attri->styles());
|
||||||
|
formatAttributeDone(ChangedBG, ChangedFG, ChangedStyles);
|
||||||
|
// which font style bits are to set?
|
||||||
|
ChangedStyles = attri->styles() & ~(mLastStyle);
|
||||||
|
mLastBG = ValidatedColor(attri->background(), mBackgroundColor);
|
||||||
|
mLastFG = ValidatedColor(attri->foreground(), mForegroundColor);
|
||||||
|
mLastStyle = attri->styles();
|
||||||
|
formatAttributeInit(ChangedBG, ChangedFG, ChangedStyles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray Exporter::buffer() const
|
||||||
|
{
|
||||||
|
QTextCodec* codec = getCodec();
|
||||||
|
return codec->fromUnicode(mText);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString &Exporter::text() const
|
||||||
|
{
|
||||||
|
return mText;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray Exporter::clipboardFormat()
|
||||||
|
{
|
||||||
|
return mClipboardFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
FormatTokenHandler Exporter::onFormatToken() const
|
||||||
|
{
|
||||||
|
return mOnFormatToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Exporter::setOnFormatToken(const FormatTokenHandler &onFormatToken)
|
||||||
|
{
|
||||||
|
mOnFormatToken = onFormatToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Exporter::lineBreak()
|
||||||
|
{
|
||||||
|
switch(mFileEndingType) {
|
||||||
|
case NewlineType::Unix:
|
||||||
|
return "\n";
|
||||||
|
case NewlineType::Windows:
|
||||||
|
return "\r\n";
|
||||||
|
case NewlineType::MacOld:
|
||||||
|
return "\r";
|
||||||
|
}
|
||||||
|
return "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -14,8 +14,8 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#ifndef SYNEXPORTER_H
|
#ifndef EXPORTER_H
|
||||||
#define SYNEXPORTER_H
|
#define EXPORTER_H
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include "../SynEdit.h"
|
#include "../SynEdit.h"
|
||||||
|
@ -23,48 +23,41 @@
|
||||||
namespace QSynedit {
|
namespace QSynedit {
|
||||||
using FormatTokenHandler = std::function<void(PSyntaxer syntaxHighlighter, int line, int column, const QString& token,
|
using FormatTokenHandler = std::function<void(PSyntaxer syntaxHighlighter, int line, int column, const QString& token,
|
||||||
PTokenAttribute& attr)>;
|
PTokenAttribute& attr)>;
|
||||||
class SynExporter
|
class Exporter
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit SynExporter(const QByteArray charset);
|
explicit Exporter(int tabSize, const QByteArray charset);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Clears the output buffer and any internal data that relates to the last
|
* @brief Clears the output buffer and any internal data that relates to the last
|
||||||
* exported text.
|
* exported text.
|
||||||
*/
|
*/
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
/**
|
|
||||||
* @brief Copies the output buffer contents to the clipboard, as the native format
|
|
||||||
* or as text depending on the ExportAsText property.
|
|
||||||
*/
|
|
||||||
void CopyToClipboard();
|
|
||||||
/**
|
/**
|
||||||
* @brief Exports everything in the strings parameter to the output buffer.
|
* @brief Exports everything in the strings parameter to the output buffer.
|
||||||
* @param ALines
|
* @param doc
|
||||||
*/
|
*/
|
||||||
void ExportAll(PDocument ALines);
|
void exportAll(const PDocument& doc);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Exports the given range of the strings parameter to the output buffer.
|
* @brief Exports the given range of the strings parameter to the output buffer.
|
||||||
* @param ALines
|
* @param doc
|
||||||
* @param Start
|
* @param start
|
||||||
* @param Stop
|
* @param stop
|
||||||
*/
|
*/
|
||||||
void ExportRange(PDocument ALines,
|
void exportRange(const PDocument& doc,
|
||||||
BufferCoord Start, BufferCoord Stop);
|
BufferCoord start, BufferCoord stop);
|
||||||
/**
|
/**
|
||||||
* @brief Saves the contents of the output buffer to a file.
|
* @brief Saves the contents of the output buffer to a file.
|
||||||
* @param AFileName
|
* @param AFileName
|
||||||
*/
|
*/
|
||||||
void SaveToFile(const QString& AFileName);
|
void saveToFile(const QString& filename);
|
||||||
/**
|
/**
|
||||||
* @brief Saves the contents of the output buffer to a stream.
|
* @brief Saves the contents of the output buffer to a stream.
|
||||||
* @param AStream
|
* @param stream
|
||||||
*/
|
*/
|
||||||
void SaveToStream(QIODevice& AStream);
|
void writeToStream(QIODevice& stream);
|
||||||
bool exportAsText() const;
|
|
||||||
void setExportAsText(bool Value);
|
|
||||||
|
|
||||||
QFont font() const;
|
QFont font() const;
|
||||||
void setFont(const QFont &font);
|
void setFont(const QFont &font);
|
||||||
|
@ -85,7 +78,7 @@ public:
|
||||||
* @brief The clipboard format the exporter creates as native format.
|
* @brief The clipboard format the exporter creates as native format.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual QByteArray clipboardFormat();
|
QByteArray clipboardFormat();
|
||||||
|
|
||||||
QColor foregroundColor() const;
|
QColor foregroundColor() const;
|
||||||
void setForegroundColor(const QColor &value);
|
void setForegroundColor(const QColor &value);
|
||||||
|
@ -102,15 +95,16 @@ public:
|
||||||
FormatTokenHandler onFormatToken() const;
|
FormatTokenHandler onFormatToken() const;
|
||||||
void setOnFormatToken(const FormatTokenHandler &onFormatToken);
|
void setOnFormatToken(const FormatTokenHandler &onFormatToken);
|
||||||
|
|
||||||
const QByteArray& buffer() const;
|
QByteArray buffer() const;
|
||||||
|
const QString& text() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
int mTabSize;
|
||||||
|
QByteArray mClipboardFormat;
|
||||||
QByteArray mCharset;
|
QByteArray mCharset;
|
||||||
QColor mBackgroundColor;
|
QColor mBackgroundColor;
|
||||||
QColor mForegroundColor;
|
QColor mForegroundColor;
|
||||||
QByteArray mClipboardFormat;
|
|
||||||
QString mDefaultFilter;
|
QString mDefaultFilter;
|
||||||
bool mExportAsText;
|
|
||||||
QFont mFont;
|
QFont mFont;
|
||||||
PSyntaxer mSyntaxer;
|
PSyntaxer mSyntaxer;
|
||||||
QColor mLastBG;
|
QColor mLastBG;
|
||||||
|
@ -125,126 +119,119 @@ protected:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Adds a string to the output buffer.
|
* @brief Adds a string to the output buffer.
|
||||||
* @param AText
|
* @param text
|
||||||
*/
|
*/
|
||||||
void AddData(const QString& AText);
|
void addData(const QString& text);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Adds a string and a trailing newline to the output buffer.
|
* @brief Adds a string and a trailing newline to the output buffer.
|
||||||
* @param AText
|
* @param text
|
||||||
*/
|
*/
|
||||||
void AddDataNewLine(const QString& AText);
|
void addDataNewLine(const QString& text);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Adds a newline to the output buffer.
|
* @brief Adds a newline to the output buffer.
|
||||||
*/
|
*/
|
||||||
void AddNewLine();
|
void addNewLine();
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Copies the data under this format to the clipboard. The clipboard has to
|
|
||||||
* be opened explicitly when more than one format is to be set.
|
|
||||||
*/
|
|
||||||
void CopyToClipboardFormat(QByteArray AFormat);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Has to be overridden in descendant classes to add the closing format
|
* @brief Has to be overridden in descendant classes to add the closing format
|
||||||
* strings to the output buffer. The parameters can be used to track what
|
* strings to the output buffer. The parameters can be used to track what
|
||||||
* changes are made for the next token.
|
* changes are made for the next token.
|
||||||
* @param BackgroundChanged
|
* @param backgroundChanged
|
||||||
* @param ForegroundChanged
|
* @param foregroundChanged
|
||||||
* @param FontStylesChanged
|
* @param fontStyles
|
||||||
*/
|
*/
|
||||||
virtual void FormatAttributeDone(bool BackgroundChanged, bool ForegroundChanged,
|
virtual void formatAttributeDone(bool backgroundChanged, bool foregroundChanged,
|
||||||
FontStyles FontStylesChanged) = 0;
|
FontStyles fontStyles) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Has to be overridden in descendant classes to add the opening format
|
* @brief Has to be overridden in descendant classes to add the opening format
|
||||||
* strings to the output buffer. The parameters can be used to track what
|
* strings to the output buffer. The parameters can be used to track what
|
||||||
* changes have been made in respect to the previous token.
|
* changes have been made in respect to the previous token.
|
||||||
* @param BackgroundChanged
|
* @param backgroundChanged
|
||||||
* @param ForegroundChanged
|
* @param foregroundChanged
|
||||||
* @param FontStylesChanged
|
* @param fontStyles
|
||||||
*/
|
*/
|
||||||
virtual void FormatAttributeInit(bool BackgroundChanged, bool ForegroundChanged,
|
virtual void formatAttributeInit(bool backgroundChanged, bool foregroundChanged,
|
||||||
FontStyles FontStylesChanged) = 0;
|
FontStyles fontStyles) = 0;
|
||||||
/**
|
/**
|
||||||
* @brief Has to be overridden in descendant classes to add the closing format
|
* @brief Has to be overridden in descendant classes to add the closing format
|
||||||
* strings to the output buffer after the last token has been written.
|
* strings to the output buffer after the last token has been written.
|
||||||
*/
|
*/
|
||||||
virtual void FormatAfterLastAttribute() = 0;
|
virtual void formatAfterLastAttribute() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Has to be overridden in descendant classes to add the opening format
|
* @brief Has to be overridden in descendant classes to add the opening format
|
||||||
* strings to the output buffer when the first token is about to be written.
|
* strings to the output buffer when the first token is about to be written.
|
||||||
* @param BackgroundChanged
|
* @param backgroundChanged
|
||||||
* @param ForegroundChanged
|
* @param foregroundChanged
|
||||||
* @param FontStylesChanged
|
* @param fontStyles
|
||||||
*/
|
*/
|
||||||
virtual void FormatBeforeFirstAttribute(bool BackgroundChanged, bool ForegroundChanged,
|
virtual void formatBeforeFirstAttribute(bool backgroundChanged, bool foregroundChanged,
|
||||||
FontStyles FontStylesChanged) = 0;
|
FontStyles fontStyles) = 0;
|
||||||
/**
|
/**
|
||||||
* @brief Can be overridden in descendant classes to add the formatted text of
|
* @brief Can be overridden in descendant classes to add the formatted text of
|
||||||
* the actual token text to the output buffer.
|
* the actual token text to the output buffer.
|
||||||
*/
|
*/
|
||||||
virtual void FormatToken(const QString& Token) ;
|
virtual void formatToken(const QString& token) ;
|
||||||
/**
|
/**
|
||||||
* @brief Has to be overridden in descendant classes to add a newline in the output
|
* @brief Has to be overridden in descendant classes to add a newline in the output
|
||||||
* format to the output buffer.
|
* format to the output buffer.
|
||||||
*/
|
*/
|
||||||
virtual void FormatNewLine() = 0;
|
virtual void formatNewLine() = 0;
|
||||||
/**
|
/**
|
||||||
* @brief Returns the size of the formatted text in the output buffer, to be used
|
* @brief Returns the size of the formatted text in the output buffer, to be used
|
||||||
* in the format header or footer.
|
* in the format header or footer.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
int GetBufferSize();
|
int getBufferSize() const;
|
||||||
/**
|
/**
|
||||||
* @brief Has to be overridden in descendant classes to return the correct output
|
* @brief Has to be overridden in descendant classes to return the correct output
|
||||||
* format footer.
|
* format footer.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual QString GetFooter() = 0;
|
virtual QString getFooter() = 0;
|
||||||
/**
|
/**
|
||||||
* @brief Has to be overridden in descendant classes to return the name of the
|
* @brief Has to be overridden in descendant classes to return the name of the
|
||||||
* output format.
|
* output format.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual QString GetFormatName() = 0;
|
virtual QString getFormatName() = 0;
|
||||||
/**
|
/**
|
||||||
* @brief Has to be overridden in descendant classes to return the correct output
|
* @brief Has to be overridden in descendant classes to return the correct output
|
||||||
* format header.
|
* format header.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual QString GetHeader() = 0;
|
virtual QString getHeader() = 0;
|
||||||
/**
|
/**
|
||||||
* @brief Inserts a data block at the given position into the output buffer. Is
|
* @brief Inserts a data block at the given position into the output buffer. Is
|
||||||
* used to insert the format header after the exporting, since some header
|
* used to insert the format header after the exporting, since some header
|
||||||
* data may be known only after the conversion is done.
|
* data may be known only after the conversion is done.
|
||||||
* @param APos
|
* @param pos
|
||||||
* @param AText
|
* @param text
|
||||||
*/
|
*/
|
||||||
void InsertData(int APos, const QString& AText);
|
void insertData(int pos, const QString& text);
|
||||||
/**
|
/**
|
||||||
* @brief Returns a string that has all the invalid chars of the output format
|
* @brief Returns a string that has all the invalid chars of the output format
|
||||||
* replaced with the entries in the replacement array.
|
* replaced with the entries in the replacement array.
|
||||||
*/
|
*/
|
||||||
QString ReplaceReservedChars(const QString &AToken);
|
QString replaceReservedChars(const QString &token);
|
||||||
/**
|
/**
|
||||||
* @brief Sets the token attribute of the next token to determine the changes
|
* @brief Sets the token attribute of the next token to determine the changes
|
||||||
* of colors and font styles so the properties of the next token can be
|
* of colors and font styles so the properties of the next token can be
|
||||||
* added to the output buffer.
|
* added to the output buffer.
|
||||||
* @param Attri
|
* @param attri
|
||||||
*/
|
*/
|
||||||
virtual void SetTokenAttribute(PTokenAttribute Attri);
|
virtual void setTokenAttribute(PTokenAttribute attri);
|
||||||
|
|
||||||
QTextCodec *getCodec();
|
QTextCodec *getCodec() const;
|
||||||
private:
|
private:
|
||||||
QByteArray mBuffer;
|
QString mText;
|
||||||
bool mFirstAttribute;
|
bool mFirstAttribute;
|
||||||
FormatTokenHandler mOnFormatToken;
|
FormatTokenHandler mOnFormatToken;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // SYNEXPORTER_H
|
#endif // EXPORTER_H
|
|
@ -14,14 +14,14 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#include "synhtmlexporter.h"
|
#include "htmlexporter.h"
|
||||||
#include "../MiscProcs.h"
|
#include "../MiscProcs.h"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
namespace QSynedit {
|
namespace QSynedit {
|
||||||
|
|
||||||
SynHTMLExporter::SynHTMLExporter(int tabSize,const QByteArray charset):
|
HTMLExporter::HTMLExporter(int tabSize,const QByteArray charset):
|
||||||
SynExporter(charset)
|
Exporter(tabSize,charset)
|
||||||
{
|
{
|
||||||
mClipboardFormat = "text/html";
|
mClipboardFormat = "text/html";
|
||||||
mDefaultFilter = "HTML Documents (*.htm;*.html)|*.htm;*.html";
|
mDefaultFilter = "HTML Documents (*.htm;*.html)|*.htm;*.html";
|
||||||
|
@ -35,139 +35,139 @@ SynHTMLExporter::SynHTMLExporter(int tabSize,const QByteArray charset):
|
||||||
mCreateHTMLFragment = false;
|
mCreateHTMLFragment = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SynHTMLExporter::createHTMLFragment() const
|
bool HTMLExporter::createHTMLFragment() const
|
||||||
{
|
{
|
||||||
return mCreateHTMLFragment;
|
return mCreateHTMLFragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SynHTMLExporter::setCreateHTMLFragment(bool createHTMLFragment)
|
void HTMLExporter::setCreateHTMLFragment(bool createHTMLFragment)
|
||||||
{
|
{
|
||||||
mCreateHTMLFragment = createHTMLFragment;
|
mCreateHTMLFragment = createHTMLFragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SynHTMLExporter::AttriToCSS(PTokenAttribute Attri, const QString &UniqueAttriName)
|
QString HTMLExporter::attriToCSS(PTokenAttribute attri, const QString &uniqueAttriName)
|
||||||
{
|
{
|
||||||
QString StyleName = MakeValidName(UniqueAttriName);
|
QString styleName = makeValidName(uniqueAttriName);
|
||||||
|
|
||||||
QString Result = "." + StyleName + " { ";
|
QString result = "." + styleName + " { ";
|
||||||
if (mUseBackground && Attri->background().isValid())
|
if (mUseBackground && attri->background().isValid())
|
||||||
Result += "background-color: " + ColorToHTML(Attri->background()) + "; ";
|
result += "background-color: " + colorToHTML(attri->background()) + "; ";
|
||||||
if (Attri->foreground().isValid())
|
if (attri->foreground().isValid())
|
||||||
Result += "color: " + ColorToHTML(Attri->foreground()) + "; ";
|
result += "color: " + colorToHTML(attri->foreground()) + "; ";
|
||||||
|
|
||||||
if (Attri->styles().testFlag(FontStyle::fsBold))
|
if (attri->styles().testFlag(FontStyle::fsBold))
|
||||||
Result += "font-weight: bold; ";
|
result += "font-weight: bold; ";
|
||||||
if (Attri->styles().testFlag(FontStyle::fsItalic))
|
if (attri->styles().testFlag(FontStyle::fsItalic))
|
||||||
Result += "font-style: italic; ";
|
result += "font-style: italic; ";
|
||||||
if (Attri->styles().testFlag(FontStyle::fsUnderline))
|
if (attri->styles().testFlag(FontStyle::fsUnderline))
|
||||||
Result += "text-decoration: underline; ";
|
result += "text-decoration: underline; ";
|
||||||
if (Attri->styles().testFlag(FontStyle::fsStrikeOut))
|
if (attri->styles().testFlag(FontStyle::fsStrikeOut))
|
||||||
Result += "text-decoration: line-through; ";
|
result += "text-decoration: line-through; ";
|
||||||
Result += "}";
|
result += "}";
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SynHTMLExporter::AttriToCSSCallback(PSyntaxer , PTokenAttribute Attri, const QString& UniqueAttriName, QList<void *> params)
|
|
||||||
{
|
|
||||||
QString& styles = *static_cast<QString *>(params[0]);
|
|
||||||
styles.append(AttriToCSS(Attri,UniqueAttriName) + lineBreak());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SynHTMLExporter::ColorToHTML(const QColor &AColor)
|
|
||||||
{
|
|
||||||
return AColor.name();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SynHTMLExporter::GetStyleName(PSyntaxer Highlighter, PTokenAttribute Attri)
|
|
||||||
{
|
|
||||||
QString result;
|
|
||||||
enumTokenAttributes(Highlighter,false,
|
|
||||||
std::bind(
|
|
||||||
&SynHTMLExporter::StyleNameCallback,this,
|
|
||||||
std::placeholders::_1, std::placeholders::_2,
|
|
||||||
std::placeholders::_3, std::placeholders::_4),
|
|
||||||
{&Attri,&result});
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SynHTMLExporter::MakeValidName(const QString &Name)
|
bool HTMLExporter::attriToCSSCallback(PSyntaxer , PTokenAttribute attri, const QString& uniqueAttriName, QList<void *> params)
|
||||||
{
|
{
|
||||||
QString Result;
|
QString& styles = *static_cast<QString *>(params[0]);
|
||||||
for (QChar ch:Name) {
|
styles.append(attriToCSS(attri,uniqueAttriName) + lineBreak());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString HTMLExporter::colorToHTML(const QColor &color) const
|
||||||
|
{
|
||||||
|
return color.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString HTMLExporter::getStyleName(PSyntaxer syntaxer, PTokenAttribute attri)
|
||||||
|
{
|
||||||
|
QString result;
|
||||||
|
enumTokenAttributes(syntaxer,false,
|
||||||
|
std::bind(
|
||||||
|
&HTMLExporter::styleNameCallback,this,
|
||||||
|
std::placeholders::_1, std::placeholders::_2,
|
||||||
|
std::placeholders::_3, std::placeholders::_4),
|
||||||
|
{&attri,&result});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString HTMLExporter::makeValidName(const QString &name)
|
||||||
|
{
|
||||||
|
QString result;
|
||||||
|
for (QChar ch:name) {
|
||||||
ch = ch.toLower();
|
ch = ch.toLower();
|
||||||
if (ch == '.' || ch =='_')
|
if (ch == '.' || ch =='_')
|
||||||
Result += '-';
|
result += '-';
|
||||||
else if ((ch >='a' && ch <= 'z') || (ch>='0' && ch<='9') || (ch == '-'))
|
else if ((ch >='a' && ch <= 'z') || (ch>='0' && ch<='9') || (ch == '-'))
|
||||||
Result += ch;
|
result += ch;
|
||||||
}
|
}
|
||||||
return Result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SynHTMLExporter::StyleNameCallback(PSyntaxer /*Highlighter*/, PTokenAttribute Attri, const QString& UniqueAttriName, QList<void *> params)
|
bool HTMLExporter::styleNameCallback(PSyntaxer /*syntaxer*/, PTokenAttribute attri, const QString& uniqueAttriName, QList<void *> params)
|
||||||
{
|
{
|
||||||
PTokenAttribute& AttriToFind = *static_cast<PTokenAttribute*>(params[0]);
|
PTokenAttribute& attriToFind = *static_cast<PTokenAttribute*>(params[0]);
|
||||||
QString& StyleName = *static_cast<QString *>(params[1]);
|
QString& styleName = *static_cast<QString *>(params[1]);
|
||||||
|
|
||||||
if (Attri == AttriToFind) {
|
if (attri == attriToFind) {
|
||||||
StyleName.clear();
|
styleName.clear();
|
||||||
StyleName.append(MakeValidName(UniqueAttriName));
|
styleName.append(makeValidName(uniqueAttriName));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SynHTMLExporter::FormatAttributeDone(bool , bool , FontStyles )
|
void HTMLExporter::formatAttributeDone(bool , bool , FontStyles )
|
||||||
{
|
{
|
||||||
AddData("</span>");
|
addData("</span>");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SynHTMLExporter::FormatAttributeInit(bool , bool , FontStyles )
|
void HTMLExporter::formatAttributeInit(bool , bool , FontStyles )
|
||||||
{
|
{
|
||||||
QString StyleName = GetStyleName(mSyntaxer, mLastAttri);
|
QString styleName = getStyleName(mSyntaxer, mLastAttri);
|
||||||
AddData(QString("<span class=\"%1\">").arg(StyleName));
|
addData(QString("<span class=\"%1\">").arg(styleName));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SynHTMLExporter::FormatAfterLastAttribute()
|
void HTMLExporter::formatAfterLastAttribute()
|
||||||
{
|
{
|
||||||
AddData("</span>");
|
addData("</span>");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SynHTMLExporter::FormatBeforeFirstAttribute(bool, bool, FontStyles)
|
void HTMLExporter::formatBeforeFirstAttribute(bool, bool, FontStyles)
|
||||||
{
|
{
|
||||||
QString StyleName = GetStyleName(mSyntaxer, mLastAttri);
|
QString styleName = getStyleName(mSyntaxer, mLastAttri);
|
||||||
AddData(QString("<span class=\"%1\">").arg(StyleName));
|
addData(QString("<span class=\"%1\">").arg(styleName));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SynHTMLExporter::FormatNewLine()
|
void HTMLExporter::formatNewLine()
|
||||||
{
|
{
|
||||||
AddData("<br />");
|
addData("<br />");
|
||||||
AddNewLine();
|
addNewLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SynHTMLExporter::GetFooter()
|
QString HTMLExporter::getFooter()
|
||||||
{
|
{
|
||||||
QString Result = "";
|
QString result = "";
|
||||||
Result = "</span>" + lineBreak();
|
result = "</div>" + lineBreak();
|
||||||
if (mCreateHTMLFragment)
|
if (mCreateHTMLFragment)
|
||||||
Result += "<!--EndFragment-->";
|
result += "<!--EndFragment-->";
|
||||||
Result += "</body>"+lineBreak()+ "</html>";
|
result += "</body>"+lineBreak()+ "</html>";
|
||||||
return Result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SynHTMLExporter::GetFormatName()
|
QString HTMLExporter::getFormatName()
|
||||||
{
|
{
|
||||||
return "HTML";
|
return "HTML";
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SynHTMLExporter::GetHeader()
|
QString HTMLExporter::getHeader()
|
||||||
{
|
{
|
||||||
using namespace std::placeholders;
|
using namespace std::placeholders;
|
||||||
QString Styles;
|
QString styles;
|
||||||
enumTokenAttributes(mSyntaxer, true,
|
enumTokenAttributes(mSyntaxer, true,
|
||||||
std::bind(&SynHTMLExporter::AttriToCSSCallback,
|
std::bind(&HTMLExporter::attriToCSSCallback,
|
||||||
this, _1, _2, _3, _4),
|
this, _1, _2, _3, _4),
|
||||||
{&Styles});
|
{&styles});
|
||||||
|
|
||||||
QString HTMLAsTextHeader = "<?xml version=\"1.0\" encoding=\"%2\"?>"+lineBreak() +
|
QString HTMLAsTextHeader = "<?xml version=\"1.0\" encoding=\"%2\"?>"+lineBreak() +
|
||||||
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" + lineBreak() +
|
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" + lineBreak() +
|
||||||
|
@ -184,12 +184,12 @@ QString SynHTMLExporter::GetHeader()
|
||||||
"</style>" + lineBreak() +
|
"</style>" + lineBreak() +
|
||||||
"</head>" + lineBreak() +
|
"</head>" + lineBreak() +
|
||||||
"<body>" + lineBreak();
|
"<body>" + lineBreak();
|
||||||
QString Header = HTMLAsTextHeader
|
QString header = HTMLAsTextHeader
|
||||||
.arg(mTitle)
|
.arg(mTitle)
|
||||||
.arg(QString(mCharset))
|
.arg(QString(mCharset))
|
||||||
.arg(ColorToHTML(mForegroundColor))
|
.arg(colorToHTML(mForegroundColor))
|
||||||
.arg(ColorToHTML(mBackgroundColor))
|
.arg(colorToHTML(mBackgroundColor))
|
||||||
.arg(Styles);
|
.arg(styles);
|
||||||
if (mCreateHTMLFragment) {
|
if (mCreateHTMLFragment) {
|
||||||
HTMLAsTextHeader = "<?xml version=\"1.0\" encoding=\"%2\"?>"+lineBreak() +
|
HTMLAsTextHeader = "<?xml version=\"1.0\" encoding=\"%2\"?>"+lineBreak() +
|
||||||
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" + lineBreak() +
|
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" + lineBreak() +
|
||||||
|
@ -205,26 +205,26 @@ QString SynHTMLExporter::GetHeader()
|
||||||
"</style>" + lineBreak() +
|
"</style>" + lineBreak() +
|
||||||
"</head>" + lineBreak() +
|
"</head>" + lineBreak() +
|
||||||
"<body>" + lineBreak();
|
"<body>" + lineBreak();
|
||||||
Header = HTMLAsTextHeader
|
header = HTMLAsTextHeader
|
||||||
.arg(QString(mCharset))
|
.arg(QString(mCharset))
|
||||||
.arg(ColorToHTML(mForegroundColor))
|
.arg(colorToHTML(mForegroundColor))
|
||||||
.arg(ColorToHTML(mBackgroundColor))
|
.arg(colorToHTML(mBackgroundColor))
|
||||||
.arg(Styles);
|
.arg(styles);
|
||||||
}
|
}
|
||||||
QString Result = Header;
|
QString result = header;
|
||||||
if (mCreateHTMLFragment) {
|
if (mCreateHTMLFragment) {
|
||||||
Result += "<!--StartFragment-->";
|
result += "<!--StartFragment-->";
|
||||||
}
|
}
|
||||||
Result += QString("<span style=\"font: %1pt %2;\">")
|
result += QString("<div style=\"font: %1pt %2;\">")
|
||||||
.arg(pixelToPoint(mFont.pixelSize()))
|
.arg(pixelToPoint(mFont.pixelSize()))
|
||||||
.arg(mFont.family());
|
.arg(mFont.family());
|
||||||
|
|
||||||
return Result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SynHTMLExporter::SetTokenAttribute(PTokenAttribute Attri)
|
void HTMLExporter::setTokenAttribute(PTokenAttribute attri)
|
||||||
{
|
{
|
||||||
mLastAttri = Attri;
|
mLastAttri = attri;
|
||||||
SynExporter::SetTokenAttribute(Attri);
|
Exporter::setTokenAttribute(attri);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef HTMLEXPORTER_H
|
||||||
|
#define HTMLEXPORTER_H
|
||||||
|
|
||||||
|
#include "exporter.h"
|
||||||
|
|
||||||
|
namespace QSynedit {
|
||||||
|
class HTMLExporter : public Exporter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HTMLExporter(int tabSize,const QByteArray charset);
|
||||||
|
bool createHTMLFragment() const;
|
||||||
|
void setCreateHTMLFragment(bool createHTMLFragment);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool mCreateHTMLFragment;
|
||||||
|
private:
|
||||||
|
PTokenAttribute mLastAttri;
|
||||||
|
QString attriToCSS(PTokenAttribute attri, const QString& uniqueAttriName);
|
||||||
|
bool attriToCSSCallback(PSyntaxer syntaxer, PTokenAttribute attri,
|
||||||
|
const QString& uniqueAttriName, QList<void *> params);
|
||||||
|
QString colorToHTML(const QColor &color) const;
|
||||||
|
QString getStyleName(PSyntaxer syntaxer,
|
||||||
|
PTokenAttribute attri);
|
||||||
|
QString makeValidName(const QString &name);
|
||||||
|
bool styleNameCallback(PSyntaxer syntaxer, PTokenAttribute attri,
|
||||||
|
const QString& uniqueAttriName, QList<void *> params);
|
||||||
|
|
||||||
|
// SynExporter interface
|
||||||
|
protected:
|
||||||
|
void formatAttributeDone(bool backgroundChanged, bool foregroundChanged, FontStyles fontStyles);
|
||||||
|
void formatAttributeInit(bool backgroundChanged, bool foregroundChanged, FontStyles fontStyles);
|
||||||
|
void formatAfterLastAttribute();
|
||||||
|
void formatBeforeFirstAttribute(bool backgroundChanged, bool foregroundChanged, FontStyles fontStyles);
|
||||||
|
void formatNewLine();
|
||||||
|
QString getFooter();
|
||||||
|
QString getFormatName();
|
||||||
|
QString getHeader();
|
||||||
|
void setTokenAttribute(PTokenAttribute Attri);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif // HTMLEXPORTER_H
|
|
@ -0,0 +1,168 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include "qtsupportedhtmlexporter.h"
|
||||||
|
#include "../MiscProcs.h"
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace QSynedit {
|
||||||
|
|
||||||
|
QtSupportedHtmlExporter::QtSupportedHtmlExporter(int tabSize,const QByteArray charset):
|
||||||
|
Exporter(tabSize,charset)
|
||||||
|
{
|
||||||
|
mClipboardFormat = "text/html";
|
||||||
|
mDefaultFilter = "HTML Documents (*.htm;*.html)|*.htm;*.html";
|
||||||
|
// setup array of chars to be replaced
|
||||||
|
mReplaceReserved['&'] = "&";
|
||||||
|
mReplaceReserved['<'] = "<";
|
||||||
|
mReplaceReserved['>'] = ">";
|
||||||
|
mReplaceReserved['"'] = """;
|
||||||
|
mReplaceReserved[' '] = " ";
|
||||||
|
mReplaceReserved['\t'] = mReplaceReserved[' '].repeated(tabSize);
|
||||||
|
mCreateHTMLFragment = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QtSupportedHtmlExporter::createHTMLFragment() const
|
||||||
|
{
|
||||||
|
return mCreateHTMLFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtSupportedHtmlExporter::setCreateHTMLFragment(bool createHTMLFragment)
|
||||||
|
{
|
||||||
|
mCreateHTMLFragment = createHTMLFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QtSupportedHtmlExporter::attriToCSS(PTokenAttribute attri)
|
||||||
|
{
|
||||||
|
QString result;
|
||||||
|
if (mUseBackground && attri->background().isValid())
|
||||||
|
result += "background-color: " + colorToHTML(attri->background()) + "; ";
|
||||||
|
if (attri->foreground().isValid())
|
||||||
|
result += "color: " + colorToHTML(attri->foreground()) + "; ";
|
||||||
|
|
||||||
|
if (attri->styles().testFlag(FontStyle::fsBold))
|
||||||
|
result += "font-weight: bold; ";
|
||||||
|
if (attri->styles().testFlag(FontStyle::fsItalic))
|
||||||
|
result += "font-style: italic; ";
|
||||||
|
if (attri->styles().testFlag(FontStyle::fsUnderline))
|
||||||
|
result += "text-decoration: underline; ";
|
||||||
|
if (attri->styles().testFlag(FontStyle::fsStrikeOut))
|
||||||
|
result += "text-decoration: line-through; ";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QtSupportedHtmlExporter::colorToHTML(const QColor &color)
|
||||||
|
{
|
||||||
|
return color.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtSupportedHtmlExporter::formatAttributeDone(bool , bool , FontStyles )
|
||||||
|
{
|
||||||
|
addData("</span>");
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtSupportedHtmlExporter::formatAttributeInit(bool , bool , FontStyles )
|
||||||
|
{
|
||||||
|
addData(QString("<span style=\"%1\">").arg(attriToCSS(mLastAttri)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtSupportedHtmlExporter::formatAfterLastAttribute()
|
||||||
|
{
|
||||||
|
addData("</span>");
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtSupportedHtmlExporter::formatBeforeFirstAttribute(bool, bool, FontStyles)
|
||||||
|
{
|
||||||
|
addData(QString("<span style=\"%1\">").arg(attriToCSS(mLastAttri)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtSupportedHtmlExporter::formatNewLine()
|
||||||
|
{
|
||||||
|
addData("<br />");
|
||||||
|
addNewLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QtSupportedHtmlExporter::getFooter()
|
||||||
|
{
|
||||||
|
QString result = "";
|
||||||
|
result = "</div>" + lineBreak();
|
||||||
|
if (mCreateHTMLFragment)
|
||||||
|
result += "<!--EndFragment-->";
|
||||||
|
result += "</body>"+lineBreak()+ "</html>";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QtSupportedHtmlExporter::getFormatName()
|
||||||
|
{
|
||||||
|
return "HTML";
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QtSupportedHtmlExporter::getHeader()
|
||||||
|
{
|
||||||
|
using namespace std::placeholders;
|
||||||
|
QString styles;
|
||||||
|
|
||||||
|
|
||||||
|
QString HTMLAsTextHeader = "<?xml version=\"1.0\" encoding=\"%2\"?>"+lineBreak() +
|
||||||
|
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" + lineBreak() +
|
||||||
|
"<html xmlns=\"http://www.w3.org/1999/xhtml\">" + lineBreak() +
|
||||||
|
"<head>"+ lineBreak() +
|
||||||
|
"<title>%1</title>" + lineBreak() +
|
||||||
|
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%2\" />" + lineBreak() +
|
||||||
|
"<meta name=\"generator\" content=\"QSynEdit HTML exporter\" />" + lineBreak() +
|
||||||
|
"</head>" + lineBreak() +
|
||||||
|
"<body>" + lineBreak();
|
||||||
|
QString header = HTMLAsTextHeader
|
||||||
|
.arg(mTitle)
|
||||||
|
.arg(QString(mCharset));
|
||||||
|
if (mCreateHTMLFragment) {
|
||||||
|
HTMLAsTextHeader = "<?xml version=\"1.0\" encoding=\"%2\"?>"+lineBreak() +
|
||||||
|
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">" + lineBreak() +
|
||||||
|
"<html xmlns=\"http://www.w3.org/1999/xhtml\">" + lineBreak() +
|
||||||
|
"<head>"+ lineBreak() +
|
||||||
|
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%1\" />" + lineBreak() +
|
||||||
|
"<meta name=\"generator\" content=\"QSynEdit HTML exporter\" />" + lineBreak() +
|
||||||
|
"</head>" + lineBreak() +
|
||||||
|
"<body>" + lineBreak();
|
||||||
|
header = HTMLAsTextHeader
|
||||||
|
.arg(QString(mCharset));
|
||||||
|
}
|
||||||
|
QString result = header;
|
||||||
|
if (mCreateHTMLFragment) {
|
||||||
|
result += "<!--StartFragment-->"+lineBreak();
|
||||||
|
}
|
||||||
|
if (mUseBackground) {
|
||||||
|
result += QString("<div style=\"color: %1; background-color: %2; font: %3pt %4;\">")
|
||||||
|
.arg(colorToHTML(mForegroundColor))
|
||||||
|
.arg(colorToHTML(mBackgroundColor))
|
||||||
|
.arg(pixelToPoint(mFont.pixelSize()))
|
||||||
|
.arg(mFont.family())+lineBreak();
|
||||||
|
} else {
|
||||||
|
result += QString("<div style=\"color: %1; font: %2pt %3;\">")
|
||||||
|
.arg(colorToHTML(mForegroundColor))
|
||||||
|
.arg(pixelToPoint(mFont.pixelSize()))
|
||||||
|
.arg(mFont.family())+lineBreak();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtSupportedHtmlExporter::setTokenAttribute(PTokenAttribute Attri)
|
||||||
|
{
|
||||||
|
mLastAttri = Attri;
|
||||||
|
Exporter::setTokenAttribute(Attri);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
#ifndef QTSUPPORTEDHTMLEXPORTER_H
|
||||||
|
#define QTSUPPORTEDHTMLEXPORTER_H
|
||||||
|
|
||||||
|
#include "exporter.h"
|
||||||
|
|
||||||
|
namespace QSynedit {
|
||||||
|
class QtSupportedHtmlExporter : public Exporter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QtSupportedHtmlExporter(int tabSize,const QByteArray charset);
|
||||||
|
bool createHTMLFragment() const;
|
||||||
|
void setCreateHTMLFragment(bool createHTMLFragment);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool mCreateHTMLFragment;
|
||||||
|
private:
|
||||||
|
PTokenAttribute mLastAttri;
|
||||||
|
QString attriToCSS(PTokenAttribute attri);
|
||||||
|
QString colorToHTML(const QColor &color);
|
||||||
|
|
||||||
|
// SynExporter interface
|
||||||
|
protected:
|
||||||
|
void formatAttributeDone(bool backgroundChanged, bool foregroundChanged, FontStyles fontStyles);
|
||||||
|
void formatAttributeInit(bool backgroundChanged, bool foregroundChanged, FontStyles fontStyles);
|
||||||
|
void formatAfterLastAttribute();
|
||||||
|
void formatBeforeFirstAttribute(bool backgroundChanged, bool foregroundChanged, FontStyles fontStyles);
|
||||||
|
void formatNewLine();
|
||||||
|
QString getFooter();
|
||||||
|
QString getFormatName();
|
||||||
|
QString getHeader();
|
||||||
|
void setTokenAttribute(PTokenAttribute Attri);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif // QTSUPPORTEDHTMLEXPORTER_H
|
|
@ -0,0 +1,172 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include "rtfexporter.h"
|
||||||
|
namespace QSynedit {
|
||||||
|
|
||||||
|
RTFExporter::RTFExporter(int tabSize, const QByteArray charset):Exporter(tabSize,charset)
|
||||||
|
{
|
||||||
|
mDefaultFilter = "Rich Text Format Documents (*.rtf)|*.rtf";
|
||||||
|
mClipboardFormat = "application/x-qt-windows-mime;value=\"Rich Format Text\"";
|
||||||
|
//mClipboardFormat = "Rich Format Text";
|
||||||
|
// setup array of chars to be replaced
|
||||||
|
mReplaceReserved['\\'] = "\\\\";
|
||||||
|
mReplaceReserved['{'] = "\\{";
|
||||||
|
mReplaceReserved['}'] = "\\}";
|
||||||
|
mReplaceReserved['\t'] = "\\tab";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QString RTFExporter::colorToRTF(const QColor &color) const
|
||||||
|
{
|
||||||
|
return QString("\\red%1\\green%2\\blue%3;")
|
||||||
|
.arg(color.red())
|
||||||
|
.arg(color.green())
|
||||||
|
.arg(color.blue());
|
||||||
|
}
|
||||||
|
|
||||||
|
int RTFExporter::getColorIndex(const QColor &color)
|
||||||
|
{
|
||||||
|
int index = mListColors.indexOf(color);
|
||||||
|
if (index<0) {
|
||||||
|
mListColors.append(color);
|
||||||
|
index = mListColors.length()-1;
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString RTFExporter::getFontTable()
|
||||||
|
{
|
||||||
|
QString result = "{\\fonttbl{\\f0\\fmodern\\fcharset134 "
|
||||||
|
+ replaceReservedChars(mFont.family());
|
||||||
|
result = result + ";}}" + lineBreak();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RTFExporter::formatAttributeDone(bool , bool , FontStyles fontStyles)
|
||||||
|
{
|
||||||
|
// nothing to do about the color, but reset the font style
|
||||||
|
if (fontStyles.testFlag(FontStyle::fsBold)) {
|
||||||
|
mAttributesChanged = true;
|
||||||
|
addData("\\b0");
|
||||||
|
}
|
||||||
|
if (fontStyles.testFlag(FontStyle::fsItalic)) {
|
||||||
|
mAttributesChanged = true;
|
||||||
|
addData("\\i0");
|
||||||
|
}
|
||||||
|
if (fontStyles.testFlag(FontStyle::fsUnderline)) {
|
||||||
|
mAttributesChanged = true;
|
||||||
|
addData("\\ul0");
|
||||||
|
}
|
||||||
|
if (fontStyles.testFlag(FontStyle::fsStrikeOut)) {
|
||||||
|
mAttributesChanged = true;
|
||||||
|
addData("\\strike0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RTFExporter::formatAttributeInit(bool backgroundChanged, bool foregroundChanged, FontStyles fontStyles)
|
||||||
|
{
|
||||||
|
// background color
|
||||||
|
if (backgroundChanged) {
|
||||||
|
addData(QString("\\chshdng0\\chcbpat%1\\cb%2\\highlight%3 ")
|
||||||
|
.arg(getColorIndex(mLastBG))
|
||||||
|
.arg(getColorIndex(mLastBG))
|
||||||
|
.arg(getColorIndex(mLastBG)));
|
||||||
|
mAttributesChanged = true;
|
||||||
|
}
|
||||||
|
// text color
|
||||||
|
if (foregroundChanged) {
|
||||||
|
addData(QString("\\cf%1").arg(getColorIndex(mLastFG)));
|
||||||
|
mAttributesChanged = true;
|
||||||
|
}
|
||||||
|
// font styles
|
||||||
|
// nothing to do about the color, but reset the font style
|
||||||
|
if (fontStyles.testFlag(FontStyle::fsBold)) {
|
||||||
|
mAttributesChanged = true;
|
||||||
|
addData("\\b0");
|
||||||
|
}
|
||||||
|
if (fontStyles.testFlag(FontStyle::fsItalic)) {
|
||||||
|
mAttributesChanged = true;
|
||||||
|
addData("\\i0");
|
||||||
|
}
|
||||||
|
if (fontStyles.testFlag(FontStyle::fsUnderline)) {
|
||||||
|
mAttributesChanged = true;
|
||||||
|
addData("\\ul0");
|
||||||
|
}
|
||||||
|
if (fontStyles.testFlag(FontStyle::fsStrikeOut)) {
|
||||||
|
mAttributesChanged = true;
|
||||||
|
addData("\\strike0");
|
||||||
|
}
|
||||||
|
if (mAttributesChanged) {
|
||||||
|
addData(" ");
|
||||||
|
mAttributesChanged = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RTFExporter::formatAfterLastAttribute()
|
||||||
|
{
|
||||||
|
// no need to reset the font style here...
|
||||||
|
}
|
||||||
|
|
||||||
|
void RTFExporter::formatBeforeFirstAttribute(bool backgroundChanged, bool foregroundChanged, FontStyles fontStyles)
|
||||||
|
{
|
||||||
|
formatAttributeInit(backgroundChanged, foregroundChanged, fontStyles);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RTFExporter::formatNewLine()
|
||||||
|
{
|
||||||
|
addNewLine();
|
||||||
|
addData("\\par ");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString RTFExporter::getFooter()
|
||||||
|
{
|
||||||
|
return "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
QString RTFExporter::getFormatName()
|
||||||
|
{
|
||||||
|
return "RTF";
|
||||||
|
}
|
||||||
|
|
||||||
|
QString RTFExporter::getHeader()
|
||||||
|
{
|
||||||
|
QFontMetrics fm(mFont);
|
||||||
|
int tabWidth = mTabSize * fm.horizontalAdvance("M")*72*20/fm.fontDpi();
|
||||||
|
|
||||||
|
QString result = QString("{\\rtf1\\ansi\\deff0\\deftab%1").arg(tabWidth) + getFontTable();
|
||||||
|
// all the colors
|
||||||
|
result = result + "{\\colortbl";
|
||||||
|
for (int i = 0; i<mListColors.count();i++) {
|
||||||
|
result = result + colorToRTF(mListColors[i]);
|
||||||
|
}
|
||||||
|
result = result + colorToRTF(mBackgroundColor);
|
||||||
|
result = result + "}" + lineBreak();
|
||||||
|
// title and creator comment
|
||||||
|
result = result + "{\\info{\\comment Generated by the QSynEdit RTF " +
|
||||||
|
"exporter}" + lineBreak();
|
||||||
|
result = result + "{\\title " + mTitle + "}}" + lineBreak();
|
||||||
|
// if (mUseBackground)
|
||||||
|
// Result = Result + { TODO } #13#10;
|
||||||
|
result = result + QString("\\deflang1033\\pard\\plain\\f0\\fs%1 ").arg((int)(2 * pixelToPoint(mFont.pixelSize())));
|
||||||
|
if (mUseBackground)
|
||||||
|
result = result + QString("\\chshdng0\\chcbpat%1\\cb%2\\highlight%3 ")
|
||||||
|
.arg(getColorIndex(mLastBG))
|
||||||
|
.arg(getColorIndex(mBackgroundColor))
|
||||||
|
.arg(getColorIndex(mBackgroundColor));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef RTFEXPORTER_H
|
||||||
|
#define RTFEXPORTER_H
|
||||||
|
|
||||||
|
#include "exporter.h"
|
||||||
|
|
||||||
|
namespace QSynedit {
|
||||||
|
|
||||||
|
class RTFExporter : public Exporter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit RTFExporter(int tabSize,const QByteArray charset);
|
||||||
|
private:
|
||||||
|
bool mAttributesChanged;
|
||||||
|
QList<QColor> mListColors;
|
||||||
|
QString colorToRTF(const QColor& AColor) const;
|
||||||
|
int getColorIndex(const QColor& AColor);
|
||||||
|
QString getFontTable();
|
||||||
|
|
||||||
|
// SynExporter interface
|
||||||
|
protected:
|
||||||
|
void formatAttributeDone(bool backgroundChanged, bool foregroundChanged, FontStyles fontStyles) override;
|
||||||
|
void formatAttributeInit(bool backgroundChanged, bool foregroundChanged, FontStyles fontStyles) override;
|
||||||
|
void formatAfterLastAttribute() override;
|
||||||
|
void formatBeforeFirstAttribute(bool backgroundChanged, bool foregroundChanged, FontStyles fontStyles) override;
|
||||||
|
void formatNewLine() override;
|
||||||
|
QString getFooter() override;
|
||||||
|
QString getFormatName() override;
|
||||||
|
QString getHeader() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif // RTFEXPORTER_H
|
|
@ -1,402 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com)
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#include "synexporter.h"
|
|
||||||
|
|
||||||
#include <QClipboard>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QGuiApplication>
|
|
||||||
#include <QMimeData>
|
|
||||||
#include <QTextCodec>
|
|
||||||
|
|
||||||
namespace QSynedit {
|
|
||||||
|
|
||||||
SynExporter::SynExporter(const QByteArray charset):mCharset(charset)
|
|
||||||
{
|
|
||||||
mClipboardFormat = "text/plain";
|
|
||||||
mFont = QGuiApplication::font();
|
|
||||||
mBackgroundColor = QGuiApplication::palette().color(QPalette::Base);
|
|
||||||
mForegroundColor = QGuiApplication::palette().color(QPalette::Text);
|
|
||||||
mUseBackground = false;
|
|
||||||
mExportAsText = false;
|
|
||||||
mFileEndingType = NewlineType::Windows;
|
|
||||||
clear();
|
|
||||||
setTitle("");
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynExporter::clear()
|
|
||||||
{
|
|
||||||
mBuffer.clear();
|
|
||||||
mLastStyle = FontStyle::fsNone;
|
|
||||||
mLastBG = QGuiApplication::palette().color(QPalette::Base);
|
|
||||||
mLastFG = QGuiApplication::palette().color(QPalette::Text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynExporter::CopyToClipboard()
|
|
||||||
{
|
|
||||||
if (mExportAsText) {
|
|
||||||
CopyToClipboardFormat("text/plain");
|
|
||||||
} else
|
|
||||||
CopyToClipboardFormat(clipboardFormat());
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynExporter::ExportAll(PDocument ALines)
|
|
||||||
{
|
|
||||||
ExportRange(ALines, BufferCoord{1, 1}, BufferCoord{INT_MAX, INT_MAX});
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynExporter::ExportRange(PDocument ALines, BufferCoord Start, BufferCoord Stop)
|
|
||||||
{
|
|
||||||
// abort if not all necessary conditions are met
|
|
||||||
if (!ALines || !mSyntaxer || (ALines->count() == 0))
|
|
||||||
return;
|
|
||||||
Stop.line = std::max(1, std::min(Stop.line, ALines->count()));
|
|
||||||
Stop.ch = std::max(1, std::min(Stop.ch, ALines->getString(Stop.line - 1).length() + 1));
|
|
||||||
Start.line = std::max(1, std::min(Start.line, ALines->count()));
|
|
||||||
Start.ch = std::max(1, std::min(Start.ch, ALines->getString(Start.line - 1).length() + 1));
|
|
||||||
if ( (Start.line > ALines->count()) || (Start.line > Stop.line) )
|
|
||||||
return;
|
|
||||||
if ((Start.line == Stop.line) && (Start.ch >= Stop.ch))
|
|
||||||
return;
|
|
||||||
// initialization
|
|
||||||
mBuffer.clear();
|
|
||||||
// export all the lines into fBuffer
|
|
||||||
mFirstAttribute = true;
|
|
||||||
|
|
||||||
if (Start.line == 1)
|
|
||||||
mSyntaxer->resetState();
|
|
||||||
else
|
|
||||||
mSyntaxer->setState(ALines->ranges(Start.line-2));
|
|
||||||
for (int i = Start.line; i<=Stop.line; i++) {
|
|
||||||
QString Line = ALines->getString(i-1);
|
|
||||||
// order is important, since Start.Y might be equal to Stop.Y
|
|
||||||
// if (i == Stop.Line)
|
|
||||||
// Line.remove(Stop.Char-1, INT_MAX);
|
|
||||||
// if ( (i = Start.Line) && (Start.Char > 1))
|
|
||||||
// Line.remove(0, Start.Char - 1);
|
|
||||||
// export the line
|
|
||||||
mSyntaxer->setLine(Line, i);
|
|
||||||
while (!mSyntaxer->eol()) {
|
|
||||||
PTokenAttribute attri = mSyntaxer->getTokenAttribute();
|
|
||||||
int startPos = mSyntaxer->getTokenPos();
|
|
||||||
QString token = mSyntaxer->getToken();
|
|
||||||
if (i==Start.line && (startPos+token.length() < Start.ch)) {
|
|
||||||
mSyntaxer->next();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (i==Stop.line && (startPos >= Stop.ch-1)) {
|
|
||||||
mSyntaxer->next();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (i==Stop.line && (startPos+token.length() > Stop.ch)) {
|
|
||||||
token = token.remove(Stop.ch - startPos - 1);
|
|
||||||
}
|
|
||||||
if (i==Start.line && startPos < Start.ch-1) {
|
|
||||||
token = token.mid(Start.ch-1-startPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Token = ReplaceReservedChars(token);
|
|
||||||
if (mOnFormatToken)
|
|
||||||
mOnFormatToken(mSyntaxer, i, mSyntaxer->getTokenPos()+1, mSyntaxer->getToken(),attri);
|
|
||||||
SetTokenAttribute(attri);
|
|
||||||
FormatToken(Token);
|
|
||||||
mSyntaxer->next();
|
|
||||||
}
|
|
||||||
if (i!=Stop.line)
|
|
||||||
FormatNewLine();
|
|
||||||
}
|
|
||||||
if (!mFirstAttribute)
|
|
||||||
FormatAfterLastAttribute();
|
|
||||||
// insert header
|
|
||||||
InsertData(0, GetHeader());
|
|
||||||
// add footer
|
|
||||||
AddData(GetFooter());
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynExporter::SaveToFile(const QString &AFileName)
|
|
||||||
{
|
|
||||||
QFile file(AFileName);
|
|
||||||
if (file.open(QIODevice::WriteOnly)) {
|
|
||||||
SaveToStream(file);
|
|
||||||
} else {
|
|
||||||
throw FileError(QObject::tr("Can't open file '%1' to write!").arg(AFileName));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynExporter::SaveToStream(QIODevice &AStream)
|
|
||||||
{
|
|
||||||
if (AStream.write(mBuffer)<0) {
|
|
||||||
throw FileError(QObject::tr("Failed to write data."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SynExporter::exportAsText() const
|
|
||||||
{
|
|
||||||
return mExportAsText;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynExporter::setExportAsText(bool Value)
|
|
||||||
{
|
|
||||||
if (mExportAsText != Value) {
|
|
||||||
mExportAsText = Value;
|
|
||||||
clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QFont SynExporter::font() const
|
|
||||||
{
|
|
||||||
return mFont;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynExporter::setFont(const QFont &font)
|
|
||||||
{
|
|
||||||
mFont = font;
|
|
||||||
}
|
|
||||||
|
|
||||||
PSyntaxer SynExporter::syntaxer() const
|
|
||||||
{
|
|
||||||
return mSyntaxer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynExporter::setSyntaxer(PSyntaxer value)
|
|
||||||
{
|
|
||||||
if (mSyntaxer != value) {
|
|
||||||
mSyntaxer = value;
|
|
||||||
clear();
|
|
||||||
if ((mSyntaxer) && (mSyntaxer->whitespaceAttribute()) && mUseBackground)
|
|
||||||
mBackgroundColor = mSyntaxer->whitespaceAttribute()->background();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SynExporter::title() const
|
|
||||||
{
|
|
||||||
return mTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynExporter::setTitle(const QString &Value)
|
|
||||||
{
|
|
||||||
if (mTitle != Value) {
|
|
||||||
if (!Value.isEmpty())
|
|
||||||
mTitle = Value;
|
|
||||||
else
|
|
||||||
mTitle = "Untitled";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SynExporter::useBackground() const
|
|
||||||
{
|
|
||||||
return mUseBackground;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynExporter::setUseBackground(bool Value)
|
|
||||||
{
|
|
||||||
if (mUseBackground != Value) {
|
|
||||||
mUseBackground = Value;
|
|
||||||
clear();
|
|
||||||
if ((mSyntaxer) && (mSyntaxer->whitespaceAttribute()) && mUseBackground)
|
|
||||||
mBackgroundColor = mSyntaxer->whitespaceAttribute()->background();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NewlineType SynExporter::fileEndingType() const
|
|
||||||
{
|
|
||||||
return mFileEndingType;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynExporter::setFileEndingType(const NewlineType &fileEndingType)
|
|
||||||
{
|
|
||||||
mFileEndingType = fileEndingType;
|
|
||||||
}
|
|
||||||
|
|
||||||
QColor SynExporter::foregroundColor() const
|
|
||||||
{
|
|
||||||
return mForegroundColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynExporter::setForegroundColor(const QColor &value)
|
|
||||||
{
|
|
||||||
if (mForegroundColor != value) {
|
|
||||||
mForegroundColor = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QColor SynExporter::backgroundColor() const
|
|
||||||
{
|
|
||||||
return mBackgroundColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynExporter::setBackgroundColor(const QColor &value)
|
|
||||||
{
|
|
||||||
if (mBackgroundColor != value) {
|
|
||||||
mBackgroundColor = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray SynExporter::charset() const
|
|
||||||
{
|
|
||||||
return mCharset;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynExporter::setCharset(const QByteArray &charset)
|
|
||||||
{
|
|
||||||
mCharset = charset;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SynExporter::defaultFilter() const
|
|
||||||
{
|
|
||||||
return mDefaultFilter;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynExporter::setDefaultFilter(const QString &defaultFilter)
|
|
||||||
{
|
|
||||||
mDefaultFilter = defaultFilter;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynExporter::AddData(const QString &AText)
|
|
||||||
{
|
|
||||||
if (!AText.isEmpty()) {
|
|
||||||
QTextCodec* codec = getCodec();
|
|
||||||
mBuffer.append(codec->fromUnicode(AText));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynExporter::AddDataNewLine(const QString &AText)
|
|
||||||
{
|
|
||||||
AddData(AText);
|
|
||||||
AddNewLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynExporter::AddNewLine()
|
|
||||||
{
|
|
||||||
AddData(lineBreak());
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynExporter::CopyToClipboardFormat(QByteArray AFormat)
|
|
||||||
{
|
|
||||||
QClipboard* clipboard = QGuiApplication::clipboard();
|
|
||||||
QMimeData * mimeData = new QMimeData();
|
|
||||||
mimeData->setData(AFormat,mBuffer);
|
|
||||||
clipboard->clear();
|
|
||||||
clipboard->setMimeData(mimeData);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynExporter::FormatToken(const QString &Token)
|
|
||||||
{
|
|
||||||
AddData(Token);
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynExporter::GetBufferSize()
|
|
||||||
{
|
|
||||||
return mBuffer.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
QTextCodec * SynExporter::getCodec() {
|
|
||||||
QTextCodec* codec = QTextCodec::codecForName(mCharset);
|
|
||||||
if (codec == nullptr)
|
|
||||||
codec = QTextCodec::codecForLocale();
|
|
||||||
return codec;
|
|
||||||
}
|
|
||||||
void SynExporter::InsertData(int APos, const QString &AText)
|
|
||||||
{
|
|
||||||
if (!AText.isEmpty()) {
|
|
||||||
QTextCodec* codec = getCodec();
|
|
||||||
mBuffer.insert(APos,codec->fromUnicode(AText));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SynExporter::ReplaceReservedChars(const QString &AToken)
|
|
||||||
{
|
|
||||||
if (AToken.isEmpty())
|
|
||||||
return "";
|
|
||||||
QString result;
|
|
||||||
for (QChar ch:AToken) {
|
|
||||||
if (mReplaceReserved.contains(ch)) {
|
|
||||||
result += mReplaceReserved[ch];
|
|
||||||
} else {
|
|
||||||
result += ch;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QColor ValidatedColor(const QColor& color, const QColor& defaultColor) {
|
|
||||||
if (color.isValid())
|
|
||||||
return color;
|
|
||||||
else
|
|
||||||
return defaultColor;
|
|
||||||
}
|
|
||||||
void SynExporter::SetTokenAttribute(PTokenAttribute Attri)
|
|
||||||
{
|
|
||||||
if (mFirstAttribute) {
|
|
||||||
mFirstAttribute = false;
|
|
||||||
mLastBG = ValidatedColor(Attri->background(), mBackgroundColor);
|
|
||||||
mLastFG = ValidatedColor(Attri->foreground(), mForegroundColor);
|
|
||||||
mLastStyle = Attri->styles();
|
|
||||||
FormatBeforeFirstAttribute(
|
|
||||||
mUseBackground && (mLastBG != mBackgroundColor),
|
|
||||||
mLastFG != mForegroundColor, Attri->styles());
|
|
||||||
} else {
|
|
||||||
bool ChangedBG = mUseBackground &&
|
|
||||||
(mLastBG != ValidatedColor(Attri->background(), mBackgroundColor));
|
|
||||||
bool ChangedFG = (mLastFG != ValidatedColor(Attri->foreground(), mForegroundColor));
|
|
||||||
if (ChangedBG || ChangedFG || (mLastStyle != Attri->styles())) {
|
|
||||||
// which font style bits are to reset?
|
|
||||||
FontStyles ChangedStyles = mLastStyle & ~(Attri->styles());
|
|
||||||
FormatAttributeDone(ChangedBG, ChangedFG, ChangedStyles);
|
|
||||||
// which font style bits are to set?
|
|
||||||
ChangedStyles = Attri->styles() & ~(mLastStyle);
|
|
||||||
mLastBG = ValidatedColor(Attri->background(), mBackgroundColor);
|
|
||||||
mLastFG = ValidatedColor(Attri->foreground(), mForegroundColor);
|
|
||||||
mLastStyle = Attri->styles();
|
|
||||||
FormatAttributeInit(ChangedBG, ChangedFG, ChangedStyles);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const QByteArray &SynExporter::buffer() const
|
|
||||||
{
|
|
||||||
return mBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray SynExporter::clipboardFormat()
|
|
||||||
{
|
|
||||||
return this->mClipboardFormat;
|
|
||||||
}
|
|
||||||
|
|
||||||
FormatTokenHandler SynExporter::onFormatToken() const
|
|
||||||
{
|
|
||||||
return mOnFormatToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynExporter::setOnFormatToken(const FormatTokenHandler &onFormatToken)
|
|
||||||
{
|
|
||||||
mOnFormatToken = onFormatToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SynExporter::lineBreak()
|
|
||||||
{
|
|
||||||
switch(mFileEndingType) {
|
|
||||||
case NewlineType::Unix:
|
|
||||||
return "\n";
|
|
||||||
case NewlineType::Windows:
|
|
||||||
return "\r\n";
|
|
||||||
case NewlineType::MacOld:
|
|
||||||
return "\r";
|
|
||||||
}
|
|
||||||
return "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com)
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#ifndef SYNHTMLEXPORTER_H
|
|
||||||
#define SYNHTMLEXPORTER_H
|
|
||||||
|
|
||||||
#include "synexporter.h"
|
|
||||||
|
|
||||||
namespace QSynedit {
|
|
||||||
class SynHTMLExporter : public SynExporter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SynHTMLExporter(int tabSize,const QByteArray charset);
|
|
||||||
bool createHTMLFragment() const;
|
|
||||||
void setCreateHTMLFragment(bool createHTMLFragment);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool mCreateHTMLFragment;
|
|
||||||
private:
|
|
||||||
PTokenAttribute mLastAttri;
|
|
||||||
QString AttriToCSS(PTokenAttribute Attri, const QString& UniqueAttriName);
|
|
||||||
bool AttriToCSSCallback(PSyntaxer Highlighter, PTokenAttribute Attri,
|
|
||||||
const QString& UniqueAttriName, QList<void *> params);
|
|
||||||
QString ColorToHTML(const QColor &AColor);
|
|
||||||
QString GetStyleName(PSyntaxer Highlighter,
|
|
||||||
PTokenAttribute Attri);
|
|
||||||
QString MakeValidName(const QString &Name);
|
|
||||||
bool StyleNameCallback(PSyntaxer Highlighter, PTokenAttribute Attri,
|
|
||||||
const QString& UniqueAttriName, QList<void *> params);
|
|
||||||
|
|
||||||
// SynExporter interface
|
|
||||||
protected:
|
|
||||||
void FormatAttributeDone(bool BackgroundChanged, bool ForegroundChanged, FontStyles FontStylesChanged);
|
|
||||||
void FormatAttributeInit(bool BackgroundChanged, bool ForegroundChanged, FontStyles FontStylesChanged);
|
|
||||||
void FormatAfterLastAttribute();
|
|
||||||
void FormatBeforeFirstAttribute(bool BackgroundChanged, bool ForegroundChanged, FontStyles FontStylesChanged);
|
|
||||||
void FormatNewLine();
|
|
||||||
QString GetFooter();
|
|
||||||
QString GetFormatName();
|
|
||||||
QString GetHeader();
|
|
||||||
void SetTokenAttribute(PTokenAttribute Attri);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
#endif // SYNHTMLEXPORTER_H
|
|
|
@ -1,168 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com)
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#include "synrtfexporter.h"
|
|
||||||
namespace QSynedit {
|
|
||||||
|
|
||||||
SynRTFExporter::SynRTFExporter(const QByteArray charset):SynExporter(charset)
|
|
||||||
{
|
|
||||||
mDefaultFilter = "Rich Text Format Documents (*.rtf)|*.rtf";
|
|
||||||
mClipboardFormat = "application/x-qt-windows-mime;value=\"Rich Format Text\"";
|
|
||||||
//mClipboardFormat = "Rich Format Text";
|
|
||||||
// setup array of chars to be replaced
|
|
||||||
mReplaceReserved['\\'] = "\\\\";
|
|
||||||
mReplaceReserved['{'] = "\\{";
|
|
||||||
mReplaceReserved['}'] = "\\}";
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SynRTFExporter::ColorToRTF(const QColor &AColor) const
|
|
||||||
{
|
|
||||||
return QString("\\red%1\\green%2\\blue%3;")
|
|
||||||
.arg(AColor.red())
|
|
||||||
.arg(AColor.green())
|
|
||||||
.arg(AColor.blue());
|
|
||||||
}
|
|
||||||
|
|
||||||
int SynRTFExporter::GetColorIndex(const QColor &AColor)
|
|
||||||
{
|
|
||||||
int index = mListColors.indexOf(AColor);
|
|
||||||
if (index<0) {
|
|
||||||
mListColors.append(AColor);
|
|
||||||
index = mListColors.length()-1;
|
|
||||||
}
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SynRTFExporter::GetFontTable()
|
|
||||||
{
|
|
||||||
QString Result = "{\\fonttbl{\\f0\\fmodern\\fcharset134 "
|
|
||||||
+ ReplaceReservedChars(mFont.family());
|
|
||||||
Result = Result + ";}}" + lineBreak();
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynRTFExporter::FormatAttributeDone(bool , bool , FontStyles FontStylesChanged)
|
|
||||||
{
|
|
||||||
// nothing to do about the color, but reset the font style
|
|
||||||
if (FontStylesChanged.testFlag(FontStyle::fsBold)) {
|
|
||||||
mAttributesChanged = true;
|
|
||||||
AddData("\\b0");
|
|
||||||
}
|
|
||||||
if (FontStylesChanged.testFlag(FontStyle::fsItalic)) {
|
|
||||||
mAttributesChanged = true;
|
|
||||||
AddData("\\i0");
|
|
||||||
}
|
|
||||||
if (FontStylesChanged.testFlag(FontStyle::fsUnderline)) {
|
|
||||||
mAttributesChanged = true;
|
|
||||||
AddData("\\ul0");
|
|
||||||
}
|
|
||||||
if (FontStylesChanged.testFlag(FontStyle::fsStrikeOut)) {
|
|
||||||
mAttributesChanged = true;
|
|
||||||
AddData("\\strike0");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynRTFExporter::FormatAttributeInit(bool BackgroundChanged, bool ForegroundChanged, FontStyles FontStylesChanged)
|
|
||||||
{
|
|
||||||
// background color
|
|
||||||
if (BackgroundChanged) {
|
|
||||||
AddData(QString("\\chshdng0\\chcbpat%1\\cb%2\\highlight%3 ")
|
|
||||||
.arg(GetColorIndex(mLastBG))
|
|
||||||
.arg(GetColorIndex(mLastBG))
|
|
||||||
.arg(GetColorIndex(mLastBG)));
|
|
||||||
mAttributesChanged = true;
|
|
||||||
}
|
|
||||||
// text color
|
|
||||||
if (ForegroundChanged) {
|
|
||||||
AddData(QString("\\cf%1").arg(GetColorIndex(mLastFG)));
|
|
||||||
mAttributesChanged = true;
|
|
||||||
}
|
|
||||||
// font styles
|
|
||||||
// nothing to do about the color, but reset the font style
|
|
||||||
if (FontStylesChanged.testFlag(FontStyle::fsBold)) {
|
|
||||||
mAttributesChanged = true;
|
|
||||||
AddData("\\b0");
|
|
||||||
}
|
|
||||||
if (FontStylesChanged.testFlag(FontStyle::fsItalic)) {
|
|
||||||
mAttributesChanged = true;
|
|
||||||
AddData("\\i0");
|
|
||||||
}
|
|
||||||
if (FontStylesChanged.testFlag(FontStyle::fsUnderline)) {
|
|
||||||
mAttributesChanged = true;
|
|
||||||
AddData("\\ul0");
|
|
||||||
}
|
|
||||||
if (FontStylesChanged.testFlag(FontStyle::fsStrikeOut)) {
|
|
||||||
mAttributesChanged = true;
|
|
||||||
AddData("\\strike0");
|
|
||||||
}
|
|
||||||
if (mAttributesChanged) {
|
|
||||||
AddData(" ");
|
|
||||||
mAttributesChanged = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynRTFExporter::FormatAfterLastAttribute()
|
|
||||||
{
|
|
||||||
// no need to reset the font style here...
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynRTFExporter::FormatBeforeFirstAttribute(bool BackgroundChanged, bool ForegroundChanged, FontStyles FontStylesChanged)
|
|
||||||
{
|
|
||||||
FormatAttributeInit(BackgroundChanged, ForegroundChanged, FontStylesChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SynRTFExporter::FormatNewLine()
|
|
||||||
{
|
|
||||||
AddNewLine();
|
|
||||||
AddData("\\par ");
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SynRTFExporter::GetFooter()
|
|
||||||
{
|
|
||||||
return "}";
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SynRTFExporter::GetFormatName()
|
|
||||||
{
|
|
||||||
return "RTF";
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SynRTFExporter::GetHeader()
|
|
||||||
{
|
|
||||||
QString Result = "{\\rtf1\\ansi\\deff0\\deftab720" + GetFontTable();
|
|
||||||
// all the colors
|
|
||||||
Result = Result + "{\\colortbl";
|
|
||||||
for (int i = 0; i<mListColors.count();i++) {
|
|
||||||
Result = Result + ColorToRTF(mListColors[i]);
|
|
||||||
}
|
|
||||||
Result = Result + ColorToRTF(mBackgroundColor);
|
|
||||||
Result = Result + "}" + lineBreak();
|
|
||||||
// title and creator comment
|
|
||||||
Result = Result + "{\\info{\\comment Generated by the QSynEdit RTF " +
|
|
||||||
"exporter}" + lineBreak();
|
|
||||||
Result = Result + "{\\title " + mTitle + "}}" + lineBreak();
|
|
||||||
// if (mUseBackground)
|
|
||||||
// Result = Result + { TODO } #13#10;
|
|
||||||
Result = Result + QString("\\deflang1033\\pard\\plain\\f0\\fs%1 ").arg((int)(2 * pixelToPoint(mFont.pixelSize())));
|
|
||||||
if (mUseBackground)
|
|
||||||
Result = Result + QString("\\chshdng0\\chcbpat%1\\cb%2\\highlight%3 ")
|
|
||||||
.arg(GetColorIndex(mLastBG))
|
|
||||||
.arg(GetColorIndex(mBackgroundColor))
|
|
||||||
.arg(GetColorIndex(mBackgroundColor));
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,48 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com)
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#ifndef SYNRTFEXPORTER_H
|
|
||||||
#define SYNRTFEXPORTER_H
|
|
||||||
|
|
||||||
#include "synexporter.h"
|
|
||||||
|
|
||||||
namespace QSynedit {
|
|
||||||
|
|
||||||
class SynRTFExporter : public SynExporter
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit SynRTFExporter(const QByteArray charset);
|
|
||||||
private:
|
|
||||||
bool mAttributesChanged;
|
|
||||||
QList<QColor> mListColors;
|
|
||||||
QString ColorToRTF(const QColor& AColor) const;
|
|
||||||
int GetColorIndex(const QColor& AColor);
|
|
||||||
QString GetFontTable();
|
|
||||||
|
|
||||||
// SynExporter interface
|
|
||||||
protected:
|
|
||||||
void FormatAttributeDone(bool BackgroundChanged, bool ForegroundChanged, FontStyles FontStylesChanged) override;
|
|
||||||
void FormatAttributeInit(bool BackgroundChanged, bool ForegroundChanged, FontStyles FontStylesChanged) override;
|
|
||||||
void FormatAfterLastAttribute() override;
|
|
||||||
void FormatBeforeFirstAttribute(bool BackgroundChanged, bool ForegroundChanged, FontStyles FontStylesChanged) override;
|
|
||||||
void FormatNewLine() override;
|
|
||||||
QString GetFooter() override;
|
|
||||||
QString GetFormatName() override;
|
|
||||||
QString GetHeader() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif // SYNRTFEXPORTER_H
|
|
Loading…
Reference in New Issue