File: PDFDocument.h

package info (click to toggle)
texstudio 2.8.4%2Bdebian-3
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 39,108 kB
  • ctags: 13,390
  • sloc: cpp: 84,770; xml: 10,109; ansic: 6,865; sh: 150; makefile: 82
file content (537 lines) | stat: -rw-r--r-- 13,881 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
/*
	This is part of TeXworks, an environment for working with TeX documents
	Copyright (C) 2007-2010  Jonathan Kew

	This program 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 2 of the License, or
	(at your option) any later version.

	This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.

	For links to further information, or to contact the author,
	see <http://texworks.org/>.
*/

#ifndef PDFDocument_H
#define PDFDocument_H

#ifndef NO_POPPLER_PREVIEW


#include "mostQtHeaders.h"

#include <QProgressDialog>

//#include "FindDialog.h"
#if QT_VERSION < 0x050000
#include "poppler-qt4.h"
#else
#include "poppler-qt5.h"
#endif
#include <synctex_parser.h>

#include "ui_PDFDocument.h"
#include "pdfrendermanager.h"


const int kPDFWindowStateVersion = 1;

class QAction;
class QMenu;
class QToolBar;
class QScrollArea;
class QShortcut;
class QFileSystemWatcher;
class ConfigManagerInterface;
class PDFDocument;
class PDFWidget;

class TitledPanel;
class PDFAnnotations;
class PDFAnnotation;
class PDFAnnotationTableView;
class MessageFrame;

class PDFMagnifier : public QLabel
{
	Q_OBJECT

public:
	PDFMagnifier(QWidget *parent, qreal inDpi);
	void setPage(int p, qreal scale, const QRect& visibleRect);
	void reshape();
	
public slots:
	void setImage(const QPixmap &img, int pageNr);
	
protected:
	virtual void paintEvent(QPaintEvent *event);

private:
	int oldshape;
	int page;
	int overScale;
	qreal	scaleFactor;
	qreal	parentDpi;
	QPixmap	image;
	
	QPoint mouseTranslate;
	
	QPoint	imageLoc, mouseOffset;
	QSize	imageSize;
	qreal	imageDpi;
	int imagePage;
};

#ifdef PHONON
#include <Phonon/VideoPlayer>

class PDFMovie: public Phonon::VideoPlayer
{
	Q_OBJECT
public:
	PDFMovie(PDFWidget* parent, Poppler::MovieAnnotation* annot, int page);
	void place();
protected:
	void contextMenuEvent(QContextMenuEvent *);
	void mouseReleaseEvent(QMouseEvent *e);
public slots:
	void realPlay();
	void setVolumeDialog();
	void seekDialog();
private:
	QMenu* popup;
	QRectF boundary;
	int page;
};
#endif

typedef enum {
	kFixedMag,
	kFitWidth,
	kFitWindow,
	kFitTextWidth
} autoScaleOption;

class PDFScrollArea;
class PDFWidget : public QLabel
{
	Q_OBJECT

public:
	explicit PDFWidget(bool embedded=false);
	virtual ~PDFWidget();
	
	void setDocument(const QSharedPointer<Poppler::Document> &doc);
	void setPDFDocument(PDFDocument *docu);

	void saveState(); // used when toggling full screen mode
	void restoreState();
	void setResolution(int res);
	void resetMagnifier();
	Q_INVOKABLE int normalizedPageIndex(int pageIndex);
	Q_INVOKABLE void goToPageDirect(int pageIndex, bool sync);
	Q_INVOKABLE void setHighlightPath(const int pageIndex, const QPainterPath& path);
	Q_INVOKABLE int getHighlightPage() const;
	Q_INVOKABLE void goToDestination(const QString& destName);
	Q_INVOKABLE void goToPageRelativePosition(int page, float xinpage, float yinpage);
	Q_INVOKABLE int getPageIndex();
	Q_INVOKABLE void reloadPage(bool sync = true);
	void updateStatusBar();
	void setGridSize(int gx, int gy, bool setAsDefault=false);
	Q_INVOKABLE int visiblePages() const;
	Q_INVOKABLE int pseudoNumPages() const;
	Q_INVOKABLE int realNumPages() const;
	Q_INVOKABLE int pageStep();
	Q_INVOKABLE int gridCols() const;
	Q_INVOKABLE int gridRowHeight() const;
	Q_INVOKABLE int gridBorder() const;
	Q_INVOKABLE PDFDocument * getPDFDocument();
	Q_INVOKABLE int getPageOffset() const;
	autoScaleOption getScaleOption() { return scaleOption; }
	double totalScaleFactor() const;

