Преглед изворни кода

Merge branch 'master' of git@github.com:antialize/wkhtmltopdf

Jakob Truelsen пре 16 година
родитељ
комит
62763eaa97
9 измењених фајлова са 340 додато и 128 уклоњено
  1. 1 1
      Doxyfile
  2. 112 0
      src/outline.cc
  3. 39 0
      src/outline.hh
  4. 43 0
      src/outline_p.hh
  5. 93 121
      src/pageconverter.cc
  6. 8 1
      src/pageconverter_p.hh
  7. 2 2
      src/settings.cc
  8. 37 0
      src/tocprinter.hh
  9. 5 3
      wkhtmltopdf.pro

+ 1 - 1
Doxyfile

@@ -1257,7 +1257,7 @@ INCLUDE_FILE_PATTERNS  =
 # undefined via #undef or recursively expanded use the := operator
 # instead of the = operator.
 
-PREDEFINED             =
+PREDEFINED             = __EXTENSIVE_WKHTMLTOPDF_QT_HACK__=
 
 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
 # this tag can be used to specify a list of macro names that should be expanded.

+ 112 - 0
src/outline.cc

@@ -0,0 +1,112 @@
+//-*- mode: c++; tab-width: 4; indent-tabs-mode: t; c-file-style: "stroustrup"; -*-
+// This file is part of wkhtmltopdf.
+//
+// wkhtmltopdf 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.
+//
+// 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 General Public License
+// along with wkhtmltopdf.  If not, see <http://www.gnu.org/licenses/>.
+
+#include "outline_p.hh"
+
+
+/*!
+  \file outline.hh
+  \brief Defiens the Outline class
+*/
+
+/*!
+  \class Outline
+  \brief Class responcible for building and keeping an outline of a document.
+*/
+
+/*!
+  \brief Construct a new outline class
+  \param settings The settings to use
+*/
+Outline::Outline(const Settings & settings): d(new OutlinePrivate(settings)) {}
+Outline::~Outline() {delete d;}
+
+/*!
+  \brief Add a new webpage to the outline
+  \param name The name of the webpage
+  \param wp A webprinter for the page
+  \param frame The frame containing the webpage
+*/
+void Outline::addWebPage(const QString & name, QWebPrinter & wp, QWebFrame * frame) {
+	QMap< QPair<int, QPair<qreal,qreal> >, QWebElement> headings;
+	
+	foreach(const QWebElement & e, frame->findAllElements("h1,h2,h3,h4,h5,h6,h7,h8,h9")) {
+		QPair<int, QRectF> location = wp.elementLocation(e);
+		headings[ qMakePair(location.first, qMakePair(location.second.y(), location.second.x()) ) ] = e;
+	}
+
+	//This huristic is a little strange, it tries to create a real tree,
+	//even though someone puts a h5 below a h1 or stuff like that
+	//The way this is handled is having a level stack, indicating what h-tags
+	//a level level in the tree currently represents
+	QVector<uint> levelStack;
+	levelStack.push_back(0);
+	OutlineItem * root = new OutlineItem();
+	OutlineItem * old = root;
+	for(QMap< QPair<int, QPair<qreal,qreal> >, QWebElement>::iterator i = headings.begin(); i != headings.end(); ++i) {
+		const QWebElement & element = i.value();
+		
+		uint level = element.tagName().mid(1).toInt();
+		OutlineItem * item = new OutlineItem();
+		item->page = d->pageCount + i.key().first;
+		item->value = element.toPlainText();
+		item->element = element;
+		item->anchor = QString("__WKANCHOR_")+QString::number(d->anchorCounter++,36);
+		while(levelStack.back() >= level) {
+			old = old->parent;
+			levelStack.pop_back();
+		}
+		item->parent = old;
+		old->children.push_back(item);
+		old = item;
+		levelStack.push_back(level);
+	}
+	d->pageCount += wp.pageCount();
+}
+
+/*!
+  \brief Fill in header footer parameters for a given page
+  \param page The page to fill in for
+  \param parms The structure to fill
+ */
+void Outline::fillHeaderFooterParms(int page, QHash<QString, QString> & parms) {
+}
+
+/*!
+  \brief Fill in anchor as to add to a given document
+  \param doc The 0 indexed document number (in order of addWebPage)
+  \param anchors The structure to fill
+*/
+void Outline::fillAnchors(int doc, QHash<QString, QWebElement> & anchors) {
+  if (doc < 0 || doc >= d->documentOutlines.size()) return;
+  d->fillChildAnchors( d->documentOutlines[doc], anchors );
+}
+
+/*!
+  \brief return the number of pages in the outlined document
+*/
+int Outline::pageCount() {
+	return d->pageCount;
+}
+
+/*!
+  \brief Print the document outline to a given printer
+  \param printer The printer to print to
+*/
+void Outline::printOutline(QPrinter * printer) {
+	foreach(OutlineItem * i, d->documentOutlines)
+		d->outlineChildren(i, printer, 0);
+}

