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

Commit

Permalink
Partly fix issue 366: allow for custum SVG for checkboxes and radio b…
Browse files Browse the repository at this point in the history
…uttons
  • Loading branch information
antialize committed Sep 30, 2010
1 parent 39cd4a6 commit a2141b0
Show file tree
Hide file tree
Showing 18 changed files with 111 additions and 85 deletions.
2 changes: 1 addition & 1 deletion common.pri
Expand Up @@ -43,4 +43,4 @@ win32 {
CONFIG += console
}

QT += webkit network xmlpatterns
QT += webkit network xmlpatterns svg
9 changes: 8 additions & 1 deletion include/wkhtmltox/converter.hh
Expand Up @@ -24,8 +24,9 @@
#endif

#include <QObject>

#include <wkhtmltox/loadsettings.hh>
#include <wkhtmltox/dllbegin.inc>

namespace wkhtmltopdf {

class DLL_LOCAL ConverterPrivate;
Expand All @@ -46,11 +47,17 @@ signals:
void phaseChanged();
void progressChanged(int progress);
void finished(bool ok);

void checkboxSvgChanged(const QString & path);
void checkboxCheckedSvgChanged(const QString & path);
void radiobuttonSvgChanged(const QString & path);
void radiobuttonCheckedSvgChanged(const QString & path);
public slots:
void beginConvertion();
bool convert();
void cancel();
protected:
void emitCheckboxSvgs(const settings::LoadPage & ls);
virtual ConverterPrivate & priv() = 0;
friend class ConverterPrivate;
};
Expand Down
10 changes: 8 additions & 2 deletions include/wkhtmltox/dllbegin.inc
Expand Up @@ -37,10 +37,16 @@
#endif
#endif

#if defined _WIN32
#define CALLTYPE __stdcall
#else
#define CALLTYPE
#endif

#ifdef __cplusplus
#define CAPI extern "C" DLL_PUBLIC
#define CAPI extern "C" DLL_PUBLIC CALLTYPE
#else
#define CAPI DLL_PUBLIC
#define CAPI DLL_PUBLIC CALLTYPE
#endif

#endif /*__WKHTMLTOPDF_DLLBEGIN__*/
1 change: 1 addition & 0 deletions include/wkhtmltox/dllend.inc
Expand Up @@ -23,5 +23,6 @@
#undef DLL_PUBLIC
#undef DLL_LOCAL
#undef CAPI
#undef CALLTYPE

#endif /*__WKHTMLTOPDF_DLLBEGIN__*/
5 changes: 5 additions & 0 deletions include/wkhtmltox/loadsettings.hh
Expand Up @@ -110,6 +110,11 @@ struct DLL_PUBLIC LoadPage {

//! Additional javascript to run on a page once it has loaded
QList< QString > runScript;

QString checkboxSvg;
QString checkboxCheckedSvg;
QString radiobuttonSvg;
QString radiobuttonCheckedSvg;
};

DLL_PUBLIC LoadPage::LoadErrorHandling strToLoadErrorHandling(const char * s, bool * ok=0);
Expand Down
10 changes: 10 additions & 0 deletions include/wkhtmltox/utilities.hh
Expand Up @@ -30,6 +30,7 @@
#include <QImageWriter>
#include <QPainter>
#include <QStyleOption>
#include <QSvgRenderer>
#include <QUrl>

#include <wkhtmltox/dllbegin.inc>
Expand All @@ -43,8 +44,17 @@ public:
MyLooksStyle();
void drawPrimitive( PrimitiveElement element, const QStyleOption * option, QPainter * painter, const QWidget * widget = 0 ) const;
bool weAreDrawingForms;

static QSvgRenderer * checkbox;
static QSvgRenderer * checkbox_checked;
static QSvgRenderer * radiobutton;
static QSvgRenderer * radiobutton_checked;
public slots:
void producingForms(bool f);
void setCheckboxSvg(const QString & path);
void setCheckboxCheckedSvg(const QString & path);
void setRadioButtonSvg(const QString & path);
void setRadioButtonCheckedSvg(const QString & path);
};