	int currentPageHistoryIndex() const;
	const QList<int> currentPageHistory() const;
	
	QPoint gridPagePosition(int pageIndex) const;
	QRect gridPageRect(int pageIndex) const;
	int gridPageIndex(const QPoint& position) const;
	void mapToScaledPosition(const QPoint& position, int & page, QPointF& scaledPos) const;
	QPoint mapFromScaledPosition(int page, const QPointF& scaledPos) const;
	int pageFromPos(const QPoint& pos) const;
	QRect pageRect(int page) const;
	QSizeF maxPageSizeF() const;
	QSizeF gridSizeF(bool ignoreVerticalGrid=false) const;
	QRectF horizontalTextRangeF() const;

	Q_INVOKABLE void zoom(qreal scale);

	virtual void wheelEvent(QWheelEvent *event);

protected slots: //not private, so scripts have access
	void goFirst();
	void goPrev();
	void goNext();
	void goLast();
	void goForward();
	void goBack();
	void doPageDialog();
	
	void fitWidth(bool checked = true);
	void fitTextWidth(bool checked = true);
	void zoomIn();
	void zoomOut();
	void jumpToSource();
	
	void upOrPrev();
	void leftOrPrev();
	void pageUpOrPrev();

	void downOrNext();
	void rightOrNext();
	void pageDownOrNext();

	void clearHighlight();
	
public slots:
	void setSinglePageStep(bool step);
	void windowResized();
	void fitWindow(bool checked = true);
	void setTool(int tool);	
	void syncWindowClick(const QPoint& p, bool activate);
	void syncCurrentPage(bool activate);
	void fixedScale(qreal scale = 1.0);
	void setImage(QPixmap img,int pageNr);

signals:
	void changedPage(int, bool);
	void changedZoom(qreal);
	void changedScaleOption(autoScaleOption);
	void syncClick(int, const QPointF&, bool activate); //page position in page coordinates

protected:
	virtual void paintEvent(QPaintEvent *event);

	virtual void mousePressEvent(QMouseEvent *event);
	virtual void mouseReleaseEvent(QMouseEvent *event);
	virtual void mouseDoubleClickEvent(QMouseEvent *event);
	virtual void mouseMoveEvent(QMouseEvent *event);

	virtual void keyPressEvent(QKeyEvent *event);
	virtual void keyReleaseEvent(QKeyEvent *event);

	virtual void focusInEvent(QFocusEvent *event);

	virtual void contextMenuEvent(QContextMenuEvent *event);

private:
	void init();
	void adjustSize();
	void updateCursor();
	void updateCursor(const QPoint& pos);
	QRect mapPopplerRectToWidget(QRectF rect, const QSizeF &pageSize) const;
	void useMagnifier(const QMouseEvent *inEvent);
	void goToDestination(const Poppler::LinkDestination& dest);
	void doLink(const Poppler::Link *link);
	void annotationClicked(Poppler::Annotation *annotation, int page);
	void doZoom(const QPoint& clickPos, int dir, qreal newScaleFactor=1.0);

	PDFScrollArea* getScrollArea();
	
	QSharedPointer<Poppler::Document> document;
	//QList<int> pages;
	Poppler::Link		*clickedLink;
	Poppler::Annotation	*clickedAnnotation;

	int realPageIndex, oldRealPageIndex;
	QList<int> pages;
	qreal	scaleFactor;
	qreal	dpi;
	autoScaleOption scaleOption;

	float summedWheelDegrees;
	
	int docPages;
	qreal			saveScaleFactor;
	autoScaleOption	saveScaleOption;

	QAction	*ctxZoomInAction;
	QAction	*ctxZoomOutAction;
	QShortcut *shortcutUp;
	QShortcut *shortcutLeft;
	QShortcut *shortcutDown;
	QShortcut *shortcutRight;