+ 39 - 0
src/outline.hh

@@ -0,0 +1,39 @@
+//-*- mode: c++; tab-width: 4; indent-tabs-mode: t; c-file-style: "stroustrup"; -*-
+// This file is part of wkhtmltopdf.
+//
+// wkhtmltopdf 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.
+//
+// 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 General Public License
+// along with wkhtmltopdf.  If not, see <http://www.gnu.org/licenses/>.
+#ifndef __OUTLINE_HH__
+#define __OUTLINE_HH__
+#include <QWebFrame>
+#ifdef  __EXTENSIVE_WKHTMLTOPDF_QT_HACK__
+#include <QWebElement>
+#include "settings.hh"
+
+class OutlinePrivate;
+
+class Outline {
+public:
+	Outline(const Settings & settings);
+	~Outline();
+	void addWebPage(const QString & name, QWebPrinter & wp, QWebFrame * frame);
+	void fillHeaderFooterParms(int page, QHash<QString, QString> & parms);
+	void fillAnchors(int d, QHash<QString, QWebElement> & anchors);
+	int pageCount();
+	void printOutline(QPrinter * printer);
+private:
+	OutlinePrivate * d;
+};
+
+#endif //__EXTENSIVE_WKHTMLTOPDF_QT_HACK__
+#endif //__OUTLINE_HH__

+ 43 - 0
src/outline_p.hh

@@ -0,0 +1,43 @@
+//-*- mode: c++; tab-width: 4; indent-tabs-mode: t; c-file-style: "stroustrup"; -*-
+// This file is part of wkhtmltopdf.
+//
+// wkhtmltopdf 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.
+//
+// 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 General Public License
+// along with wkhtmltopdf.  If not, see <http://www.gnu.org/licenses/>.
+#ifndef __OUTLINE_P_HH
+#define __OUTLINE_P_HH
+#include "outline.hh"
+#ifdef __EXTENSIVE_WKHTMLTOPDF_QT_HACK__
+
+class OutlineItem {
+public:
+	QList<OutlineItem *> children;
+	OutlineItem * parent;
+	uint page;
+	QString value;
+	QWebElement element;
+	QString anchor;
+	~OutlineItem();
+};
+
+class OutlinePrivate {
+public:
+	QList<OutlineItem *> documentOutlines;
+	int pageCount;
+	int anchorCounter;
+	OutlinePrivate(const Settings & settings);
+	void fillChildAnchors(OutlineItem * item, QHash<QString, QWebElement> & anchors);
+	void outlineChildren(OutlineItem * item, QPrinter * printer, int level);
+};
+
+#endif //__EXTENSIVE_WKHTMLTOPDF_QT_HACK__
+#endif //__OUTLINE_P_HH

+ 93 - 121
src/pageconverter.cc

@@ -71,31 +71,6 @@ PageConverterPrivate::PageConverterPrivate(Settings & s, PageConverter & o) :
 	connect(&hfLoader, SIGNAL(loadFinished(bool)), this, SLOT(printPage(bool)));
 }
 
