aboutsummaryrefslogtreecommitdiffstats
path: root/Plugins/HtmlExport
diff options
context:
space:
mode:
Diffstat (limited to 'Plugins/HtmlExport')
-rw-r--r--Plugins/HtmlExport/HtmlExport.pro29
-rw-r--r--Plugins/HtmlExport/htmlexport.cpp615
-rw-r--r--Plugins/HtmlExport/htmlexport.css59
-rw-r--r--Plugins/HtmlExport/htmlexport.h74
-rw-r--r--Plugins/HtmlExport/htmlexport.json7
-rw-r--r--Plugins/HtmlExport/htmlexport.qrc8
-rw-r--r--Plugins/HtmlExport/htmlexport.ui129
-rw-r--r--Plugins/HtmlExport/htmlexport_global.h12
8 files changed, 933 insertions, 0 deletions
diff --git a/Plugins/HtmlExport/HtmlExport.pro b/Plugins/HtmlExport/HtmlExport.pro
new file mode 100644
index 0000000..ff0a68e
--- /dev/null
+++ b/Plugins/HtmlExport/HtmlExport.pro
@@ -0,0 +1,29 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2014-06-20T22:57:37
+#
+#-------------------------------------------------
+
+include($$PWD/../../SQLiteStudio3/plugins.pri)
+
+QT -= gui
+
+TARGET = HtmlExport
+TEMPLATE = lib
+
+DEFINES += HTMLEXPORT_LIBRARY
+
+SOURCES += htmlexport.cpp
+
+HEADERS += htmlexport.h\
+ htmlexport_global.h
+
+OTHER_FILES += \
+ htmlexport.json \
+ htmlexport.css
+
+RESOURCES += \
+ htmlexport.qrc
+
+FORMS += \
+ htmlexport.ui
diff --git a/Plugins/HtmlExport/htmlexport.cpp b/Plugins/HtmlExport/htmlexport.cpp
new file mode 100644
index 0000000..75b3868
--- /dev/null
+++ b/Plugins/HtmlExport/htmlexport.cpp
@@ -0,0 +1,615 @@
+#include "htmlexport.h"
+#include "services/pluginmanager.h"
+#include "common/unused.h"
+#include <QFile>
+#include <QTextCodec>
+#include <QDebug>
+#include <QRegExp>
+#include <schemaresolver.h>
+
+QString HtmlExport::getFormatName() const
+{
+ return "HTML";
+}
+
+ExportManager::StandardConfigFlags HtmlExport::standardOptionsToEnable() const
+{
+ return ExportManager::CODEC;
+}
+
+QString HtmlExport::getExportConfigFormName() const
+{
+ return "HtmlExportConfig";
+}
+
+void HtmlExport::validateOptions()
+{
+ bool header = cfg.HtmlExport.PrintHeader.get();
+ EXPORT_MANAGER->updateVisibilityAndEnabled(cfg.HtmlExport.PrintDataTypes, true, header);
+}
+
+QString HtmlExport::defaultFileExtension() const
+{
+ return "html";
+}
+
+CfgMain* HtmlExport::getConfig()
+{
+ return &cfg;
+}
+
+bool HtmlExport::beforeExportQueryResults(const QString& query, QList<QueryExecutor::ResultColumnPtr>& columns, const QHash<ExportManager::ExportProviderFlag, QVariant> providedData)
+{
+ UNUSED(query);
+ UNUSED(providedData);
+
+ if (!beginDoc(tr("SQL query results")))
+ return false;
+
+ columnTypes = QueryExecutor::resolveColumnTypes(db, columns, true);
+
+ writeln("<table>");
+ incrIndent();
+ if (printHeader)
+ {
+ writeln("<tr class=\"header\">");
+ incrIndent();
+ if (printRownum)
+ {
+ writeln("<td align=\"right\">");
+ incrIndent();
+ writeln("<b><i>#</i></b>");
+ decrIndent();
+ writeln("</td>");
+ }
+
+ QString column;
+ int i = 0;
+ for (const QueryExecutor::ResultColumnPtr& col : columns)
+ {
+ writeln("<td>");
+ incrIndent();
+ column = QString("<b>%1</b>").arg(col->displayName);
+ if (printDatatypes)
+ {
+ if (!columnTypes[i].isNull())
+ column.append("<br/>" + columnTypes[i].toFullTypeString());
+ else
+ column.append("<br/>" + tr("no type"));
+ }
+ writeln(column);
+ decrIndent();
+ writeln("</td>");
+ i++;
+ }
+ decrIndent();
+ writeln("</tr>");
+ }
+
+ currentDataRow = 0;
+ return true;
+}
+
+bool HtmlExport::exportQueryResultsRow(SqlResultsRowPtr row)
+{
+ return exportDataRow(row);
+}
+
+bool HtmlExport::afterExportQueryResults()
+{
+ decrIndent();
+ writeln("</table>");
+ writeln("<br/><br/>");
+ return true;
+}
+
+bool HtmlExport::exportTable(const QString& database, const QString& table, const QStringList& columnNames, const QString& ddl, SqliteCreateTablePtr createTable, const QHash<ExportManager::ExportProviderFlag, QVariant> providedData)
+{
+ UNUSED(database);
+ UNUSED(ddl);
+ UNUSED(columnNames);
+ UNUSED(providedData);
+
+ if (isTableExport())
+ {
+ if (!beginDoc(tr("Exported table: %1").arg(table)))
+ return false;
+ }
+
+ int colCount = createTable->columns.size();
+ int colSpan = printRownum ? colCount + 1 : colCount;
+
+ writeln("<table>");
+ incrIndent();
+
+ writeln("<tr class=\"title\">");
+ incrIndent();
+ writeln(QString("<td colspan=\"%1\" align=\"center\">%2</td>").arg(colSpan).arg(tr("Table: %1").arg(table)));
+ decrIndent();
+ writeln("</tr>");
+
+ if (printHeader)
+ {
+ writeln("<tr class=\"header\">");
+ incrIndent();
+ if (printRownum)
+ {
+ writeln("<td align=\"right\">");
+ incrIndent();
+ writeln("<b><i>#</i></b>");
+ decrIndent();
+ writeln("</td>");
+ }
+
+ QString column;
+ for (SqliteCreateTable::Column* col : createTable->columns)
+ {
+ writeln("<td>");
+ incrIndent();
+ column = QString("<b>%1</b>").arg(col->name);
+ if (printDatatypes)
+ {
+ if (col->type)
+ column.append("<br/>" + col->type->toDataType().toFullTypeString());
+ else
+ column.append("<br/>" + tr("no type"));
+ }
+ writeln(column);
+ decrIndent();
+ writeln("</td>");
+ }
+ decrIndent();
+ writeln("</tr>");
+ }
+
+ columnTypes.clear();
+ for (SqliteCreateTable::Column* col : createTable->columns)
+ {
+ if (col->type)
+ columnTypes << col->type->toDataType();
+ else
+ columnTypes << DataType();
+ }
+
+ currentDataRow = 0;
+ return true;
+}
+
+bool HtmlExport::exportDataRow(SqlResultsRowPtr data)
+{
+ currentDataRow++;
+
+ writeln("<tr>");
+ incrIndent();
+ if (printRownum)
+ {
+ writeln("<td class=\"rownum\">");
+ incrIndent();
+ writeln(QString("<i>%1</i>").arg(currentDataRow));
+ decrIndent();
+ writeln("</td>");
+ }
+
+ QString align;
+ QString cellValue;
+ QString cellStyle;
+ int i = 0;
+ for (const QVariant& value : data->valueList())
+ {
+ if (columnTypes[i].isNumeric())
+ align = "right";
+ else
+ align = "left";
+
+ if (value.isNull())
+ {
+ cellValue = "<i>NULL</i>";
+ cellStyle = " class=\"null\"";
+ }
+ else
+ {
+ cellStyle = "";
+ if (value.toString().trimmed().isEmpty())
+ cellValue = "&nbsp;";
+ else
+ {
+ cellValue = value.toString();
+ cellValue.truncate(byteLengthLimit);
+ cellValue = escape(cellValue);
+ }
+ }
+ writeln(QString("<td align=\"%1\"%2>").arg(align, cellStyle));
+ incrIndent();
+ writeln(cellValue);
+ decrIndent();
+ writeln("</td>");
+ i++;
+ }
+ decrIndent();
+ writeln("</tr>");
+ return true;
+}
+
+bool HtmlExport::exportVirtualTable(const QString& database, const QString& table, const QStringList& columnNames, const QString& ddl, SqliteCreateVirtualTablePtr createTable, const QHash<ExportManager::ExportProviderFlag, QVariant> providedData)
+{
+ UNUSED(database);
+ UNUSED(ddl);
+ UNUSED(columnNames);
+ UNUSED(createTable);
+ UNUSED(providedData);
+
+ if (isTableExport())
+ {
+ if (!beginDoc(tr("Exported table: %1").arg(table)))
+ return false;
+ }
+
+ int colCount = columnNames.size();
+ int colSpan = printRownum ? colCount + 1 : colCount;
+
+ writeln("<table>");
+ incrIndent();
+
+ writeln("<tr class=\"title\">");
+ incrIndent();
+ writeln(QString("<td colspan=\"%1\" align=\"center\">%2 <font color=\"#777777\">(%3)</font></td>").arg(colSpan).arg(tr("Table: %1").arg(table), tr("virtual")));
+ decrIndent();
+ writeln("</tr>");
+
+ if (printHeader)
+ {
+ writeln("<tr class=\"header\">");
+ incrIndent();
+ if (printRownum)
+ {
+ writeln("<td align=\"right\">");
+ incrIndent();
+ writeln("<b><i>#</i></b>");
+ decrIndent();
+ writeln("</td>");
+ }
+
+ QString column;
+ for (const QString& col : columnNames)
+ {
+ writeln("<td>");
+ incrIndent();
+ writeln(QString("<b>%1</b>").arg(col));
+ decrIndent();
+ writeln("</td>");
+ }
+ decrIndent();
+ writeln("</tr>");
+ }
+
+ columnTypes.clear();
+ for (int i = 0, total = columnNames.size(); i < total; ++i)
+ columnTypes << DataType();
+
+ currentDataRow = 0;
+ return true;
+}
+
+bool HtmlExport::exportTableRow(SqlResultsRowPtr data)
+{
+ return exportDataRow(data);
+}
+
+bool HtmlExport::afterExportTable()
+{
+ decrIndent();
+ writeln("</table>");
+ writeln("<br/><br/>");
+ return true;
+}
+
+bool HtmlExport::beforeExportDatabase(const QString& database)
+{
+ if (!beginDoc(tr("Exported database: %1").arg(database)))
+ return false;
+
+ return true;
+}
+
+bool HtmlExport::exportIndex(const QString& database, const QString& name, const QString& ddl, SqliteCreateIndexPtr createIndex)
+{
+ UNUSED(database);
+ UNUSED(ddl);
+
+ writeln("<table>");
+ incrIndent();
+
+ writeln("<tr class=\"title\">");
+ incrIndent();
+ writeln(QString("<td align=\"center\" colspan=\"3\">%1</td>").arg(tr("Index: %1").arg("<b>" + name + "</b>")));
+ decrIndent();
+ writeln("</tr>");
+
+ writeln("<tr>");
+ incrIndent();
+ writeln(QString("<td align=\"right\" class=\"rownum\">%1</td>").arg(tr("For table:")));
+ writeln(QString("<td colspan=\"2\">%1</td>").arg(createIndex->table));
+ decrIndent();
+ writeln("</tr>");
+
+ writeln("<tr>");
+ incrIndent();
+ writeln(QString("<td align=\"right\" class=\"rownum\">%1</td>").arg(tr("Unique:")));
+ writeln(QString("<td colspan=\"2\">%1</td>").arg(createIndex->uniqueKw ? tr("Yes") : tr("No")));
+ decrIndent();
+ writeln("</tr>");
+
+ writeln("<tr class=\"header\">");
+ incrIndent();
+ writeln(QString("<td><b>%1</b></td>").arg(tr("Column")));
+ writeln(QString("<td><b>%1</b></td>").arg(tr("Collating")));
+ writeln(QString("<td><b>%1</b></td>").arg(tr("Sort order")));
+ decrIndent();
+ writeln("</tr>");
+
+ for (SqliteIndexedColumn* idxCol : createIndex->indexedColumns)
+ {
+ writeln("<tr>");
+ incrIndent();
+ writeln(QString("<td>%1</td>").arg(escape(idxCol->name)));
+ writeln(QString("<td align=\"center\">%1</td>").arg(idxCol->collate.isNull() ? "&nbsp;" : escape(idxCol->collate)));
+ writeln(QString("<td align=\"center\">%1</td>").arg(idxCol->sortOrder == SqliteSortOrder::null ? "&nbsp;" : sqliteSortOrder(idxCol->sortOrder)));
+ decrIndent();
+ writeln("</tr>");
+ }
+
+ decrIndent();
+ writeln("</table>");
+ writeln("<br/><br/>");
+ return true;
+}
+
+bool HtmlExport::exportTrigger(const QString& database, const QString& name, const QString& ddl, SqliteCreateTriggerPtr createTrigger)
+{
+ UNUSED(database);
+ UNUSED(ddl);
+
+ writeln("<table>");
+ incrIndent();
+
+ writeln("<tr class=\"title\">");
+ incrIndent();
+ writeln(QString("<td align=\"center\" colspan=\"2\">%1</td>").arg(tr("Trigger: %1").arg("<b>" + name + "</b>")));
+ decrIndent();
+ writeln("</tr>");
+
+ writeln("<tr>");
+ incrIndent();
+ writeln(QString("<td align=\"right\" class=\"rownum\">%1</td>").arg(tr("Activated:")));
+ writeln(QString("<td><code>%1</code></td>").arg(SqliteCreateTrigger::time(createTrigger->eventTime)));
+ decrIndent();
+ writeln("</tr>");
+
+ QString event = createTrigger->event ? SqliteCreateTrigger::Event::typeToString(createTrigger->event->type) : "";
+ writeln("<tr>");
+ incrIndent();
+ writeln(QString("<td align=\"right\" class=\"rownum\">%1</td>").arg(tr("Action:")));
+ writeln(QString("<td><code>%1</code></td>").arg(event));
+ decrIndent();
+ writeln("</tr>");
+
+ QString onObj;
+ if (createTrigger->eventTime == SqliteCreateTrigger::Time::INSTEAD_OF)
+ onObj = tr("On view:");
+ else
+ onObj = tr("On table:");
+
+ writeln("<tr>");
+ incrIndent();
+ writeln(QString("<td align=\"right\" class=\"rownum\">%1</td>").arg(onObj));
+ writeln(QString("<td><code>%1</code></td>").arg(createTrigger->table));
+ decrIndent();
+ writeln("</tr>");
+
+ writeln("<tr>");
+ incrIndent();
+ writeln(QString("<td align=\"right\" class=\"rownum\">%1</td>").arg(tr("Activate condition:")));
+ writeln(QString("<td><code>%1</code></td>").arg(createTrigger->precondition ? escape(createTrigger->precondition->detokenize()) : ""));
+ decrIndent();
+ writeln("</tr>");
+
+ writeln("<tr>");
+ incrIndent();
+ writeln(QString("<td colspan=\"2\" class=\"separator\">%1</td>").arg(tr("Code executed:")));
+ decrIndent();
+ writeln("</tr>");
+
+ QStringList queryStrings;
+ for (SqliteQuery* q : createTrigger->queries)
+ queryStrings << escape(q->detokenize());
+
+ writeln("<tr>");
+ incrIndent();
+ writeln("<td colspan=\"2\">");
+ incrIndent();
+ writeln(QString("<pre>%1</pre>").arg(queryStrings.join("<br/>")));
+ decrIndent();
+ writeln("</td>");
+ decrIndent();
+ writeln("</tr>");
+
+ decrIndent();
+ writeln("</table>");
+ writeln("<br/><br/>");
+ return true;
+}
+
+bool HtmlExport::exportView(const QString& database, const QString& name, const QString& ddl, SqliteCreateViewPtr view)
+{
+ UNUSED(database);
+ UNUSED(ddl);
+
+ writeln("<table>");
+ incrIndent();
+
+ writeln("<tr class=\"title\">");
+ incrIndent();
+ writeln(QString("<td align=\"center\">%1</td>").arg(tr("View: %1").arg("<b>" + name + "</b>")));
+ decrIndent();
+ writeln("</tr>");
+
+ writeln("<tr>");
+ incrIndent();
+ writeln("<td>");
+ incrIndent();
+ writeln(QString("<pre>%1</pre>").arg(escape(view->select->detokenize())));
+ decrIndent();
+ writeln("</td>");
+ decrIndent();
+ writeln("</tr>");
+
+ decrIndent();
+ writeln("</table>");
+ writeln("<br/><br/>");
+ return true;
+}
+
+bool HtmlExport::afterExport()
+{
+ static const QString bodyEndTpl = QStringLiteral("</body>");
+ static const QString docEnd = QStringLiteral("</html>");
+
+ writeln("<i>" + tr("Document generated by SQLiteStudio v%1 on %2").arg(SQLITESTUDIO->getVersionString(), QDateTime::currentDateTime().toString()) + "</i>");
+ decrIndent();
+ writeln(bodyEndTpl);
+ decrIndent();
+ writeln(docEnd);
+ return true;
+}
+
+bool HtmlExport::beginDoc(const QString& title)
+{
+ static const QString docStart = QStringLiteral(
+ R"(<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">)"
+ "\n<html>"
+ );
+
+ static const QString metaCodecTpl = QStringLiteral(R"(<meta http-equiv="Content-Type" content="text/html; charset=%1"/>)");
+ static const QString titletpl = QStringLiteral(R"(<title>%1</title>)");
+ static const QString styleStartTpl = QStringLiteral(R"(<style type="text/css">)");
+ static const QString styleEndTpl = QStringLiteral(R"(</style>)");
+ static const QString bodyStartTpl = QStringLiteral(R"(<body>)");
+
+ setupConfig();
+
+ QFile file(":/htmlexport/htmlexport.css");
+ if (!file.open(QIODevice::ReadOnly))
+ {
+ qCritical() << "Could not open htmlexport.css resource while exporting to HTML:" << file.errorString();
+ return false;
+ }
+
+ writeln(docStart);
+ incrIndent();
+ writeln(metaCodecTpl.arg(codecName));
+ writeln(titletpl.arg(title));
+ writeln(styleStartTpl);
+ incrIndent();
+ writeln(indent ? file.readAll() : compressCss(file.readAll()));
+ decrIndent();
+ writeln(styleEndTpl);
+ writeln(bodyStartTpl);
+ incrIndent();
+
+ file.close();
+ return true;
+}
+
+void HtmlExport::setupConfig()
+{
+ codecName = codec->name();
+ indentDepth = 0;
+ newLineStr = "";
+ indentStr = "";
+ indent = (cfg.HtmlExport.Format.get() == "format");
+ if (indent)
+ newLineStr = "\n";
+
+ printRownum = cfg.HtmlExport.PrintRowNum.get();
+ printHeader = cfg.HtmlExport.PrintHeader.get();
+ printDatatypes = printHeader && cfg.HtmlExport.PrintDataTypes.get();
+ byteLengthLimit = cfg.HtmlExport.ByteLengthLimit.get();
+}
+
+void HtmlExport::incrIndent()
+{
+ if (indent)
+ {
+ indentDepth++;
+ updateIndent();
+ }
+}
+
+void HtmlExport::decrIndent()
+{
+ if (indent)
+ {
+ indentDepth--;
+ updateIndent();
+ }
+}
+
+void HtmlExport::updateIndent()
+{
+ indentStr = QString(" ").repeated(indentDepth);
+}
+
+void HtmlExport::writeln(const QString& str)
+{
+ QString newStr;
+ if (str.contains("\n"))
+ {
+ QStringList lines = str.split("\n");
+ QMutableStringListIterator it(lines);
+ while (it.hasNext())
+ it.next().prepend(indentStr);
+
+ newStr = lines.join("\n") + newLineStr;
+ }
+ else
+ {
+ newStr = indentStr + str + newLineStr;
+ }
+ GenericExportPlugin::write(newStr);
+}
+
+QString HtmlExport::escape(const QString& str)
+{
+ if (cfg.HtmlExport.DontEscapeHtml.get())
+ return str;
+
+ return str.toHtmlEscaped();
+}
+
+QString HtmlExport::compressCss(QString css)
+{
+ static const QRegExp spacesLeftRe(R"REGEXP(([^a-zA-Z0-9_\s]+)\s+(\S+))REGEXP");
+ static const QRegExp spacesRightRe(R"REGEXP((\S+)\s+([^a-zA-Z0-9_\s]+))REGEXP");
+ static const QRegExp spacesBetweenWordsRe(R"REGEXP((\S+)\s{2,}(\S+))REGEXP");
+ while (spacesLeftRe.indexIn(css) > -1)
+ css.replace(spacesLeftRe, R"(\1\2)");
+
+ while (spacesRightRe.indexIn(css) > -1)
+ css.replace(spacesRightRe, R"(\1\2)");
+
+ while (spacesBetweenWordsRe.indexIn(css) > -1)
+ css.replace(spacesBetweenWordsRe, R"(\1 \2)");
+
+ return css.trimmed();
+}
+
+bool HtmlExport::init()
+{
+ Q_INIT_RESOURCE(htmlexport);
+ return GenericExportPlugin::init();
+}
+
+void HtmlExport::deinit()
+{
+ Q_CLEANUP_RESOURCE(htmlexport);
+}
diff --git a/Plugins/HtmlExport/htmlexport.css b/Plugins/HtmlExport/htmlexport.css
new file mode 100644
index 0000000..72ebf4f
--- /dev/null
+++ b/Plugins/HtmlExport/htmlexport.css
@@ -0,0 +1,59 @@
+table
+{
+ border-style: solid;
+ border-width: 1px;
+ border-color: black;
+ border-collapse: collapse;
+}
+
+table tr
+{
+ background-color: white;
+}
+
+table tr.header
+{
+ background-color: #DDDDDD;
+}
+
+table tr.title
+{
+ background-color: #EEEEEE;
+}
+
+table tr td
+{
+ padding: 0px 3px 0px 3px;
+ border-style: solid;
+ border-width: 1px;
+ border-color: #666666;
+}
+
+table tr td.null
+{
+ color: #999999;
+ text-align: center;
+ padding: 0px 3px 0px 3px;
+ border-style: solid;
+ border-width: 1px;
+ border-color: #666666;
+}
+
+table tr td.separator
+{
+ padding: 0px 3px 0px 3px;
+ border-style: solid;
+ border-width: 1px;
+ border-color: #666666;
+ background-color: #DDDDDD;
+}
+
+table tr td.rownum
+{
+ padding: 0px 3px 0px 3px;
+ border-style: solid;
+ border-width: 1px;
+ border-color: #666666;
+ background-color: #DDDDDD;
+ text-align: right;
+}
diff --git a/Plugins/HtmlExport/htmlexport.h b/Plugins/HtmlExport/htmlexport.h
new file mode 100644
index 0000000..04a379c
--- /dev/null
+++ b/Plugins/HtmlExport/htmlexport.h
@@ -0,0 +1,74 @@
+#ifndef HTMLEXPORT_H
+#define HTMLEXPORT_H
+
+#include "htmlexport_global.h"
+#include "plugins/genericexportplugin.h"
+#include "config_builder.h"
+
+CFG_CATEGORIES(HtmlExportConfig,
+ CFG_CATEGORY(HtmlExport,
+ CFG_ENTRY(QString, Format, "compress")
+ CFG_ENTRY(bool, PrintRowNum, true)
+ CFG_ENTRY(bool, PrintHeader, true)
+ CFG_ENTRY(bool, PrintDataTypes, true)
+ CFG_ENTRY(bool, DontEscapeHtml, false)
+ CFG_ENTRY(int, ByteLengthLimit, 10000)
+ )
+)
+class HTMLEXPORTSHARED_EXPORT HtmlExport : public GenericExportPlugin
+{
+ Q_OBJECT
+ SQLITESTUDIO_PLUGIN("htmlexport.json")
+
+ public:
+ QString getFormatName() const;
+ ExportManager::StandardConfigFlags standardOptionsToEnable() const;
+ QString getExportConfigFormName() const;
+ CfgMain* getConfig();
+ void validateOptions();
+ QString defaultFileExtension() const;
+ bool beforeExportQueryResults(const QString& query, QList<QueryExecutor::ResultColumnPtr>& columns,
+ const QHash<ExportManager::ExportProviderFlag,QVariant> providedData);
+ bool exportQueryResultsRow(SqlResultsRowPtr row);
+ bool exportTable(const QString& database, const QString& table, const QStringList& columnNames, const QString& ddl, SqliteCreateTablePtr createTable,
+ const QHash<ExportManager::ExportProviderFlag,QVariant> providedData);
+ bool exportVirtualTable(const QString& database, const QString& table, const QStringList& columnNames, const QString& ddl, SqliteCreateVirtualTablePtr createTable,
+ const QHash<ExportManager::ExportProviderFlag,QVariant> providedData);
+ bool exportTableRow(SqlResultsRowPtr data);
+ bool beforeExportDatabase(const QString& database);
+ bool exportIndex(const QString& database, const QString& name, const QString& ddl, SqliteCreateIndexPtr createIndex);
+ bool exportTrigger(const QString& database, const QString& name, const QString& ddl, SqliteCreateTriggerPtr createTrigger);
+ bool exportView(const QString& database, const QString& name, const QString& ddl, SqliteCreateViewPtr view);
+ bool afterExportQueryResults();
+ bool afterExportTable();
+ bool afterExport();
+ bool init();
+ void deinit();
+
+ private:
+ bool beginDoc(const QString& title);
+ bool exportDataRow(SqlResultsRowPtr data);
+ void setupConfig();
+ void incrIndent();
+ void decrIndent();
+ void updateIndent();
+ void writeln(const QString& str);
+ QString escape(const QString& str);
+
+ static QString compressCss(QString css);
+
+ CFG_LOCAL(HtmlExportConfig, cfg)
+ bool indent = false;
+ int indentDepth = 0;
+ QString indentStr;
+ QString newLineStr;
+ QString codecName;
+ int currentDataRow = 0;
+ QList<DataType> columnTypes;
+ bool printRownum = false;
+ bool printHeader = false;
+ bool printDatatypes = false;
+ int byteLengthLimit = 0;
+};
+
+#endif // HTMLEXPORT_H
diff --git a/Plugins/HtmlExport/htmlexport.json b/Plugins/HtmlExport/htmlexport.json
new file mode 100644
index 0000000..530a21d
--- /dev/null
+++ b/Plugins/HtmlExport/htmlexport.json
@@ -0,0 +1,7 @@
+{
+ "type": "ExportPlugin",
+ "title": "HTML export",
+ "description": "Provides HTML format for exporting.",
+ "version": 10000,
+ "author": "SalSoft"
+}
diff --git a/Plugins/HtmlExport/htmlexport.qrc b/Plugins/HtmlExport/htmlexport.qrc
new file mode 100644
index 0000000..77f9482
--- /dev/null
+++ b/Plugins/HtmlExport/htmlexport.qrc
@@ -0,0 +1,8 @@
+<RCC>
+ <qresource prefix="/htmlexport">
+ <file>htmlexport.css</file>
+ </qresource>
+ <qresource prefix="/forms">
+ <file>htmlexport.ui</file>
+ </qresource>
+</RCC>
diff --git a/Plugins/HtmlExport/htmlexport.ui b/Plugins/HtmlExport/htmlexport.ui
new file mode 100644
index 0000000..a4727a4
--- /dev/null
+++ b/Plugins/HtmlExport/htmlexport.ui
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>HtmlExportConfig</class>
+ <widget class="QWidget" name="HtmlExportConfig">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>228</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="4" column="1">
+ <widget class="QSpinBox" name="spinBox">
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="maximum">
+ <number>999999999</number>
+ </property>
+ <property name="cfg" stdset="0">
+ <string>HtmlExport.ByteLengthLimit</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Maximum number of characters per cell:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <widget class="QCheckBox" name="dataTypesCheck">
+ <property name="text">
+ <string>Include data types in first row</string>
+ </property>
+ <property name="cfg" stdset="0">
+ <string>HtmlExport.PrintDataTypes</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QCheckBox" name="colNamesCheck">
+ <property name="text">
+ <string>Column names as first row</string>
+ </property>
+ <property name="cfg" stdset="0">
+ <string>HtmlExport.PrintHeader</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" colspan="2">
+ <widget class="QCheckBox" name="rowNumsCheck">
+ <property name="text">
+ <string>Row numbers as first column</string>
+ </property>
+ <property name="cfg" stdset="0">
+ <string>HtmlExport.PrintRowNum</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0" colspan="2">
+ <widget class="QGroupBox" name="outputFormatGroup">
+ <property name="title">
+ <string>Output format</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="ConfigRadioButton" name="formatRadio">
+ <property name="text">
+ <string>Format document (new lines, indentation)</string>
+ </property>
+ <property name="cfg" stdset="0">
+ <string>HtmlExport.Format</string>
+ </property>
+ <property name="assignedValue" stdset="0">
+ <string>format</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="ConfigRadioButton" name="compressRadio">
+ <property name="text">
+ <string>Compress (everything in one line)</string>
+ </property>
+ <property name="cfg" stdset="0">
+ <string>HtmlExport.Format</string>
+ </property>
+ <property name="assignedValue" stdset="0">
+ <string>compress</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QCheckBox" name="dontEscapeCheck">
+ <property name="toolTip">
+ <string>&lt;p&gt;When enabled, HTML characters such as &amp;lt;, &amp;gt; and &amp;amp; are not escaped in exported values. This allows you for example to export hyper-link enabled documents, but it also may result in incorrect HTML document (unmatched pairs of &amp;lt; and &amp;gt; characters). Be warned.&lt;/p&gt;</string>
+ </property>
+ <property name="text">
+ <string>Don't escape HTML characters</string>
+ </property>
+ <property name="cfg" stdset="0">
+ <string>HtmlExport.DontEscapeHtml</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>ConfigRadioButton</class>
+ <extends>QRadioButton</extends>
+ <header>common/configradiobutton.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Plugins/HtmlExport/htmlexport_global.h b/Plugins/HtmlExport/htmlexport_global.h
new file mode 100644
index 0000000..02671c4
--- /dev/null
+++ b/Plugins/HtmlExport/htmlexport_global.h
@@ -0,0 +1,12 @@
+#ifndef HTMLEXPORT_GLOBAL_H
+#define HTMLEXPORT_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+#if defined(HTMLEXPORT_LIBRARY)
+# define HTMLEXPORTSHARED_EXPORT Q_DECL_EXPORT
+#else
+# define HTMLEXPORTSHARED_EXPORT Q_DECL_IMPORT
+#endif
+
+#endif // HTMLEXPORT_GLOBAL_H