1 /* 2 dspdfviewer - Dual Screen PDF Viewer for LaTeX-Beamer 3 Copyright (C) 2012 Danny Edel <mail@danny-edel.de> 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License along 16 with this program; if not, write to the Free Software Foundation, Inc., 17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 20 21 #ifndef PDFRENDERFACTORY_H 22 #define PDFRENDERFACTORY_H 23 24 #include <QObject> 25 #include <QMutex> 26 #include <QCache> 27 #include <QThread> 28 #include <QFileSystemWatcher> 29 #include <QTimer> 30 #include <qimage.h> 31 #include "poppler-qt.h" 32 #include "renderedpage.h" 33 #include "runtimeconfiguration.h" 34 #include "pdfcacheoption.h" 35 #include "pdfdocumentreference.h" 36 37 38 /** Factory for rendered pages 39 * 40 * This class is responsible for rendering the PDF to images. 41 * 42 * You create a factory using a filename (if the file cannot be opened this will throw), 43 * then you can simply request renderings by supplying the desired size and page part 44 * to requestPageRendering. 45 * 46 * The class uses the global instance of QThreadPool and renders in paralell, meaning it 47 * can take advantage of SMP or Multi-Core Systems. 48 * 49 * NOTE for updating the external file: 50 * If you plan on rewriting the displayed file while this application is running, 51 * you can cache the entire file to memory. This can be done via constructor parameter. 52 * 53 * That way, if you create an invalid PDF file (for example you make an error in your latex 54 * document), it still has a copy of the old file present. 55 * The tradeoff is that this will cost you additional memory for *the entire PDF file*, which 56 * can be a lot if you have an image-heavy PDF file. 57 * 58 * The class will notify you via signals when it detects a file change. Then it will try to re-read 59 * the file, and it will notify you if that has succeeded or failed. 60 * 61 * If the re-reading failed, you can still get pages from cache, and you can keep rendering new ones 62 * if you have used the memory cache. However, if you try to render new pages, you will probably 63 * experience strange behaviour or the program will crash. 64 * 65 * If the re-reading went well, the cache will be cleared and new page renders will use the new pdf 66 * file. 67 * 68 */ 69 class PdfRenderFactory : public QObject 70 { 71 Q_OBJECT 72 73 private: 74 PDFDocumentReference documentReference; 75 QFileSystemWatcher fileWatcher; 76 QTimer fileWatcherRewatchTimer; 77 78 QSet< RenderingIdentifier > currentlyRenderingPages; 79 QCache< RenderingIdentifier, RenderedPage> renderedPages; 80 81 mutable QMutex mutex; 82 83 /** This is a little helper for the cache-clear-function to detect 84 * renderings that have been started before, but finished after 85 * a cache clearing. 86 */ 87 quint64 currentVersion; 88 89 int numberOfPages_; 90 91 private: 92 void clearAllCaches(); 93 94 public: 95 PdfRenderFactory( const RuntimeConfiguration& ); 96 ~PdfRenderFactory(); 97 98 /** Request a page rendering. Defaults to low priority (i.e. background rendering), please set High priority manually 99 * on the current page. 100 */ 101 void requestPageRendering( const RenderingIdentifier& originalIdentifier, QThread::Priority priority = QThread::LowPriority); 102 103 int numberOfPages() const; 104 105 private slots: 106 void fileOnDiskChanged(const QString& filename); 107 void pageThreadFinishedRendering( QSharedPointer<RenderedPage> renderedPage ); 108 109 signals: 110 void pageRendered( QSharedPointer<RenderedPage> renderedPage); 111 112 void pdfFileChanged(); 113 void pdfFileRereadSuccesfully(); 114 void pdfFileRereadFailed(); 115 116 public slots: 117 void rewatchFile(); 118 }; 119 120 #endif // PDFRENDERFACTORY_H 121