-
-// /*!
-//  * Once loading is finished, we start the printing
-//  * \param ok did the loading finish correctly?
-//  */
-// void PageConverterPrivate::loadFinished(bool ok) {
-// 	//Keep track of the number of pages currently loading
-// 	#warning "This is a race condition"
-// 	loading.deref();
-// 	if (!ok) {
-// 		//It went bad, return with 1
-// 		emit outer.error("Failed loading page");
-//         #warning "FIX ME"
-// 		exit(1);
-// 		return;
-// 	}
-
-// 	  #warning "FIX ME"
-// 	//feedback.nextState("Waiting for redirect");
-// 	if (loading == 0) {
-// 		//Wait a little while for js-redirects, and then print
-// 		QTimer::singleShot(settings.jsredirectwait, this, SLOT(preparePrint()));
-// 	}
-// }
-
 /*!
  * Called when the page is loading, display some progress to the using
  * \param progress the loading progress in percent
@@ -130,14 +105,6 @@ void PageConverterPrivate::beginConvert() {
  * Prepares printing out the document to the pdf file
  */
 void PageConverterPrivate::preparePrint(bool ok) {
-	//If there are still pages loading wait til they are done
-	//if (loading != 0) return;
-	//Give some user feed back
-// 	if (!quiet) {
-// 		fprintf(stderr, "Outputting pages       \r");
-// 		fflush(stdout);
-// 	}
-	
 
 	printer = new QPrinter(settings.resolution);
 	
@@ -242,11 +209,9 @@ void PageConverterPrivate::preparePrint(bool ok) {
 		}
 	}
 
-	headings.clear();
-
 	currentPhase = 2;
 	emit outer.phaseChanged();
-
+	outline = new Outline(settings);
 	//This is the first render face, it is done to calculate:
 	// * The number of pages of each document
 	// * A visual ordering of the header elemnt
@@ -259,46 +224,32 @@ void PageConverterPrivate::preparePrint(bool ok) {
 		painter->save();
 		QWebPrinter wp(pages[d]->mainFrame(), printer, *painter);
 		int count = wp.pageCount();
-		pageCount.push_back(count);
+		//pageCount.push_back(count);
 		actualPages += count;
 		if (settings.cover.isEmpty() || d != 0) {
+			outline->addWebPage("", wp, pages[d]->mainFrame());
 			logicalPages += count;
-			foreach(const QWebElement & e, pages[d]->mainFrame()->findAllElements("h1,h2,h3,h4,h5,h6,h7,h8,h9")) {
-				QPair<int, QRectF> location = wp.elementLocation(e);
-				headings[d][ qMakePair(location.first, qMakePair(location.second.y(), location.second.x()) ) ] = e;
-			}
 		} 
 		painter->restore();
 	}
 
+
 	//Now that we know the ordering of the headers in each document we
 	//can calculate the number of pages in the table of content
 	if (settings.printToc) {
 		int k=pages.size()+1;
 		progressString = QString("Page ")+QString::number(k)+QString(" of ")+QString::number(k);
 		emit outer.progressChanged(100);
-
-//  		TocItem * root = new TocItem();
-// 		for(int d=0; d < pages.size(); ++d) {
-// 			if (cover[0] && d == 0) continue;
-// 			// buildToc(root,pages[d]->mainFrame(),
-//  					 anchors[d], externalLinks[d]
-//  					 ,-1);
-// 		}
-		//tocPages = tocPrinter.countPages(root, &printer, painter);
-		tocPages = 0;
-		actualPages += tocPages;
-		logicalPages += tocPages;
- 		//delete root;
+		
+		tocPrinter = new TocPrinter(outline, printer, *painter);
+		actualPages += tocPrinter->pageCount();
+		logicalPages += tocPrinter->pageCount();
    	}
 	actualPages *= settings.copies;
 	int page=1;
 
 	headers.clear();
 	footers.clear();
-// 	headerFooterLoading =
-// 		(settings.header.htmlUrl.isEmpty()?0:actualPages) +
-// 		(settings.fooher.htmlURl.isEmpty()?0:actualPages);
 	if(!settings.header.htmlUrl.isEmpty() || !settings.footer.htmlUrl.isEmpty()) {
 		for(int d=0; d < pages.size(); ++d) {
 			if (!settings.cover.isEmpty() && d == 0) continue;
@@ -310,11 +261,72 @@ void PageConverterPrivate::preparePrint(bool ok) {
 				++page;
 			}
 		}
+		hfLoader.load();
 	} else 
 		printPage(true);
 #endif
 }
 