	QPixmap image;
	QRect	imageRect;
	qreal	imageDpi;
	int	imagePage;

	PDFMagnifier	*magnifier;
#ifdef PHONON
	PDFMovie	*movie;
#endif
	int		currentTool;	// the current tool selected in the toolbar
	int		usingTool;	// the tool actually being used in an ongoing mouse drag
	bool		singlePageStep;

	int gridx, gridy;

	bool forceUpdate;

	QPainterPath	highlightPath;
	int highlightPage;
	QTimer highlightRemover;
	
	static QCursor	*magnifierCursor;
	static QCursor	*zoomInCursor;
	static QCursor	*zoomOutCursor;

	mutable QSizeF maxPageSize; //cache pageSize
	mutable QRectF horizontalTextRange;

	QList<int> pageHistory;
	int pageHistoryIndex;

	PDFDocument *pdfdocument;
};

class PDFSearchResult {
public:
	explicit PDFSearchResult(const PDFDocument* pdfdoc = NULL, int page = -1, QRectF rect = QRectF())
		: doc(pdfdoc), pageIdx(page), selRect(rect)
	{ }

	const PDFDocument* doc;
	int pageIdx;
	QRectF selRect;
};



struct PDFDocumentConfig;
class PDFDock;
class PDFSearchDock;
class PDFScrollArea;
class PDFDocument : public QMainWindow, private Ui::PDFDocument
{
	Q_OBJECT
	Q_PROPERTY(QString fileName READ fileName)

public:
    explicit PDFDocument(PDFDocumentConfig* const pdfConfig, bool embedded=false);
	virtual ~PDFDocument();

	static PDFDocument *findDocument(const QString &fileName);
	static QList<PDFDocument*> documentList()
	{
		return docList;
	}

	Q_INVOKABLE QString fileName() const { return curFile; }
	Q_INVOKABLE QFileInfo getMasterFile() const { return masterFile; }

	void saveGeometryToConfig();

	Q_INVOKABLE void zoomToRight(QWidget *otherWindow);
	void showScale(qreal scale);
	Q_INVOKABLE void showPage(int page);
	Q_INVOKABLE void setResolution(int res);
	void resetMagnifier();
	Q_INVOKABLE void goToDestination(const QString& destName);
	Q_INVOKABLE void goToPage(const int page);
	Q_INVOKABLE void focus();
	bool hasSyncData()
	{
		return scanner != NULL;
	}

	const QSharedPointer<Poppler::Document> & popplerDoc() const
	{
		return document;
	}
	
	Q_INVOKABLE PDFWidget *widget(){ return pdfWidget; }
	const PDFWidget *widget() const { return pdfWidget; }

	bool followCursor() const;
	PDFRenderManager *renderManager;

	static bool isCompiling, isMaybeCompiling;
	bool embeddedMode;
	bool autoClose;

    void setStateEnlarged(bool state);
	
protected:
	virtual void changeEvent(QEvent *event);
	virtual void closeEvent(QCloseEvent *event);
	virtual void dragEnterEvent(QDragEnterEvent *event);
	virtual void dropEvent(QDropEvent *event);
	virtual void enterEvent(QEvent *event);
	virtual void leaveEvent(QEvent *event);
	virtual void mouseMoveEvent(QMouseEvent *event);
	void setToolbarsVisible(bool visible);
	void shortcutOnlyIfFocused(const QList<QAction *> &actions);

public slots:
	void reloadSettings();
	void loadCurrentFile(bool fillCache=true);
	void fillRenderCache(int pg=-1);
	void sideBySide();
    void doFindDialog(const QString command="");
	void doFindAgain();
	void goToSource();
	void toggleFullScreen(const bool fullscreen);
	int syncFromSource(const QString& sourceFile, int lineNo, bool activatePreview); //lineNo 0 based
	void syncFromView(const QString& pdfFile, const QFileInfo& masterFile, int page);
	void loadFile(const QString &fileName, const QFileInfo& masterFile, bool alert = true);
	void printPDF();
	void setAutoHideToolbars(bool enabled);
	void hideToolbars();
	void showToolbars();
private slots:
	void fileOpen();
	