DLL_PUBLIC int handleError(bool success, int errorCode);
Expand Down
9 changes: 7 additions & 2 deletions src/image/wkhtmltoimage.cc
Expand Up @@ -43,11 +43,16 @@ int main(int argc, char** argv) {
#endif
#endif
QApplication a(argc, argv, use_graphics);
a.setStyle(new MyLooksStyle());
MyLooksStyle * style = new MyLooksStyle();
a.setStyle(style);

//Create the actual page converter to convert the pages
wkhtmltopdf::ImageConverter converter(settings);

QObject::connect(&converter, SIGNAL(checkboxSvgChanged(const QString &)), style, SLOT(setCheckboxSvg(const QString &)));
QObject::connect(&converter, SIGNAL(checkboxCheckedSvgChanged(const QString &)), style, SLOT(setCheckboxCheckedSvg(const QString &)));
QObject::connect(&converter, SIGNAL(radiobuttonSvgChanged(const QString &)), style, SLOT(setRadioButtonSvg(const QString &)));
QObject::connect(&converter, SIGNAL(radiobuttonCheckedSvgChanged(const QString &)), style, SLOT(setRadioButtonCheckedSvg(const QString &)));

wkhtmltopdf::ProgressFeedback feedback(settings.quiet, converter);
bool success = converter.convert();
return handleError(success, converter.httpErrorCode());
Expand Down
6 changes: 6 additions & 0 deletions src/lib/converter.cc
Expand Up @@ -154,5 +154,11 @@ void Converter::cancel() {
priv().cancel();
}

void Converter::emitCheckboxSvgs(const settings::LoadPage & ls) {
emit checkboxSvgChanged(ls.checkboxSvg);
emit checkboxCheckedSvgChanged(ls.checkboxCheckedSvg);
emit radiobuttonSvgChanged(ls.radiobuttonSvg);
emit radiobuttonCheckedSvgChanged(ls.radiobuttonCheckedSvg);
}

}
9 changes: 8 additions & 1 deletion src/lib/converter.hh
Expand Up @@ -27,8 +27,9 @@
#endif

#include <QObject>

#include <wkhtmltox/loadsettings.hh>
#include <wkhtmltox/dllbegin.inc>

