// -*- 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 wkhtmltopdf authors // // This file is part of wkhtmltopdf. // // wkhtmltopdf is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // wkhtmltopdf 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 Lesser General Public License // along with wkhtmltopdf. If not, see . #ifdef _MSC_VER #define strcasecmp _stricmp #endif #include "pdfsettings.hh" #include "reflect.hh" #include #include #include "dllbegin.inc" namespace wkhtmltopdf { namespace settings { template<> struct DLL_LOCAL ReflectImpl: public ReflectSimple { UnitReal & ur; ReflectImpl(UnitReal & _): ur(_) {} QString get() {bool d; return unitRealToStr(ur, &d);} void set(const QString & value, bool * ok) {ur = strToUnitReal(value.toUtf8().constData(), ok);} }; template<> struct DLL_LOCAL ReflectImpl: public ReflectSimple { QPrinter::PageSize & ps; ReflectImpl(QPrinter::PageSize & _): ps(_) {} QString get() {return pageSizeToStr(ps);} void set(const QString & value, bool * ok) {ps = strToPageSize(value.toUtf8().constData(), ok);} }; template<> struct DLL_LOCAL ReflectImpl: public ReflectSimple { QPrinter::Orientation & o; ReflectImpl(QPrinter::Orientation & _): o(_) {} QString get() {return orientationToStr(o);} void set(const QString & value, bool * ok) {o = strToOrientation(value.toUtf8().constData(), ok);} }; template<> struct DLL_LOCAL ReflectImpl: public ReflectSimple { QPrinter::PrinterMode & m; ReflectImpl(QPrinter::PrinterMode & _): m(_) {} QString get() {return printerModeToStr(m);} void set(const QString & value, bool * ok) {m = strToPrinterMode(value.toUtf8().constData(), ok);} }; template<> struct DLL_LOCAL ReflectImpl: public ReflectSimple { QPrinter::ColorMode & m; ReflectImpl(QPrinter::ColorMode & _): m(_) {} QString get() {return colorModeToStr(m);} void set(const QString & value, bool * ok) {m = strToColorMode(value.toUtf8().constData(), ok);} }; template<> struct DLL_LOCAL ReflectImpl: public ReflectClass { ReflectImpl(Margin & c) { WKHTMLTOPDF_REFLECT(top); WKHTMLTOPDF_REFLECT(right); WKHTMLTOPDF_REFLECT(bottom); WKHTMLTOPDF_REFLECT(left); } }; template<> struct DLL_LOCAL ReflectImpl: public ReflectClass { ReflectImpl(Size & c) { WKHTMLTOPDF_REFLECT(pageSize); WKHTMLTOPDF_REFLECT(height); WKHTMLTOPDF_REFLECT(width); } }; template<> struct DLL_LOCAL ReflectImpl: public ReflectClass { ReflectImpl(TableOfContent & c) { WKHTMLTOPDF_REFLECT(useDottedLines); WKHTMLTOPDF_REFLECT(captionText); WKHTMLTOPDF_REFLECT(forwardLinks); WKHTMLTOPDF_REFLECT(backLinks); WKHTMLTOPDF_REFLECT(indentation); WKHTMLTOPDF_REFLECT(fontScale); } }; template<> struct DLL_LOCAL ReflectImpl: public ReflectClass { ReflectImpl(PdfGlobal & c) { WKHTMLTOPDF_REFLECT(size); WKHTMLTOPDF_REFLECT(quiet); WKHTMLTOPDF_REFLECT(useGraphics); WKHTMLTOPDF_REFLECT(resolveRelativeLinks); WKHTMLTOPDF_REFLECT(orientation); WKHTMLTOPDF_REFLECT(colorMode); WKHTMLTOPDF_REFLECT(resolution); WKHTMLTOPDF_REFLECT(dpi); WKHTMLTOPDF_REFLECT(pageOffset); WKHTMLTOPDF_REFLECT(copies); WKHTMLTOPDF_REFLECT(collate); WKHTMLTOPDF_REFLECT(outline); WKHTMLTOPDF_REFLECT(dumpOutline); WKHTMLTOPDF_REFLECT(out); WKHTMLTOPDF_REFLECT(documentTitle); WKHTMLTOPDF_REFLECT(useCompression); WKHTMLTOPDF_REFLECT(margin); WKHTMLTOPDF_REFLECT(imageDPI); WKHTMLTOPDF_REFLECT(imageQuality); WKHTMLTOPDF_REFLECT(load); } }; template<> struct DLL_LOCAL ReflectImpl: public ReflectClass { ReflectImpl(HeaderFooter & c) { WKHTMLTOPDF_REFLECT(fontSize); WKHTMLTOPDF_REFLECT(fontName); WKHTMLTOPDF_REFLECT(left); WKHTMLTOPDF_REFLECT(right); WKHTMLTOPDF_REFLECT(center); WKHTMLTOPDF_REFLECT(line); WKHTMLTOPDF_REFLECT(htmlUrl); WKHTMLTOPDF_REFLECT(spacing); } }; template<> struct DLL_LOCAL ReflectImpl: public ReflectClass { ReflectImpl(PdfObject & c) { WKHTMLTOPDF_REFLECT(toc); WKHTMLTOPDF_REFLECT(page); WKHTMLTOPDF_REFLECT(header); WKHTMLTOPDF_REFLECT(footer); WKHTMLTOPDF_REFLECT(useExternalLinks); WKHTMLTOPDF_REFLECT(useLocalLinks); WKHTMLTOPDF_REFLECT(replacements); WKHTMLTOPDF_REFLECT(produceForms); WKHTMLTOPDF_REFLECT(load); WKHTMLTOPDF_REFLECT(web); WKHTMLTOPDF_REFLECT(includeInOutline); WKHTMLTOPDF_REFLECT(pagesCount); WKHTMLTOPDF_REFLECT(isTableOfContent); WKHTMLTOPDF_REFLECT(tocXsl); } }; /*! \file settings.hh \brief Defines the Settings class */ DLL_LOCAL QMap pageSizeMap() { QMap res; res["A0"] = QPrinter::A0; res["A1"] = QPrinter::A1; res["A2"] = QPrinter::A2; res["A3"] = QPrinter::A3; res["A4"] = QPrinter::A4; res["A5"] = QPrinter::A5; res["A6"] = QPrinter::A6; res["A7"] = QPrinter::A7; res["A8"] = QPrinter::A8; res["A9"] = QPrinter::A9; res["B0"] = QPrinter::B0; res["B1"] = QPrinter::B1; res["B10"] = QPrinter::B10; res["B2"] = QPrinter::B2; res["B3"] = QPrinter::B3; res["B4"] = QPrinter::B4; res["B5"] = QPrinter::B5; res["B6"] = QPrinter::B6; res["B7"] = QPrinter::B7; res["B8"] = QPrinter::B8; res["B9"] = QPrinter::B9; res["C5E"] = QPrinter::C5E; res["Comm10E"] = QPrinter::Comm10E; res["DLE"] = QPrinter::DLE; res["Executive"] = QPrinter::Executive; res["Folio"] = QPrinter::Folio; res["Ledger"] = QPrinter::Ledger; res["Legal"] = QPrinter::Legal; res["Letter"] = QPrinter::Letter; res["Tabloid"] = QPrinter::Tabloid; return res; } /*! Convert a string to a paper size, basically all thinkable values are allowed. if a unknown value is given A4 is returned \param s The string to convert \param ok If supplied indicates if the conversion was successful */ QPrinter::PageSize strToPageSize(const char * s, bool * ok) { QMap map = pageSizeMap(); for (QMap::const_iterator i=map.begin(); i != map.end(); ++i) { if (i.key().compare(s, Qt::CaseInsensitive) != 0) continue; if (ok) *ok=true; return i.value(); } if (ok) *ok = false; return QPrinter::A4; } QString pageSizeToStr(QPrinter::PageSize ps) { QMap map = pageSizeMap(); for (QMap::const_iterator i=map.begin(); i != map.end(); ++i) { if (i.value() == ps) return i.key(); } return ""; } /*! Read orientation from a string, possible values are landscape and portrait (case insensitive) \param s The string containing the orientation \param ok If supplied indicates whether the s was valid */ QPrinter::Orientation strToOrientation(const char * s, bool * ok) { if (ok) *ok = true; if (!strcasecmp(s,"Landscape")) return QPrinter::Landscape; if (!strcasecmp(s,"Portrait")) return QPrinter::Portrait; if (ok) *ok = false; return QPrinter::Portrait; } QString orientationToStr(QPrinter::Orientation o) { return (o == QPrinter::Landscape)?"Landscape":"Portrait"; } /*! Parse a string describing a distance, into a real number and a unit. \param o Tho string describing the distance \param ok If supplied indicates whether the s was valid */ UnitReal strToUnitReal(const char * o, bool * ok) { qreal s=1.0; //Since not all units are provided by qt, we use this variable to scale //Them into units that are. QPrinter::Unit u=QPrinter::Millimeter; //Skip the real number part int i=0; while ('0' <= o[i] && o[i] <= '9') ++i; if (o[i] == '.' || o[i] == '.') ++i; while ('0' <= o[i] && o[i] <= '9') ++i; //Try to match the unit used if (!strcasecmp(o+i,"") || !strcasecmp(o+i,"mm") || !strcasecmp(o+i,"millimeter")) { u=QPrinter::Millimeter; } else if (!strcasecmp(o+i,"cm") || !strcasecmp(o+i,"centimeter")) { u=QPrinter::Millimeter; s=10.0; //1cm=10mm } else if (!strcasecmp(o+i,"m") || !strcasecmp(o+i,"meter")) { u=QPrinter::Millimeter; s=1000.0; //1m=1000m } else if (!strcasecmp(o+i,"didot")) u=QPrinter::Didot; //Todo is there a short for didot?? else if (!strcasecmp(o+i,"inch") || !strcasecmp(o+i,"in")) u=QPrinter::Inch; else if (!strcasecmp(o+i,"pica") || !strcasecmp(o+i,"pc")) u=QPrinter::Pica; else if (!strcasecmp(o+i,"cicero")) u=QPrinter::Cicero; else if (!strcasecmp(o+i,"pixel") || !strcasecmp(o+i,"px")) u=QPrinter::DevicePixel; else if (!strcasecmp(o+i,"point") || !strcasecmp(o+i,"pt")) u=QPrinter::Point; else { if (ok) *ok=false; return UnitReal(QString(o).left(i).toDouble()*s, u); } return UnitReal(QString(o).left(i).toDouble(ok)*s, u); } QString unitRealToStr(const UnitReal & ur, bool * ok) { QString c; if (ur.first == -1) { if (ok) *ok=false; return ""; } if (ok) *ok=true; switch (ur.second) { case QPrinter::Didot: c = "didot"; break; case QPrinter::Inch: c = "in"; break; case QPrinter::Pica: c = "pica"; break; case QPrinter::DevicePixel: c = "px"; break; case QPrinter::Point: c = "pt"; break; case QPrinter::Millimeter: c = "mm"; break; default: if (ok) *ok=false; break; } return QString("%1%2").arg(ur.first).arg(c); } QPrinter::PrinterMode strToPrinterMode(const char * s, bool * ok) { if (ok) *ok=true; if (!strcasecmp(s,"screen")) return QPrinter::ScreenResolution; if (!strcasecmp(s,"printer")) return QPrinter::PrinterResolution; if (!strcasecmp(s,"high")) return QPrinter::HighResolution; *ok=false; return QPrinter::HighResolution; } QString printerModeToStr(QPrinter::PrinterMode o) { switch (o) { case QPrinter::ScreenResolution: return "screen"; case QPrinter::PrinterResolution: return "printer"; case QPrinter::HighResolution: return "high"; } return QString(); } QPrinter::ColorMode strToColorMode(const char * s, bool * ok) { if (ok) *ok=true; if (!strcasecmp(s,"color")) return QPrinter::Color; if (!strcasecmp(s,"grayscale")) return QPrinter::GrayScale; *ok=false; return QPrinter::Color; } QString colorModeToStr(QPrinter::ColorMode o) { switch (o) { case QPrinter::Color: return "color"; case QPrinter::GrayScale: return "grayscale"; } return QString(); } Size::Size(): pageSize(QPrinter::A4), height(UnitReal(-1,QPrinter::Millimeter)), width(UnitReal(-1,QPrinter::Millimeter)) {} HeaderFooter::HeaderFooter(): fontSize(12), fontName("Arial"), left(""), right(""), center(""), line(false), htmlUrl(""), spacing(0.0) {} Margin::Margin(): top(UnitReal(-1,QPrinter::Millimeter)), right(UnitReal(10,QPrinter::Millimeter)), bottom(UnitReal(-1,QPrinter::Millimeter)), left(UnitReal(10,QPrinter::Millimeter)) {} PdfGlobal::PdfGlobal(): quiet(false), useGraphics(false), resolveRelativeLinks(true), orientation(QPrinter::Portrait), colorMode(QPrinter::Color), resolution(QPrinter::HighResolution), dpi(-1), pageOffset(0), copies(1), collate(true), outline(true), outlineDepth(4), dumpOutline(""), out(""), documentTitle(""), useCompression(true), viewportSize(""), imageDPI(600), imageQuality(94){}; TableOfContent::TableOfContent(): useDottedLines(true), captionText("Table of Contents"), forwardLinks(true), backLinks(false), indentation("1em"), fontScale(0.8f) {} PdfObject::PdfObject(): useExternalLinks(true), useLocalLinks(true), produceForms(false), includeInOutline(true), pagesCount(true), isTableOfContent(false), tocXsl("") {}; QString PdfGlobal::get(const char * name) { ReflectImpl impl(*this); return impl.get(name); } bool PdfGlobal::set(const char * name, const QString & value) { ReflectImpl impl(*this); return impl.set(name, value); } QString PdfObject::get(const char * name) { ReflectImpl impl(*this); return impl.get(name); } bool PdfObject::set(const char * name, const QString & value) { ReflectImpl impl(*this); return impl.set(name, value); } } }