+void PageConverterPrivate::beginPage(int & actualPage, bool & first) {
+	progressString = QString("Page ") + QString::number(actualPage) + QString(" of ") + QString::number(actualPages);
+	emit outer.progressChanged(actualPage * 100 / actualPages);
+	if(first)
+		first=false;
+	else
+		printer->newPage();
+	actualPages++;
+}
+
+void PageConverterPrivate::endPage(bool actual, bool hasHeaderFooter) {
+	if(hasHeaderFooter && actual) {
+		//Webkit used all kinds of crasy cordinate transformation, and font setup
+		//We save it here and restore some sane defaults
+		painter->save();
+		painter->resetTransform();
+						
+		int h=printer->height();
+		int w=printer->width();
+						
+		//If needed draw the header line
+		if (settings.header.line) painter->drawLine(0, 0, w, 0);
+		//Guess the height of the header text
+		painter->setFont(QFont(settings.header.fontName, settings.header.fontSize));
+		int dy = painter->boundingRect(0, 0, w, h, Qt::AlignTop, "M").height();
+		//Draw the header text
+		QRect r=QRect(0, 0-dy, w, h);
+		painter->drawText(r, Qt::AlignTop | Qt::AlignLeft, hfreplace(settings.header.left));
+		painter->drawText(r, Qt::AlignTop | Qt::AlignHCenter, hfreplace(settings.header.center));
+		painter->drawText(r, Qt::AlignTop | Qt::AlignRight, hfreplace(settings.header.right));
+		
+		//IF needed draw the footer line
+		if (settings.footer.line) painter->drawLine(0, h, w, h);
+		//Guess the height of the footer text
+		painter->setFont(QFont(settings.footer.fontName, settings.footer.fontSize));
+		dy = painter->boundingRect(0, 0, w, h, Qt::AlignTop, "M").height();
+		//Draw the fooder text
+		r=QRect(0,0,w,h+dy);
+		painter->drawText(r, Qt::AlignBottom | Qt::AlignLeft, hfreplace(settings.footer.left));
+		painter->drawText(r, Qt::AlignBottom | Qt::AlignHCenter, hfreplace(settings.footer.center));
+		painter->drawText(r, Qt::AlignBottom | Qt::AlignRight, hfreplace(settings.footer.right));
+		
+		//Restore webkits crasy scaling and font settings
+		painter->restore();
+	}
+// 					painter->save();
+// 					painter->resetTransform();
+// 					painter->drawPicture(0,-208 - 4, picture);
+// 					painter->restore();
+// 					{
+// 						painter->save();
+// 						
+// 						//MThread::msleep(100);
+// 						painter->translate(0,-222);
+// 						QWebPrinter whp(headers[0]->mainFrame(), printer, *painter);
+// 						//painter->translate(0,-whp.elementLocation(headers[0]->mainFrame()->findFirstElement("body")).second.height());
+// 						whp.spoolPage(1);
+// 					}
+
+}
 
 void PageConverterPrivate::printPage(bool ok) {
 	//if (headerFooterLoading != 0 || loading != 0) return;
@@ -362,12 +374,32 @@ void PageConverterPrivate::printPage(bool ok) {
 
 		logicalPage=1;
 		for(int d=0; d < pages.size(); ++d) {
+			//Output the table of content now
+			if(tocPrinter && d == (settings.cover.isEmpty()?0:1)) {
+				painter->save();
+				for(int p=0; p < tocPrinter->pageCount(); ++p) {
+					for(int pc_=0; pc_ < pc; ++pc_) {
+						beginPage(actualPage,first);
+						tocPrinter->spoolPage(p);
+						endPage(true, hasHeaderFooter);
+					}
+					++logicalPage;
+				}
+				painter->restore();
+			}
 			painter->save();
-			
+
+			//output 
 			QWebPrinter wp(pages[d]->mainFrame(), printer, *painter);
 			QString l1=pages[d]->mainFrame()->url().path().split("/").back()+"#";
 			QString l2=pages[d]->mainFrame()->url().toString() + "#";
 
+			if (settings.cover.isEmpty() || d != 0) {
+				int md = d - settings.cover.isEmpty()?0:1;
+				if(tocPrinter) tocPrinter->fillLinks(md, localLinks[md]);
+				outline->fillAnchors(md, anchors[md]);				
+			}
+
 			//Sort anchors and links by page
 			QHash<int, QHash<QString, QWebElement> > myAnchors;
 			QHash<int, QVector< QPair<QWebElement,QString> > > myLocalLinks;
@@ -383,21 +415,11 @@ void PageConverterPrivate::printPage(bool ok) {
 			for(QVector< QPair<QWebElement,QString> >::iterator i=externalLinks[d].begin();
 				i != externalLinks[d].end(); ++i)
 				myExternalLinks[wp.elementLocation(i->first).first].push_back(*i);
-						
+				
 			for(int p=0; p < wp.pageCount(); ++p) {
 				for(int pc_=0; pc_ < pc; ++pc_) {
-
-					progressString = QString("Page ") + QString::number(actualPage) + QString(" of ") + QString::number(actualPages);
-					emit outer.progressChanged(actualPage * 100 / actualPages);
-
-					if(first)
-						first=false;
-					else
-						printer->newPage();
-
-
+					beginPage(actualPage,first);
 					wp.spoolPage(p+1);
-					
 					for(QHash<QString, QWebElement>::iterator i=myAnchors[p+1].begin();
 						i != myAnchors[p+1].end(); ++i) {
 						QRectF r = wp.elementLocation(i.value()).second;
@@ -413,57 +435,7 @@ void PageConverterPrivate::printPage(bool ok) {
 						QRectF r = wp.elementLocation(i->first).second;
 						painter->addHyperlink(r, QUrl(i->second));
 					}
-					++actualPage;
-
-					if(hasHeaderFooter && (settings.cover.isEmpty() || d != 0)) {
-						//Webkit used all kinds of crasy cordinate transformation, and font setup
-						//We save it here and restore some sane defaults
-						painter->save();
-						painter->resetTransform();
-						
-						int h=printer->height();
-						int w=printer->width();
-						
-						//If needed draw the header line
-						if (settings.header.line) painter->drawLine(0, 0, w, 0);
-						//Guess the height of the header text
-						painter->setFont(QFont(settings.header.fontName, settings.header.fontSize));
-						int dy = painter->boundingRect(0, 0, w, h, Qt::AlignTop, "M").height();
-						//Draw the header text
-						QRect r=QRect(0, 0-dy, w, h);
-						painter->drawText(r, Qt::AlignTop | Qt::AlignLeft, hfreplace(settings.header.left));
-						painter->drawText(r, Qt::AlignTop | Qt::AlignHCenter, hfreplace(settings.header.center));
-						painter->drawText(r, Qt::AlignTop | Qt::AlignRight, hfreplace(settings.header.right));
-						
-						//IF needed draw the footer line
-						if (settings.footer.line) painter->drawLine(0, h, w, h);
-						//Guess the height of the footer text
-						painter->setFont(QFont(settings.footer.fontName, settings.footer.fontSize));
-						dy = painter->boundingRect(0, 0, w, h, Qt::AlignTop, "M").height();
-						//Draw the fooder text
-						r=QRect(0,0,w,h+dy);
-						painter->drawText(r, Qt::AlignBottom | Qt::AlignLeft, hfreplace(settings.footer.left));
-						painter->drawText(r, Qt::AlignBottom | Qt::AlignHCenter, hfreplace(settings.footer.center));
-						painter->drawText(r, Qt::AlignBottom | Qt::AlignRight, hfreplace(settings.footer.right));
-						
-						//Restore webkits crasy scaling and font settings
-						painter->restore();
-					}
-
-
-// 					painter->save();
-// 					painter->resetTransform();
-// 					painter->drawPicture(0,-208 - 4, picture);
-// 					painter->restore();
-// 					{
-// 						painter->save();
-// 						
-// 						//MThread::msleep(100);
-// 						painter->translate(0,-222);
-// 						QWebPrinter whp(headers[0]->mainFrame(), printer, *painter);
-// 						//painter->translate(0,-whp.elementLocation(headers[0]->mainFrame()->findFirstElement("body")).second.height());
-// 						whp.spoolPage(1);
-// 					}
+					endPage(settings.cover.isEmpty() || d != 0, hasHeaderFooter);
 				}
 				if (settings.cover.isEmpty() || d != 0) ++logicalPage;
 			}

+ 8 - 1
src/pageconverter_p.hh

@@ -28,6 +28,8 @@
 #include "tempfile.hh"
 #include <QWaitCondition>
 #include <QMutex>
+#include "outline.hh"
+#include "tocprinter.hh"
 
 class PageConverterPrivate: public QObject {
 	Q_OBJECT
@@ -57,6 +59,9 @@ private:
 	QList<QWebPage *> pages;
 	QPrinter * printer;
 	QPainter * painter;
+	Outline * outline;
+	TocPrinter * tocPrinter;
+
 	int logicalPages;
 	int logicalPage;
 	int actualPages;
@@ -69,10 +74,12 @@ private:
 	QHash<int, QHash<QString, QWebElement> > anchors;
 	QHash<int, QVector< QPair<QWebElement,QString> > > localLinks;
 	QHash<int, QVector< QPair<QWebElement,QString> > > externalLinks;
-	QHash<int, QMap< QPair<int, QPair<qreal,qreal> >, QWebElement> > headings;
+
 	QList<QWebPage *> headers;
 	QList<QWebPage *> footers;
 
+	void beginPage(int & actualPage, bool & first);
+	void endPage(bool actual, bool hasHeaderFooter);
 	QString hfreplace(const QString & q);
 	QWebPage * loadHeaderFooter(QString url, int d, int page);
 public slots:

+ 2 - 2
src/settings.cc

@@ -112,9 +112,9 @@ QPair<qreal, QPrinter::Unit> Settings::strToUnitReal(const char * o, bool * ok)
 		u=QPrinter::Point;
 	else {
 		if(ok) ok=false;
-		return qMakePair((qreal)QString(o).left(i).toDouble(), u);
+		return qMakePair((qreal)QString(o).left(i).toDouble()*s, u);
 	}
-	return qMakePair((qreal)QString(o).left(i).toDouble(ok), u);
+	return qMakePair((qreal)QString(o).left(i).toDouble(ok)*s, u);
 }
 
 /*!

+ 37 - 0
src/tocprinter.hh

@@ -0,0 +1,37 @@
+//-*- mode: c++; tab-width: 4; indent-tabs-mode: t; c-file-style: "stroustrup"; -*-
+// This file is part of wkhtmltopdf.
+//
+// wkhtmltopdf 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.
+//
+// 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 General Public License
+// along with wkhtmltopdf.  If not, see <http://www.gnu.org/licenses/>.
+#ifndef __TOCPRINTER_HH__
+#define __TOCPRINTER_HH__
+#include <QWebFrame>
+#ifdef __EXTENSIVE_WKHTMLTOPDF_QT_HACK__
+#include "outline.hh"
+#include <QPainter>
+#include <QPrinter>
+
+class TocPrinterPrivate;
+
+class TocPrinter {
+public:
+	TocPrinter(Outline * outline, QPrinter * printer, QPainter & painter);
+	int pageCount();
+	void spoolPage(int page);
+	void fillLinks(int d, QVector<QPair<QWebElement, QString> > & links);
+private:
+	TocPrinterPrivate * tocPrinter;
+};
+
+#endif //__EXTENSIVE_WKHTMLTOPDF_QT_HACK__
+#endif //__TOCPRINTER_HH

+ 5 - 3
wkhtmltopdf.pro

@@ -58,10 +58,12 @@ target.path=$$INSTALLBASE/bin
 QT += webkit network
 
 # Input
-HEADERS += src/wkhtmltopdf.hh src/toc.hh src/pageconverter_p.hh src/pageconverter.hh \
+HEADERS += src/wkhtmltopdf.hh src/pageconverter_p.hh src/pageconverter.hh \
            src/multipageloader_p.hh src/multipageloader.hh src/progressfeedback.hh
 
-SOURCES += src/wkhtmltopdf.cc src/toc.cc src/arguments.cc src/commandlineparser.cc \
+SOURCES += src/wkhtmltopdf.cc src/arguments.cc src/commandlineparser.cc \
            src/docparts.cc src/outputter.cc src/manoutputter.cc src/settings.cc \
            src/htmloutputter.cc src/textoutputter.cc src/tempfile.cc \
-           src/multipageloader.cc src/pageconverter.cc src/progressfeedback.cc
+           src/multipageloader.cc src/pageconverter.cc src/progressfeedback.cc \
+           src/outline.cc 
+