namespace wkhtmltopdf {

class DLL_LOCAL ConverterPrivate;
Expand All @@ -49,11 +50,17 @@ signals:
void phaseChanged();
void progressChanged(int progress);
void finished(bool ok);

void checkboxSvgChanged(const QString & path);
void checkboxCheckedSvgChanged(const QString & path);
void radiobuttonSvgChanged(const QString & path);
void radiobuttonCheckedSvgChanged(const QString & path);
public slots:
void beginConvertion();
bool convert();
void cancel();
protected:
void emitCheckboxSvgs(const settings::LoadPage & ls);
virtual ConverterPrivate & priv() = 0;
friend class ConverterPrivate;
};
Expand Down
4 changes: 3 additions & 1 deletion src/lib/imageconverter.cc
Expand Up @@ -45,6 +45,7 @@ ImageConverterPrivate::ImageConverterPrivate(ImageConverter & o, wkhtmltopdf::se
settings(s),
loader(s.loadGlobal),
out(o) {
out.emitCheckboxSvgs(s.loadPage);
if (data) inputData = *data;

phaseDescriptions.push_back("Loading page");
Expand Down Expand Up @@ -148,6 +149,7 @@ void ImageConverterPrivate::pagesLoaded(bool ok) {
} if (settings.out != "-" ) {
file.setFileName(settings.out);
openOk = file.open(QIODevice::WriteOnly);
qDebug() << "HERE" << endl;
} else {
openOk = file.open(stdout, QIODevice::WriteOnly);
}
Expand All @@ -166,7 +168,7 @@ void ImageConverterPrivate::pagesLoaded(bool ok) {
emit out.error("Will not output an empty image");
fail();
}

if (settings.fmt != "svg") {
image = QImage(rect.size(), QImage::Format_ARGB32_Premultiplied);
painter.begin(&image);
Expand Down
3 changes: 0 additions & 3 deletions src/lib/lib.pri
Expand Up @@ -32,9 +32,6 @@ HEADERS += ../lib/pdfconverter_p.hh
SOURCES += ../lib/pdfsettings.cc ../lib/pdfconverter.cc \
../lib/outline.cc ../lib/tocstylesheet.cc

#Image
QT += svg

PUBLIC_HEADERS += ../lib/imageconverter.hh ../lib/imagesettings.hh
HEADERS += ../lib/imageconverter_p.hh
SOURCES += ../lib/imagesettings.cc ../lib/imageconverter.cc
Expand Down
5 changes: 5 additions & 0 deletions src/lib/loadsettings.hh
Expand Up @@ -113,6 +113,11 @@ struct DLL_PUBLIC LoadPage {

//! Additional javascript to run on a page once it has loaded
QList< QString > runScript;

QString checkboxSvg;
QString checkboxCheckedSvg;
QString radiobuttonSvg;
QString radiobuttonCheckedSvg;
};

DLL_PUBLIC LoadPage::LoadErrorHandling strToLoadErrorHandling(const char * s, bool * ok=0);
Expand Down
3 changes: 2 additions & 1 deletion src/lib/pdfconverter.cc
Expand Up @@ -667,7 +667,8 @@ void PdfConverterPrivate::printDocument() {
foreach (const QWebElement & elm, obj.page->mainFrame()->findAllElements("textarea"))
myFormElements[wp.elementLocation(elm).first].push_back(elm);
}
emit out.producingForms( obj.settings.produceForms);
emit out.producingForms(obj.settings.produceForms);
out.emitCheckboxSvgs(obj.settings.load);
for (int p=0; p < wp.pageCount(); ++p) {
for (int pc_=0; pc_ < pc; ++pc_) {
beginPage(actualPage);
Expand Down
4 changes: 4 additions & 0 deletions src/lib/reflect.cc
Expand Up @@ -71,6 +71,10 @@ ReflectImpl<LoadPage>::ReflectImpl(LoadPage & c) {
WKHTMLTOPDF_REFLECT(loadErrorHandling);
WKHTMLTOPDF_REFLECT(proxy);
WKHTMLTOPDF_REFLECT(runScript);
WKHTMLTOPDF_REFLECT(checkboxSvg);
WKHTMLTOPDF_REFLECT(checkboxCheckedSvg);
WKHTMLTOPDF_REFLECT(radiobuttonSvg);
WKHTMLTOPDF_REFLECT(radiobuttonCheckedSvg);
}

ReflectImpl<Web>::ReflectImpl(Web & c) {
Expand Down
103 changes: 30 additions & 73 deletions src/lib/utilities.cc
Expand Up @@ -34,77 +34,22 @@ Q_IMPORT_PLUGIN(qtiff)
Q_IMPORT_PLUGIN(qmng)
#endif

MyLooksStyle::MyLooksStyle(): weAreDrawingForms(false) {
if (checkbox == 0)
checkbox = new QSvgRenderer(QByteArray(
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"
"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"
" version=\"1.1\" baseProfile=\"full\" width=\"12px\" height=\"12px\" viewBox=\"0 0 12px 12px\">\n"
" <rect x=\"0\" y=\"0\" width=\"1\" height=\"12\" fill=\"#808080\" />\n"
" <rect x=\"1\" y=\"0\" width=\"11\" height=\"1\" fill=\"#808080\" />\n"
" <rect x=\"1\" y=\"11\" width=\"11\" height=\"1\" fill=\"#d4d0c8\" />\n"
" <rect x=\"11\" y=\"1\" width=\"1\" height=\"11\" fill=\"#d4d0c8\" />\n"
" <rect x=\"1\" y=\"1\" width=\"1\" height=\"10\" fill=\"#404040\" />\n"
" <rect x=\"2\" y=\"1\" width=\"9\" height=\"1\" fill=\"#404040\" />\n"
" <rect x=\"2\" y=\"10\" width=\"9\" height=\"1\" fill=\"white\" />\n"
" <rect x=\"10\" y=\"2\" width=\"1\" height=\"9\" fill=\"white\" />\n"
" <rect x=\"2\" y=\"2\" width=\"8\" height=\"8\" fill=\"white\" />\n"
"</svg>\n"));
if (checkbox_checked == 0)
checkbox_checked = new QSvgRenderer(QByteArray(
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"
"<svg xmlns=\"http://www.w3.org/2000/svg\"\n"
" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"
" version=\"1.1\" baseProfile=\"full\" width=\"12px\" height=\"12px\" viewBox=\"0 0 12px 12px\">\n"
" <rect x=\"0\" y=\"0\" width=\"1\" height=\"12\" fill=\"#808080\" />\n"
" <rect x=\"1\" y=\"0\" width=\"11\" height=\"1\" fill=\"#808080\" />\n"
" <rect x=\"1\" y=\"11\" width=\"11\" height=\"1\" fill=\"#d4d0c8\" />\n"
" <rect x=\"11\" y=\"1\" width=\"1\" height=\"11\" fill=\"#d4d0c8\" />\n"
" <rect x=\"1\" y=\"1\" width=\"1\" height=\"10\" fill=\"#404040\" />\n"
" <rect x=\"2\" y=\"1\" width=\"9\" height=\"1\" fill=\"#404040\" />\n"
" <rect x=\"2\" y=\"10\" width=\"9\" height=\"1\" fill=\"white\" />\n"
" <rect x=\"10\" y=\"2\" width=\"1\" height=\"9\" fill=\"white\" />\n"
" <rect x=\"2\" y=\"2\" width=\"8\" height=\"8\" fill=\"white\" />\n"
" <path d=\"M 3 5.5 L 3 8 L 5.5 10.5 L 10 5.5 L 10 2.5 L 5.5 7.5\" fill=\"black\" />\n"
"</svg>\n"));
if (radiobutton == 0)
radiobutton = new QSvgRenderer(QByteArray(
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"
"<svg xmlns=\"http://www.w3.org/2000/svg\"\n"
" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"
" version=\"1.1\" baseProfile=\"full\" width=\"11px\" height=\"11px\" viewBox=\"0 0 11px 11px\">\n"
" <clipPath id=\"upleftclip\"><path d=\"M 11 0 L 0 0 L 0 11\"/></clipPath>\n"
" <clipPath id=\"downrightclip\"><path d=\"M 11 0 L 11 11 L 0 11\"/></clipPath>\n"
" <circle cx=\"5.5\" cy=\"5.5\" r=\"5.5\" fill=\"#808080\" clip-path=\"url(#upleftclip)\" />\n"
" <circle cx=\"5.5\" cy=\"5.5\" r=\"5.5\" fill=\"white\" clip-path=\"url(#downrightclip)\" />\n"
" <circle cx=\"5.5\" cy=\"5.5\" r=\"4.5\" fill=\"#404040\" clip-path=\"url(#upleftclip)\" />\n"
" <circle cx=\"5.5\" cy=\"5.5\" r=\"4.5\" fill=\"#d4d0c8\" clip-path=\"url(#downrightclip)\" />\n"
" <circle cx=\"5.5\" cy=\"5.5\" r=\"3.5\" fill=\"white\"/>\n"
"</svg>\n"));
if (radiobutton_checked == 0)
radiobutton_checked = new QSvgRenderer(QByteArray(
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"
"<svg xmlns=\"http://www.w3.org/2000/svg\"\n"
" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n"
" version=\"1.1\" baseProfile=\"full\" width=\"11px\" height=\"11px\" viewBox=\"0 0 11px 11px\">\n"
" <clipPath id=\"upleftclip\"><path d=\"M 11 0 L 0 0 L 0 11\"/></clipPath>\n"
" <clipPath id=\"downrightclip\"><path d=\"M 11 0 L 11 11 L 0 11\"/></clipPath>\n"
" <circle cx=\"5.5\" cy=\"5.5\" r=\"5.5\" fill=\"#808080\" clip-path=\"url(#upleftclip)\" />\n"
" <circle cx=\"5.5\" cy=\"5.5\" r=\"5.5\" fill=\"white\" clip-path=\"url(#downrightclip)\" />\n"
" <circle cx=\"5.5\" cy=\"5.5\" r=\"4.5\" fill=\"#404040\" clip-path=\"url(#upleftclip)\" />\n"
" <circle cx=\"5.5\" cy=\"5.5\" r=\"4.5\" fill=\"#d4d0c8\" clip-path=\"url(#downrightclip)\" />\n"
" <circle cx=\"5.5\" cy=\"5.5\" r=\"3.5\" fill=\"white\" />\n"
" <circle cx=\"5.5\" cy=\"5.5\" r=\"1.5\" fill=\"black\" />\n"
"</svg>\n"));
void loadSvg(QSvgRenderer * & ptr, const QString & path) {
delete ptr;
ptr = new QSvgRenderer(path);
if (ptr->isValid()) return;
delete ptr;
ptr = 0;
}

void MyLooksStyle::producingForms(bool f) {
weAreDrawingForms=f;
}
void MyLooksStyle::setCheckboxSvg(const QString & path) {loadSvg(checkbox, path);}
void MyLooksStyle::setCheckboxCheckedSvg(const QString & path) {loadSvg(checkbox_checked, path);}
void MyLooksStyle::setRadioButtonSvg(const QString & path) {loadSvg(radiobutton, path);}
void MyLooksStyle::setRadioButtonCheckedSvg(const QString & path) {loadSvg(radiobutton_checked, path);}

MyLooksStyle::MyLooksStyle(): weAreDrawingForms(false) {}

void MyLooksStyle::producingForms(bool f) {weAreDrawingForms=f;}

void MyLooksStyle::drawPrimitive( PrimitiveElement element, const QStyleOption * option, QPainter * painter, const QWidget * widget) const {
painter->setBrush(Qt::white);
Expand All @@ -115,16 +60,28 @@ void MyLooksStyle::drawPrimitive( PrimitiveElement element, const QStyleOption *
if (element == QStyle::PE_PanelLineEdit) {
painter->drawRect(r);
} else if (element == QStyle::PE_IndicatorCheckBox) {
if (weAreDrawingForms)
if (weAreDrawingForms || ((option->state & QStyle::State_On)? !checkbox_checked: !checkbox)) {
painter->drawRect(r);
else if (option->state & QStyle::State_On)
if (!weAreDrawingForms && (option->state & QStyle::State_On)) {
r.translate(int(r.width()*0.075), int(r.width()*0.075));
painter->drawLine(r.topLeft(), r.bottomRight());
painter->drawLine(r.topRight(), r.bottomLeft());
}
} else if (option->state & QStyle::State_On)
checkbox_checked->render(painter, r);
else
checkbox->render(painter, r);
} else if (element == QStyle::PE_IndicatorRadioButton) {
if (weAreDrawingForms)
if (weAreDrawingForms || ((option->state & QStyle::State_On)? !radiobutton_checked: !radiobutton)) {
painter->drawEllipse(r);
else if (option->state & QStyle::State_On)
if (!weAreDrawingForms && (option->state & QStyle::State_On)) {
r.translate(int(r.width()*0.20), int(r.width()*0.20));
r.setWidth(int(r.width()*0.70));
r.setHeight(int(r.height()*0.70));
painter->setBrush(Qt::black);
painter->drawEllipse(r);
}
} else if (option->state & QStyle::State_On)
radiobutton_checked->render(painter, r);
else
radiobutton->render(painter, r);
Expand Down
4 changes: 4 additions & 0 deletions src/lib/utilities.hh
Expand Up @@ -54,6 +54,10 @@ public:
static QSvgRenderer * radiobutton_checked;
public slots:
void producingForms(bool f);
void setCheckboxSvg(const QString & path);
void setCheckboxCheckedSvg(const QString & path);
void setRadioButtonSvg(const QString & path);
void setRadioButtonCheckedSvg(const QString & path);
};

DLL_PUBLIC int handleError(bool success, int errorCode);
Expand Down
5 changes: 5 additions & 0 deletions src/pdf/wkhtmltopdf.cc
Expand Up @@ -169,6 +169,11 @@ int main(int argc, char * argv[]) {
//Create the actual page converter to convert the pages
PdfConverter converter(globalSettings);
QObject::connect(&converter, SIGNAL(producingForms(bool)), style, SLOT(producingForms(bool)));
QObject::connect(&converter, SIGNAL(checkboxSvgChanged(const QString &)), style, SLOT(setCheckboxSvg(const QString &)));
QObject::connect(&converter, SIGNAL(checkboxCheckedSvgChanged(const QString &)), style, SLOT(setCheckboxCheckedSvg(const QString &)));
QObject::connect(&converter, SIGNAL(radiobuttonSvgChanged(const QString &)), style, SLOT(setRadioButtonSvg(const QString &)));
QObject::connect(&converter, SIGNAL(radiobuttonCheckedSvgChanged(const QString &)), style, SLOT(setRadioButtonCheckedSvg(const QString &)));

ProgressFeedback feedback(globalSettings.quiet, converter);
foreach (const PdfObject & object, objectSettings)
converter.addResource(object);
Expand Down
4 changes: 4 additions & 0 deletions src/shared/commonarguments.cc
Expand Up @@ -226,4 +226,8 @@ void CommandLineParserBase::addPageLoadArgs(LoadPage & s) {
#endif
addarg("run-script", 0, "Run this additional javascript after the page is done loading (repeatable)", new StringListSetter(s.runScript, "js"));

addarg("checkbox-svg", 0, "Use this SVG file when rendering unchecked checkboxes", new QStrSetter(s.checkboxSvg, "path", ""));
addarg("checkbox-checked-svg", 0, "Use this SVG file when rendering checked checkboxes", new QStrSetter(s.checkboxCheckedSvg, "path" ,""));
addarg("radiobutton-svg", 0, "Use this SVG file when rendering unchecked radiobuttons", new QStrSetter(s.radiobuttonSvg, "path", ""));
addarg("radiobutton-checked-svg", 0, "Use this SVG file when rendering checked radiobuttons", new QStrSetter(s.radiobuttonCheckedSvg, "path", ""));
}

0 comments on commit a2141b0

Please sign in to comment.