	void enablePageActions(int, bool);
	void enableZoomActions(qreal);
	void adjustScaleActions(autoScaleOption);
	void syncClick(int page, const QPointF& pos, bool activate);
	void stopReloadTimer();
	void reloadWhenIdle();
	void idleReload();

	void runExternalViewer();
    void runInternalViewer();
	void toggleEmbedded();
	void runQuickBuild();

	void setGrid();

public slots:
	void closeSomething();
private slots:
	void tileWindows();
	void stackWindows();
	void unminimize();
	void arrangeWindows(bool tile);
	void updateToolBarForOrientation(Qt::Orientation orientation);

	void jumpToPage();

	void search(bool backward, bool incremental);
public:
	void search(const QString& searchText, bool backward, bool incremental, bool caseSensitive, bool sync);
	void search();
private slots:
	void gotoAnnotation(const PDFAnnotation *ann);

	void zoomFromAction();
	void zoomSliderChange(int pos = 0);
    void enlarge();
    void shrink();
signals:
	void documentClosed();
	void documentLoaded();
	void syncSource(const QString& sourceFile, int line, bool activate, const QString& guessedWord); //view -> source
	void syncView(const QString& pdfFile, const QFileInfo& masterFile, int page); //view -> other view
	void focusEditor();
	void fileDropped(const QUrl& url);

	void runCommand(const QString& command, const QFileInfo& masterFile, const QFileInfo& currentFile, int linenr);

	void triggeredAbout();
	void triggeredManual();
	void triggeredQuit();
	void triggeredPlaceOnLeft();
	void triggeredConfigure();
    void triggeredEnlarge();
    void triggeredShrink();
	
	void triggeredClone();

private:
    void init(bool embedded=false);
    void setupMenus();
	void setCurrentFile(const QString &fileName);
	void loadSyncData();

	qreal zoomSliderPosToScale(int pos);
	int scaleToZoomSliderPos(qreal scale);

	QString curFile, curFileUnnormalized;
	qint64 curFileSize;
	QDateTime curFileLastModified;
	QFileInfo masterFile, lastSyncSourceFile;
	int lastSyncLineNumber;

	QSharedPointer<Poppler::Document> document;
	
	PDFWidget	*pdfWidget;
	PDFScrollArea	*scrollArea;
	MessageFrame *messageFrame;
	TitledPanel * annotationPanel;
	PDFAnnotations * annotations;
	PDFAnnotationTableView * annotationTable;

	QMenuBar *menubar;
	QMenu *menuHelp;
	QMenu *menuFile;
	QMenu *menuEdit;
	QMenu *menuView;
	QMenu *menuGrid;
	QMenu *menuWindow;
public:
	QMenu *menuShow;
private:
	QMenu *menuEdit_2;

	QAction *actionPage_Up;
	QAction *actionPage_Down;

	QButtonGroup	*toolButtonGroup;
	QToolButton *comboZoom;
	QLineEdit *leCurrentPage;
	QLabel *pageCountSeparator;
	QLabel *pageCountLabel;
	QIntValidator *leCurrentPageValidator;

	QLabel *pageLabel;
	QToolButton *scaleButton;
	QSlider *zoomSlider;
	QList<QAction*> recentFileActions;
	QShortcut* exitFullscreen;

	QFileSystemWatcher *watcher;
	QTimer *reloadTimer;
	
	synctex_scanner_t scanner;
	
	static QList<PDFDocument*> docList;
	
	PDFDock *dwClock, *dwOutline, *dwFonts, *dwInfo, *dwOverview;
	bool dwVisOutline,dwVisFonts,dwVisInfo,dwVisSearch,dwVisOverview;
	bool wasContinuous;
	PDFSearchDock *dwSearch;

	PDFSearchResult lastSearchResult;
	// stores the page idx a search was started on
	// after wrapping the search will continue only up to this page
	int firstSearchPage;

	bool wasMaximized;
	bool syncFromSourceBlock;  //temporary disable sync from source
	bool syncToSourceBlock;    //temporary disable sync to source (only for continuous scrolling)
};

#endif

#endif