Skip to content
This repository has been archived by the owner on Jan 2, 2023. It is now read-only.

Add support for rendering PDF combobox form control for <select> element #1848

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
75 changes: 67 additions & 8 deletions src/lib/pdfconverter.cc
@@ -1,4 +1,4 @@
// -*- mode: c++; tab-width: 4; indent-tabs-mode: t; eval: (progn (c-set-style "stroustrup") (c-set-offset 'innamespace 0)); -*-
// -*- mode: c++; tab-width: 4; indent-tabs-mode: t; eval: (progn (c-set-style "stroustrup") (c-set-offset "innamespace 0)); -*-
// vi:set ts=4 sts=4 sw=4 noet :
//
// Copyright 2010, 2011 wkhtmltopdf authors
Expand Down Expand Up @@ -72,7 +72,7 @@ struct DLL_LOCAL StreamDumper {

bool DLL_LOCAL looksLikeHtmlAndNotAUrl(QString str) {
QString s = str.split("?")[0];
return s.count('<') > 0 || s.count('<') > 0;
return s.count("<") > 0 || s.count("<") > 0;
}

PdfConverterPrivate::PdfConverterPrivate(PdfGlobal & s, PdfConverter & o) :
Expand Down Expand Up @@ -641,7 +641,7 @@ void PdfConverterPrivate::endPage(PageObject & object, bool hasHeaderFooter, int
painter->drawText(r, Qt::AlignBottom | Qt::AlignHCenter, hfreplace(s.footer.center, parms));
painter->drawText(r, Qt::AlignBottom | Qt::AlignRight, hfreplace(s.footer.right, parms));

//Restore Webkit's crazy scaling and font settings
//Restore Webkit"s crazy scaling and font settings
painter->restore();
}

Expand Down Expand Up @@ -819,14 +819,25 @@ void PdfConverterPrivate::spoolPage(int page) {
if (actualPage != 1)
printer->newPage();

webPrinter->spoolPage(page+1);
foreach (QWebElement elm, pageFormElements[page+1]) {
QString type = elm.attribute("type");
QString tn = elm.tagName();
QString name = elm.attribute("name");
QStringList attributes = elm.attributeNames();
QMap<QString, QString> data;
foreach (const QString &attributeName, attributes) {
if (attributeName.startsWith("data-", Qt::CaseInsensitive)) {
QString name(attributeName);
data.insert(name.replace("data-","", Qt::CaseInsensitive), elm.attribute(attributeName));
}
}
if (tn == "TEXTAREA" || type == "text" || type == "password") {
if (elm.hasAttribute("placeholder")) {
data["placeholder"] = elm.attribute("placeholder");
}
painter->addTextField(
webPrinter->elementLocation(elm).second,
data,
tn == "TEXTAREA"?elm.toPlainText():elm.attribute("value"),
name,
tn == "TEXTAREA",
Expand All @@ -837,11 +848,52 @@ void PdfConverterPrivate::spoolPage(int page) {
} else if (type == "checkbox") {
painter->addCheckBox(
webPrinter->elementLocation(elm).second,
data,
elm.evaluateJavaScript("this.checked;").toBool(),
name,
elm.evaluateJavaScript("this.readonly;").toBool());
}
} else if (type == "hidden") {
painter->addHiddenField(
webPrinter->elementLocation(elm).second,
data,
elm.attribute("value"), name
);
} else if (tn == "SELECT") {
QWebElementCollection options = elm.findAll("option");
QString option_list = "";
QString default_value = "";
QString style = elm.attribute("style");
// so that it will ignore the drawing of the actual combo box
elm.setAttribute("style", "color: transparent; " + style);

foreach (QWebElement opt_elm, options) {
QString text = opt_elm.toPlainText();
QString value = opt_elm.attribute("value");
option_list += "[(" + value + ")(" + text + ")]";
if (opt_elm.evaluateJavaScript("this.selected").toBool()) {
default_value = value;
}
}
option_list = "[" + option_list + "]";
painter->addComboBox(
webPrinter->elementLocation(elm).second,
data,
name,
option_list,
default_value,
elm.evaluateJavaScript("this.readonly;").toBool()
);
} else if (tn == "SCRIPT") {
//add page javascript ONLY if data-acroform-include=true
if (elm.hasAttribute("data-acroform-include") && elm.attribute("data-acroform-include").compare("true", Qt::CaseInsensitive) == 0) {
painter->addPageJavaScript(
data,
elm.toPlainText()
);
}
}
}
webPrinter->spoolPage(page+1);
for (QHash<QString, QWebElement>::iterator i=pageAnchors[page+1].begin();
i != pageAnchors[page+1].end(); ++i) {
QRectF r = webPrinter->elementLocation(i.value()).second;
Expand Down Expand Up @@ -917,10 +969,17 @@ void PdfConverterPrivate::beginPrintObject(PageObject & obj) {
pageExternalLinks[webPrinter->elementLocation(i->first).first].push_back(*i);

if (ps.produceForms) {
foreach (const QWebElement & elm, obj.page->mainFrame()->findAllElements("input"))
pageFormElements[webPrinter->elementLocation(elm).first].push_back(elm);
foreach (const QWebElement & elm, obj.page->mainFrame()->findAllElements("input")) {
int pageNo = webPrinter->elementLocation(elm).first;
pageFormElements[pageNo > 0 ? pageNo : 1].push_back(elm);
}
foreach (const QWebElement & elm, obj.page->mainFrame()->findAllElements("textarea"))
pageFormElements[webPrinter->elementLocation(elm).first].push_back(elm);
foreach (const QWebElement & elm, obj.page->mainFrame()->findAllElements("select"))
pageFormElements[webPrinter->elementLocation(elm).first].push_back(elm);
foreach (const QWebElement & elm, obj.page->mainFrame()->findAllElements("script")) {
pageFormElements[1].push_back(elm);
}
}
emit out.producingForms(obj.settings.produceForms);
out.emitCheckboxSvgs(obj.settings.load);
Expand Down Expand Up @@ -1041,7 +1100,7 @@ void PdfConverterPrivate::printDocument() {
convertionDone = true;
emit out.finished(true);

qApp->exit(0); // quit qt's event handling
qApp->exit(0); // quit qt"s event handling
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change looks unintentional.

}

#ifdef __EXTENSIVE_WKHTMLTOPDF_QT_HACK__
Expand Down