1 /***************************************************************************
2  *   copyright       : (C) 2012-2017 by Pascal Brachet                     *
3  *   http://www.xm1math.net/texmaker/                                      *
4  *   based on qpdfview  Copyright 2012 Adam Reichold GPL                   *
5  *                                                                         *
6  *   This program is free software; you can redistribute it and/or modify  *
7  *   it under the terms of the GNU General Public License as published by  *
8  *   the Free Software Foundation; either version 2 of the License, or     *
9  *   (at your option) any later version.                                   *
10  *                                                                         *
11  ***************************************************************************/
12 /*
13 
14 Copyright 2012 Adam Reichold
15 
16 This file is part of qpdfview.
17 
18 modified by Pascal Brachet
19 
20 */
21 
22 #include "documentview.h"
23 #include <QProgressDialog>
24 #include <QDir>
25 #include <QFileDialog>
26 #include <QMessageBox>
27 #include <QDebug>
28 #include <QProgressBar>
29 #include <QScrollBar>
30 #include <QApplication>
31 #include <QInputDialog>
32 #include <QLineEdit>
33 
34 bool DocumentView::s_openUrl = false;
35 
36 bool DocumentView::s_autoRefresh = false;
37 
38 bool DocumentView::s_antialiasing = true;
39 bool DocumentView::s_textAntialiasing = true;
40 bool DocumentView::s_textHinting = false;
41 
42 bool DocumentView::s_prefetch = false;
43 
44 qreal DocumentView::s_pageSpacing = 5.0;
45 
46 qreal DocumentView::s_minimumScaleFactor = 0.1;
47 qreal DocumentView::s_maximumScaleFactor = 10.0;
48 
openUrl()49 bool DocumentView::openUrl()
50 {
51     return s_openUrl;
52 }
53 
setOpenUrl(bool openUrl)54 void DocumentView::setOpenUrl(bool openUrl)
55 {
56     s_openUrl = openUrl;
57 }
58 
autoRefresh()59 bool DocumentView::autoRefresh()
60 {
61     return s_autoRefresh;
62 }
63 
setAutoRefresh(bool autoRefresh)64 void DocumentView::setAutoRefresh(bool autoRefresh)
65 {
66     s_autoRefresh = autoRefresh;
67 }
68 
antialiasing()69 bool DocumentView::antialiasing()
70 {
71     return s_antialiasing;
72 }
73 
setAntialiasing(bool antialiasing)74 void DocumentView::setAntialiasing(bool antialiasing)
75 {
76     s_antialiasing = antialiasing;
77 }
78 
textAntialiasing()79 bool DocumentView::textAntialiasing()
80 {
81     return s_textAntialiasing;
82 }
83 
setTextAntialiasing(bool textAntialiasing)84 void DocumentView::setTextAntialiasing(bool textAntialiasing)
85 {
86     s_textAntialiasing = textAntialiasing;
87 }
88 
textHinting()89 bool DocumentView::textHinting()
90 {
91     return s_textHinting;
92 }
93 
setTextHinting(bool textHinting)94 void DocumentView::setTextHinting(bool textHinting)
95 {
96     s_textHinting = textHinting;
97 }
98 
prefetch()99 bool DocumentView::prefetch()
100 {
101     return s_prefetch;
102 }
103 
setPrefetch(bool prefetch)104 void DocumentView::setPrefetch(bool prefetch)
105 {
106     s_prefetch = prefetch;
107 }
108 
pageSpacing()109 qreal DocumentView::pageSpacing()
110 {
111     return s_pageSpacing;
112 }
113 
setPageSpacing(qreal pageSpacing)114 void DocumentView::setPageSpacing(qreal pageSpacing)
115 {
116     if(pageSpacing >= 0.0)
117     {
118         s_pageSpacing = pageSpacing;
119     }
120 }
121 
minimumScaleFactor()122 qreal DocumentView::minimumScaleFactor()
123 {
124     return s_minimumScaleFactor;
125 }
126 
maximumScaleFactor()127 qreal DocumentView::maximumScaleFactor()
128 {
129     return s_maximumScaleFactor;
130 }
131 
DocumentView(QWidget * parent)132 DocumentView::DocumentView(QWidget* parent) : QGraphicsView(parent),
133     m_autoRefreshWatcher(0),
134     m_autoRefreshTimer(0),
135     m_prefetchTimer(0),
136     m_mutex(),
137     m_document(0),
138     m_filePath(),
139     m_numberOfPages(-1),
140     m_currentPage(-1),
141     m_returnToPage(-1),
142     m_returnToLeft(0.0),
143     m_returnToTop(0.0),
144     m_continuousMode(false),
145     m_twoPagesMode(false),
146     m_scaleMode(ScaleFactor),
147     m_scaleFactor(0.1),
148     m_rotation(QPdf::Rotate0),
149     m_pagesScene(0),
150     m_pages(),
151     m_heightToIndex(),
152     m_highlight(0),
153     m_outlineModel(0),
154     m_propertiesModel(0)
155 {
156     m_pagesScene = new QGraphicsScene(this);
157     m_outlineModel = new QPdfBookmarkModel(this);
158     m_propertiesModel = new QStandardItemModel(this);
159 
160     m_filePath="";
161     m_currentPage=-1;
162     m_returnToPage=-1;
163 
164     setScene(m_pagesScene);
165 
166     setDragMode(QGraphicsView::ScrollHandDrag);
167     setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
168     setCursor(Qt::ArrowCursor);
169 //    setLineWidth(1);
170     setFrameShape(QFrame::Box);
171     setFrameShadow(QFrame::Plain);
172 //QApplication::setOverrideCursor(Qt::ArrowCursor);
173     setAcceptDrops(false);
174 
175     connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this,SLOT(on_verticalScrollBar_valueChanged(int)));
176     connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), this,SLOT(on_horizontalScrollBar_valueChanged(int)));
177 
178     // highlight
179 
180     m_highlight = new QGraphicsRectItem();
181 
182     m_highlight->setVisible(false);
183     scene()->addItem(m_highlight);
184 
185     QColor highlightColor = QApplication::palette().color(QPalette::Highlight);
186 
187     highlightColor.setAlpha(127);
188     m_highlight->setBrush(QBrush(highlightColor));
189 
190     highlightColor.setAlpha(255);
191     m_highlight->setPen(QPen(highlightColor));
192 
193 
194     // auto-refresh
195 
196     m_autoRefreshWatcher = new QFileSystemWatcher(this);
197     m_autoRefreshTimer = new QTimer(this);
198 
199     m_autoRefreshTimer->setInterval(500);
200     m_autoRefreshTimer->setSingleShot(true);
201 
202     connect(m_autoRefreshWatcher, SIGNAL(fileChanged(QString)), m_autoRefreshTimer, SLOT(start()));
203     connect(m_autoRefreshTimer, SIGNAL(timeout()), this, SLOT(refresh()));
204 
205     // prefetch
206 
207     m_prefetchTimer = new QTimer(this);
208     m_prefetchTimer->setInterval(250);
209     m_prefetchTimer->setSingleShot(true);
210 
211     connect(this, SIGNAL(currentPageChanged(int)), m_prefetchTimer, SLOT(start()));
212     connect(this, SIGNAL(scaleModeChanged(DocumentView::ScaleMode)), m_prefetchTimer, SLOT(start()));
213     connect(this, SIGNAL(scaleFactorChanged(qreal)), m_prefetchTimer, SLOT(start()));
214     connect(this, SIGNAL(rotationChanged(QPdf::Rotation)), m_prefetchTimer, SLOT(start()));
215 
216     connect(m_prefetchTimer, SIGNAL(timeout()), this,SLOT(on_prefetch_timeout()));
217 }
218 
~DocumentView()219 DocumentView::~DocumentView()
220 {
221     qDeleteAll(m_pages);
222 
223 
224 }
225 
clearAll()226 void DocumentView::clearAll()
227 {
228 disconnect(verticalScrollBar(), SIGNAL(valueChanged(int)), this,SLOT(on_verticalScrollBar_valueChanged(int)));
229 disconnect(horizontalScrollBar(), SIGNAL(valueChanged(int)),this, SLOT(on_horizontalScrollBar_valueChanged(int)));
230 disconnect(m_autoRefreshWatcher, SIGNAL(fileChanged(QString)), m_autoRefreshTimer, SLOT(start()));
231 disconnect(m_autoRefreshTimer, SIGNAL(timeout()), this, SLOT(refresh()));
232 disconnect(this, SIGNAL(currentPageChanged(int)), m_prefetchTimer, SLOT(start()));
233 disconnect(this, SIGNAL(scaleModeChanged(DocumentView::ScaleMode)), m_prefetchTimer, SLOT(start()));
234 disconnect(this, SIGNAL(scaleFactorChanged(qreal)), m_prefetchTimer, SLOT(start()));
235 disconnect(this, SIGNAL(rotationChanged(QPdf::Rotation)), m_prefetchTimer, SLOT(start()));
236 disconnect(m_prefetchTimer, SIGNAL(timeout()), this,SLOT(on_prefetch_timeout()));
237 m_pages.clear();
238 m_numberOfPages=-1;
239 scene()->clear();
240 m_pagesScene = new QGraphicsScene(this);
241 m_filePath="";
242 m_currentPage=-1;
243 m_returnToPage=-1;
244 setScene(m_pagesScene);
245 m_highlight = new QGraphicsRectItem();
246 m_highlight->setVisible(false);
247 scene()->addItem(m_highlight);
248 prepareScene();
249 prepareView(0,0);
250 QColor highlightColor = QApplication::palette().color(QPalette::Highlight);
251 highlightColor.setAlpha(127);
252 m_highlight->setBrush(QBrush(highlightColor));
253 highlightColor.setAlpha(255);
254 m_highlight->setPen(QPen(highlightColor));
255 update();
256 connect(verticalScrollBar(), SIGNAL(valueChanged(int)), SLOT(on_verticalScrollBar_valueChanged(int)));
257 connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), SLOT(on_horizontalScrollBar_valueChanged(int)));
258 connect(m_autoRefreshWatcher, SIGNAL(fileChanged(QString)), m_autoRefreshTimer, SLOT(start()));
259 connect(m_autoRefreshTimer, SIGNAL(timeout()), this, SLOT(refresh()));
260 connect(this, SIGNAL(currentPageChanged(int)), m_prefetchTimer, SLOT(start()));
261 connect(this, SIGNAL(scaleModeChanged(DocumentView::ScaleMode)), m_prefetchTimer, SLOT(start()));
262 connect(this, SIGNAL(scaleFactorChanged(qreal)), m_prefetchTimer, SLOT(start()));
263 connect(this, SIGNAL(rotationChanged(QPdf::Rotation)), m_prefetchTimer, SLOT(start()));
264 connect(m_prefetchTimer, SIGNAL(timeout()), SLOT(on_prefetch_timeout()));
265 }
266 
filePath() const267 const QString& DocumentView::filePath() const
268 {
269     return m_filePath;
270 }
271 
numberOfPages() const272 int DocumentView::numberOfPages() const
273 {
274     return m_numberOfPages;
275 }
276 
currentPage() const277 int DocumentView::currentPage() const
278 {
279     return m_currentPage;
280 }
281 
continousMode() const282 bool DocumentView::continousMode() const
283 {
284     return m_continuousMode;
285 }
286 
setContinousMode(bool continousMode)287 void DocumentView::setContinousMode(bool continousMode)
288 {
289 if (m_pages.count()<1) return;
290     if(m_continuousMode != continousMode)
291     {
292         m_continuousMode = continousMode;
293 
294         qreal left = 0.0, top = 0.0;
295         saveLeftAndTop(left, top);
296 
297         prepareView(left, top);
298 
299         emit continousModeChanged(m_continuousMode);
300     }
301 }
302 
twoPagesMode() const303 bool DocumentView::twoPagesMode() const
304 {
305     return m_twoPagesMode;
306 }
307 
setTwoPagesMode(bool twoPagesMode)308 void DocumentView::setTwoPagesMode(bool twoPagesMode)
309 {
310 if (m_pages.count()<1) return;
311     if(m_twoPagesMode != twoPagesMode)
312     {
313         m_twoPagesMode = twoPagesMode;
314 
315         if(m_twoPagesMode)
316         {
317             if(m_currentPage != (m_currentPage % 2 != 0 ? m_currentPage :  m_currentPage - 1))
318             {
319                 m_currentPage = m_currentPage % 2 != 0 ? m_currentPage :  m_currentPage - 1;
320 
321                 emit currentPageChanged(m_currentPage);
322             }
323         }
324 
325         prepareScene();
326         prepareView();
327 
328         emit twoPagesModeChanged(m_twoPagesMode);
329     }
330 }
331 
scaleMode() const332 DocumentView::ScaleMode DocumentView::scaleMode() const
333 {
334     return m_scaleMode;
335 }
336 
setScaleMode(ScaleMode scaleMode)337 void DocumentView::setScaleMode(ScaleMode scaleMode)
338 {
339 if (m_pages.count()<1) return;
340     if(m_scaleMode != scaleMode)
341     {
342         m_scaleMode = scaleMode;
343 
344         qreal left = 0.0, top = 0.0;
345         saveLeftAndTop(left, top);
346 
347         prepareScene();
348         prepareView(left, top);
349 
350         emit scaleModeChanged(m_scaleMode);
351     }
352 }
353 
scaleFactor() const354 qreal DocumentView::scaleFactor() const
355 {
356     return m_scaleFactor;
357 }
358 
realScale() const359 qreal DocumentView::realScale() const
360 {
361 if (m_pages.count()<1) return 1;
362 return m_pages.at(0)->scaleFactor();
363 }
364 
setScaleFactor(qreal scaleFactor)365 void DocumentView::setScaleFactor(qreal scaleFactor)
366 {
367 if (m_pages.count()<1) return;
368     if(m_scaleFactor != scaleFactor && scaleFactor >= s_minimumScaleFactor && scaleFactor <= s_maximumScaleFactor)
369     {
370         m_scaleFactor = scaleFactor;
371 
372         if(m_scaleMode == ScaleFactor)
373         {
374             qreal left = 0.0, top = 0.0;
375             saveLeftAndTop(left, top);
376 
377             prepareScene();
378             prepareView(left, top);
379 // #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
380 // 	    viewport()->update();
381 // #endif
382         }
383 
384         emit scaleFactorChanged(m_scaleFactor);
385     }
386 }
387 
doc() const388 QPdfDocument* DocumentView::doc() const
389 {
390    return m_document;
391 }
392 
rotation() const393 QPdf::Rotation DocumentView::rotation() const
394 {
395     return m_rotation;
396 }
397 
setRotation(QPdf::Rotation rotation)398 void DocumentView::setRotation(QPdf::Rotation rotation)
399 {
400 if (m_pages.count()<1) return;
401     if(m_rotation != rotation)
402     {
403         m_rotation = rotation;
404 
405         prepareScene();
406         prepareView();
407 
408         emit rotationChanged(m_rotation);
409     }
410 }
411 
412 
clearPaths(int index)413 void DocumentView::clearPaths(int index)
414 {
415 if ((m_pages.count()<1) || (index>=m_pages.count())) return;
416 m_pages.at(index)->clearPaths();
417 }
418 
setHighlightPath(int index,const QPainterPath & path)419 void DocumentView::setHighlightPath(int index, const QPainterPath& path)
420 {
421 if ((m_pages.count()<1) || (index>=m_pages.count())) return;
422 m_pages.at(index)->setHighlightPath(path);
423 }
424 
setSearchPath(int index,const QPainterPath & path)425 void DocumentView::setSearchPath(int index, const QPainterPath& path)
426 {
427 if ((m_pages.count()<1) || (index>=m_pages.count())) return;
428 m_pages.at(index)->setSearchPath(path);
429 }
430 
outlineModel() const431 QPdfBookmarkModel* DocumentView::outlineModel() const
432 {
433     return m_outlineModel;
434 }
435 
propertiesModel() const436 QStandardItemModel* DocumentView::propertiesModel() const
437 {
438     return m_propertiesModel;
439 }
440 
441 
442 
show()443 void DocumentView::show()
444 {
445     QGraphicsView::show();
446 
447     prepareView();
448 }
449 
open(const QString & filePath)450 bool DocumentView::open(const QString& filePath)
451 {
452     QPdfDocument* document=new QPdfDocument(this);
453     QPdfDocument::DocumentError result=document->load(filePath);
454 
455     if (result== QPdfDocument::NoError)
456     {
457         m_filePath = filePath;
458         m_numberOfPages = document->pageCount();
459         m_currentPage = 1;
460         m_returnToPage = -1;
461         prepareDocument(document);
462         prepareScene();
463         prepareView();
464         emit filePathChanged(m_filePath);
465         emit numberOfPagesChanged(m_numberOfPages);
466         emit currentPageChanged(m_currentPage);
467     }
468 
469     return result== QPdfDocument::NoError ;
470 }
471 
refresh()472 bool DocumentView::refresh()
473 {
474     QPdfDocument* document=new QPdfDocument(this);
475     QPdfDocument::DocumentError result=document->load(m_filePath);
476 
477     if (result== QPdfDocument::NoError)
478     {
479 
480         qreal left = 0.0, top = 0.0;
481         saveLeftAndTop(left, top);
482 
483         m_numberOfPages = document->pageCount();
484         m_currentPage = m_currentPage <= m_numberOfPages ? m_currentPage : 1;
485 
486         m_returnToPage = m_returnToPage <= m_numberOfPages ? m_returnToPage : -1;
487 
488         prepareDocument(document);
489 
490         prepareScene();
491         prepareView(left, top);
492 
493         emit numberOfPagesChanged(m_numberOfPages);
494         emit currentPageChanged(m_currentPage);
495     }
496 
497     return result== QPdfDocument::NoError ;
498 }
499 
print(QPrinter * printer)500 bool DocumentView::print(QPrinter* printer)
501 {
502     int fromPage = printer->fromPage() != 0 ? printer->fromPage() : 1;
503     int toPage = printer->toPage() != 0 ? printer->toPage() : m_numberOfPages;
504 
505     QProgressDialog* progressDialog = new QProgressDialog(this);
506     progressDialog->setLabelText(tr("Printing '%1'...").arg(m_filePath));
507     progressDialog->setRange(fromPage - 1, toPage);
508 
509     QPainter painter;
510     painter.begin(printer);
511 
512     for(int index = fromPage - 1; index <= toPage - 1; index++)
513     {
514         progressDialog->setValue(index);
515 
516         QApplication::processEvents();
517 
518         {
519             m_mutex.lock();
520 
521             const QSizeF size = m_document->pageSize(index);
522 
523             qreal pageWidth =  printer->physicalDpiX() / 72.0 * size.width();
524             qreal pageHeight = printer->physicalDpiY() / 72.0 * size.height();
525 
526             ////????????????????????????
527             QImage image = m_document->render(index,QSize(size.width()*printer-> physicalDpiX()/72,size.height()*printer-> physicalDpiY()/72));
528 
529             //QImage image = page->renderToImage(printer->physicalDpiX(), printer->physicalDpiY());
530 
531 
532 
533             m_mutex.unlock();
534 
535             qreal scaleFactor = qMin(printer->width() / pageWidth, printer->height() / pageHeight);
536 
537             painter.setTransform(QTransform::fromScale(scaleFactor, scaleFactor));
538             painter.drawImage(QPointF(), image);
539         }
540 
541         if(index < toPage - 1)
542         {
543             printer->newPage();
544         }
545 
546         QApplication::processEvents();
547 
548         if(progressDialog->wasCanceled())
549         {
550             delete progressDialog;
551             return false;
552         }
553     }
554 
555     painter.end();
556 
557     delete progressDialog;
558     return true;
559 }
560 
previousPage()561 void DocumentView::previousPage()
562 {
563 if (m_pages.count()<1) return;
564     jumpToPage(currentPage() - (m_twoPagesMode ? 2 : 1), 0.0, 0.0, false);
565 }
566 
nextPage()567 void DocumentView::nextPage()
568 {
569 if (m_pages.count()<1) return;
570     jumpToPage(currentPage() + (m_twoPagesMode ? 2 : 1), 0.0, 0.0, false);
571 }
572 
firstPage()573 void DocumentView::firstPage()
574 {
575 if (m_pages.count()<1) return;
576     jumpToPage(1);
577 }
578 
lastPage()579 void DocumentView::lastPage()
580 {
581 if (m_pages.count()<1) return;
582     jumpToPage(numberOfPages());
583 }
584 
jumpToPage(int page,qreal changeLeft,qreal changeTop,bool returnTo)585 void DocumentView::jumpToPage(int page, qreal changeLeft, qreal changeTop, bool returnTo)
586 {
587 if (m_pages.count()<1) return;
588     if(page >= 1 && page <= m_numberOfPages)
589     {
590         qreal left = 0.0, top = 0.0;
591         saveLeftAndTop(left, top);
592 
593         if(m_currentPage != currentPageForPage(page) || !qFuzzyCompare(1.0 + left, 1.0 + changeLeft) || !qFuzzyCompare(1.0 + top, 1.0 + changeTop))
594         {
595             if(returnTo)
596             {
597                 m_returnToPage = m_currentPage;
598                 m_returnToLeft = left; m_returnToTop = top;
599             }
600 
601             m_currentPage = currentPageForPage(page);
602 
603             prepareView(changeLeft, changeTop);
604 
605             emit currentPageChanged(m_currentPage);
606         }
607     }
608 }
609 
610 
611 
zoomIn()612 void DocumentView::zoomIn()
613 {
614 if (m_pages.count()<1) return;
615     if(scaleMode() != ScaleFactor)
616     {
617         PageItem* page = m_pages.at(m_currentPage - 1);
618 
619         setScaleFactor(qMin(page->scaleFactor() + 0.1f, s_maximumScaleFactor));
620         setScaleMode(ScaleFactor);
621     }
622     else
623     {
624         setScaleFactor(qMin(scaleFactor() + 0.1f, s_maximumScaleFactor));
625     }
626 }
627 
zoomOut()628 void DocumentView::zoomOut()
629 {
630 if (m_pages.count()<1) return;
631     if(scaleMode() != ScaleFactor)
632     {
633         PageItem* page = m_pages.at(m_currentPage - 1);
634 
635         setScaleFactor(qMax(page->scaleFactor() - 0.1f, s_minimumScaleFactor));
636         setScaleMode(ScaleFactor);
637     }
638     else
639     {
640         setScaleFactor(qMax(scaleFactor() - 0.1f, s_minimumScaleFactor));
641     }
642 }
643 
originalSize()644 void DocumentView::originalSize()
645 {
646     setScaleFactor(1.0);
647     setScaleMode(ScaleFactor);
648 }
649 
rotateLeft()650 void DocumentView::rotateLeft()
651 {
652     switch(rotation())
653     {
654     case QPdf::Rotate0:
655         setRotation(QPdf::Rotate270);
656         break;
657     case QPdf::Rotate90:
658         setRotation(QPdf::Rotate0);
659         break;
660     case QPdf::Rotate180:
661         setRotation(QPdf::Rotate90);
662         break;
663     case QPdf::Rotate270:
664         setRotation(QPdf::Rotate180);
665         break;
666     }
667 }
668 
rotateRight()669 void DocumentView::rotateRight()
670 {
671     switch(rotation())
672     {
673     case QPdf::Rotate0:
674         setRotation(QPdf::Rotate90);
675         break;
676     case QPdf::Rotate90:
677         setRotation(QPdf::Rotate180);
678         break;
679     case QPdf::Rotate180:
680         setRotation(QPdf::Rotate270);
681         break;
682     case QPdf::Rotate270:
683         setRotation(QPdf::Rotate0);
684         break;
685     }
686 }
687 
presentation()688 void DocumentView::presentation()
689 {
690 if (m_pages.count()<1) return;
691     PresentationView* presentationView = new PresentationView(&m_mutex, m_document);
692 
693     presentationView->jumpToPage(currentPage());
694 
695     presentationView->show();
696     presentationView->setAttribute(Qt::WA_DeleteOnClose);
697 }
698 
on_horizontalScrollBar_valueChanged(int value)699 void DocumentView::on_horizontalScrollBar_valueChanged(int value)
700 {
701 if (m_pages.count()<1) return;
702 if ( horizontalScrollBar()->maximum()!=0) emit doHScroll(value);
703 }
704 
on_verticalScrollBar_valueChanged(int value)705 void DocumentView::on_verticalScrollBar_valueChanged(int value)
706 {
707 if (m_pages.count()<1) return;
708     if(m_continuousMode)
709     {
710         QRectF visibleRect = mapToScene(viewport()->rect()).boundingRect();
711 
712         foreach(PageItem* page, m_pages)
713         {
714             if(!page->boundingRect().translated(page->pos()).intersects(visibleRect))
715             {
716                 page->cancelRender();
717             }
718         }
719 
720         QMap< qreal, int >::const_iterator lowerBound = m_heightToIndex.lowerBound(-value);
721 
722         if(lowerBound != m_heightToIndex.end())
723         {
724             int page = lowerBound.value() + 1;
725 
726             if(m_currentPage != page)
727             {
728                 m_currentPage = page;
729 
730                 emit currentPageChanged(m_currentPage);
731             }
732         }
733     }
734 }
735 
736 
on_prefetch_timeout()737 void DocumentView::on_prefetch_timeout()
738 {
739 if (m_pages.count()<1) return;
740     int fromPage = m_currentPage - (m_twoPagesMode ? 2 : 1);
741     int toPage = m_currentPage + (m_twoPagesMode ? 3 : 1);
742 
743     fromPage = fromPage >= 1 ? fromPage : 1;
744     toPage = toPage <= m_numberOfPages ? toPage : m_numberOfPages;
745 
746     for(int index = fromPage - 1; index <= toPage - 1; index++)
747     {
748         PageItem* page = m_pages.at(index);
749 
750         page->startRender(true);
751     }
752 }
753 
on_pages_linkClicked(int page,qreal left,qreal top)754 void DocumentView::on_pages_linkClicked(int page, qreal left, qreal top)
755 {
756 if (m_pages.count()<1) return;
757     page = page >= 1 ? page : 1;
758     page = page <= m_numberOfPages ? page : m_numberOfPages;
759 
760     left = left >= 0.0 ? left : 0.0;
761     left = left <= 1.0 ? left : 1.0;
762 
763     top = top >= 0.0 ? top : 0.0;
764     top = top <= 1.0 ? top : 1.0;
765 
766     emit gotoDest(page, left, top);
767 }
768 
on_pages_linkClicked(const QString & url)769 void DocumentView::on_pages_linkClicked(const QString& url)
770 {
771 	QUrl theurl = QUrl::fromEncoded(url.toLatin1());
772 	QDesktopServices::openUrl(theurl);
773 }
774 
resizeEvent(QResizeEvent * event)775 void DocumentView::resizeEvent(QResizeEvent* event)
776 {
777     QGraphicsView::resizeEvent(event);
778 
779     if(m_scaleMode != ScaleFactor)
780     {
781         qreal left = 0.0, top = 0.0;
782         saveLeftAndTop(left, top);
783 
784         prepareScene();
785         prepareView(left, top);
786     }
787 }
788 
keyPressEvent(QKeyEvent * event)789 void DocumentView::keyPressEvent(QKeyEvent* event)
790 {
791 if (m_pages.count()<1) return;
792     if(event->modifiers() == Qt::NoModifier)
793     {
794         if(event->key() == Qt::Key_Return)
795         {
796             jumpToPage(m_returnToPage, m_returnToLeft, m_returnToTop);
797 
798             event->accept();
799             return;
800         }
801 
802         if(!m_continuousMode)
803         {
804             if(event->key() == Qt::Key_PageUp && verticalScrollBar()->value() == verticalScrollBar()->minimum() && m_currentPage > 1)
805             {
806                 previousPage();
807 
808                 verticalScrollBar()->setValue(verticalScrollBar()->maximum());
809 
810                 event->accept();
811                 return;
812             }
813             else if(event->key() == Qt::Key_PageDown && verticalScrollBar()->value() == verticalScrollBar()->maximum() && m_currentPage != currentPageForPage(m_numberOfPages))
814             {
815                 nextPage();
816 
817                 verticalScrollBar()->setValue(verticalScrollBar()->minimum());
818 
819                 event->accept();
820                 return;
821             }
822         }
823     }
824 int qtKeyCode = event->key();
825 
826 if(event->modifiers() & Qt::ShiftModifier) {
827 	qtKeyCode += Qt::SHIFT;
828 }
829 if(event->modifiers() & Qt::ControlModifier) {
830 	qtKeyCode += Qt::CTRL;
831 }
832 if(event->modifiers() & Qt::AltModifier) {
833 	qtKeyCode += Qt::ALT;
834 }
835 if(event->modifiers() & Qt::MetaModifier) {
836 	qtKeyCode += Qt::META;
837 }
838 QKeySequence s1 = QKeySequence(qtKeyCode);
839 if (hasFocus() && (s1.matches(QKeySequence(Qt::CTRL + Qt::Key_Left))==QKeySequence::ExactMatch)) rotateLeft();
840 else if (hasFocus() && (s1.matches(QKeySequence(Qt::CTRL + Qt::Key_Right))==QKeySequence::ExactMatch)) rotateRight();
841 else QGraphicsView::keyPressEvent(event);
842 }
843 
844 
mouseReleaseEvent(QMouseEvent * event)845 void DocumentView::mouseReleaseEvent(QMouseEvent* event)
846 {
847   QApplication::setOverrideCursor(Qt::ArrowCursor);
848     QGraphicsView::mouseReleaseEvent(event);
849 }
850 
mousePressEvent(QMouseEvent * event)851 void DocumentView::mousePressEvent(QMouseEvent* event)
852 {
853     QGraphicsView::mousePressEvent(event);
854     //QApplication::setOverrideCursor(Qt::ArrowCursor);
855 
856 //     if(!event->isAccepted() && event->modifiers() == Qt::NoModifier && event->button() == Qt::RightButton)
857 //     {
858 //         QMenu* menu = new QMenu();
859 //
860 //         QAction* returnToPageAction = menu->addAction(tr("&Return to page %1").arg(m_returnToPage));
861 //         returnToPageAction->setShortcut(QKeySequence(Qt::Key_Return));
862 //         returnToPageAction->setIcon(QIcon::fromTheme("go-jump", QIcon(":icons/go-jump.svg")));
863 //         returnToPageAction->setIconVisibleInMenu(true);
864 //
865 //         returnToPageAction->setVisible(m_returnToPage != -1);
866 //
867 //         QAction* previousPageAction = menu->addAction(tr("&Previous page"));
868 //         previousPageAction->setShortcut(QKeySequence(Qt::Key_Backspace));
869 //         previousPageAction->setIcon(QIcon::fromTheme("go-previous", QIcon(":icons/go-previous.svg")));
870 //         previousPageAction->setIconVisibleInMenu(true);
871 //
872 //         QAction* nextPageAction = menu->addAction(tr("&Next page"));
873 //         nextPageAction->setShortcut(QKeySequence(Qt::Key_Space));
874 //         nextPageAction->setIcon(QIcon::fromTheme("go-next", QIcon(":icons/go-next.svg")));
875 //         nextPageAction->setIconVisibleInMenu(true);
876 //
877 //         QAction* refreshAction = menu->addAction(tr("&Refresh"));
878 //         refreshAction->setShortcut(QKeySequence::Refresh);
879 //         refreshAction->setIcon(QIcon::fromTheme("view-refresh", QIcon(":icons/view-refresh.svg")));
880 //         refreshAction->setIconVisibleInMenu(true);
881 //
882 //         QAction* action = menu->exec(event->globalPos());
883 //
884 //         if(action == returnToPageAction)
885 //         {
886 //             jumpToPage(m_returnToPage, m_returnToLeft, m_returnToTop);
887 //         }
888 //         else if(action == previousPageAction)
889 //         {
890 //             previousPage();
891 //         }
892 //         else if(action == nextPageAction)
893 //         {
894 //             nextPage();
895 //         }
896 //         else if(action == refreshAction)
897 //         {
898 //             refresh();
899 //         }
900 //
901 //         delete menu;
902 //     }
903 }
904 
wheelEvent(QWheelEvent * event)905 void DocumentView::wheelEvent(QWheelEvent* event)
906 {
907 if (m_pages.count()<1) return;
908     if(event->modifiers() == Qt::ControlModifier)
909     {
910         if(event->delta() > 0)
911         {
912             emit requestZoomIn();//zoomIn();
913         }
914         else
915         {
916             emit requestZoomOut();//zoomOut();
917         }
918 
919         event->accept();
920         return;
921     }
922     else if(event->modifiers() == Qt::ShiftModifier)
923     {
924         if(event->delta() > 0)
925         {
926             rotateLeft();
927         }
928         else
929         {
930             rotateRight();
931         }
932 
933         event->accept();
934         return;
935     }
936     else if(event->modifiers() == Qt::NoModifier)
937     {
938         if(!m_continuousMode)
939         {
940             if(event->delta() > 0 && verticalScrollBar()->value() == verticalScrollBar()->minimum() && m_currentPage > 1)
941             {
942                 previousPage();
943 
944                 verticalScrollBar()->setValue(verticalScrollBar()->maximum());
945 
946                 event->accept();
947                 return;
948             }
949             else if(event->delta() < 0 && verticalScrollBar()->value() == verticalScrollBar()->maximum() && m_currentPage != currentPageForPage(m_numberOfPages))
950             {
951                 nextPage();
952 
953                 verticalScrollBar()->setValue(verticalScrollBar()->minimum());
954 
955                 event->accept();
956                 return;
957             }
958         }
959     }
960 
961     QGraphicsView::wheelEvent(event);
962 }
963 
currentPageForPage(int page)964 int DocumentView::currentPageForPage(int page)
965 {
966     if(m_twoPagesMode)
967     {
968         return page % 2 != 0 ? page : page - 1;
969     }
970     else
971     {
972         return page;
973     }
974 }
975 
saveLeftAndTop(qreal & left,qreal & top)976 void DocumentView::saveLeftAndTop(qreal& left, qreal& top)
977 {
978 if ((m_pages.count()>0) && (m_currentPage>=1))
979     {
980     PageItem* page = m_pages.at(m_currentPage - 1);
981 
982     QRectF boundingRect = page->boundingRect().translated(page->pos());
983     QPointF topLeft = mapToScene(viewport()->rect().topLeft());
984 
985     left = (topLeft.x() - boundingRect.x()) / boundingRect.width();
986     top = (topLeft.y() - boundingRect.y()) / boundingRect.height();
987     }
988 }
989 
prepareDocument(QPdfDocument * document)990 void DocumentView::prepareDocument(QPdfDocument* document)
991 {
992     m_prefetchTimer->blockSignals(true);
993     m_prefetchTimer->stop();
994 
995     qDeleteAll(m_pages);
996 
997 
998 
999     if(m_document != 0)
1000     {
1001         delete m_document;
1002 
1003         if(!m_autoRefreshWatcher->files().isEmpty())
1004         {
1005             m_autoRefreshWatcher->removePaths(m_autoRefreshWatcher->files());
1006         }
1007     }
1008 
1009     m_document = document;
1010 
1011     if(s_autoRefresh)
1012     {
1013         m_autoRefreshWatcher->addPath(m_filePath);
1014     }
1015 
1016 //     m_document->setRenderHint(Poppler::Document::Antialiasing, s_antialiasing);
1017 //     m_document->setRenderHint(Poppler::Document::TextAntialiasing, s_textAntialiasing);
1018 //     m_document->setRenderHint(Poppler::Document::TextHinting, s_textHinting);
1019 
1020     preparePages();
1021     prepareOutline();
1022     prepareProperties();
1023 
1024     if(s_prefetch)
1025     {
1026         m_prefetchTimer->blockSignals(false);
1027         m_prefetchTimer->start();
1028     }
1029 }
1030 
preparePages()1031 void DocumentView::preparePages()
1032 {
1033     m_pages.clear();
1034     m_pages.reserve(m_numberOfPages);
1035 
1036    QProgressDialog* progressDialog = new QProgressDialog(this);
1037 //     QProgressBar* progress = new QProgressBar();
1038 //     progress->setFormat(" ");
1039 //     progress->setMaximum(0);
1040 //     progress->setMinimum(0);
1041 //    progressDialog->setBar(progress);
1042     progressDialog->setLabelText(tr("Loading pdf..."));
1043     progressDialog->setCancelButton(0);
1044     progressDialog->setRange(0,m_numberOfPages-1);
1045 //    progressDialog->setMinimumDuration(0);
1046 //    progressDialog->show();
1047 //    progressDialog->raise();
1048 
1049     for(int index = 0; index < m_numberOfPages; index++)
1050     {
1051       progressDialog->setValue(index);
1052        //QApplication::processEvents();
1053         PageItem* page = new PageItem(&m_mutex, m_document, index);
1054 const int dpr = int(qApp->devicePixelRatio());
1055 if (qApp->devicePixelRatio()>=2) page->setPhysicalDpi(physicalDpiX()*dpr, physicalDpiY()*dpr);
1056 else page->setPhysicalDpi(physicalDpiX(), physicalDpiY());
1057 
1058         m_pagesScene->addItem(page);
1059         m_pages.append(page);
1060 
1061         connect(page, SIGNAL(linkClicked(int,qreal,qreal)), SLOT(on_pages_linkClicked(int,qreal,qreal)));
1062         connect(page, SIGNAL(linkClicked(QString)), SLOT(on_pages_linkClicked(QString)));
1063 	connect(page, SIGNAL(syncpage(int, const QPointF&)), this, SLOT(on_syncpage(int, const QPointF&)));
1064 	connect(page, SIGNAL(wantPngExport(int)), this, SLOT(pngExport(int)));
1065 	connect(page, SIGNAL(wantNumWords()), this, SLOT(countWords()));
1066 	connect(page, SIGNAL(wantNumPageWords(int)), this, SLOT(countPageWords(int)));
1067 	connect(page, SIGNAL(wantOpenLocation()), this, SLOT(openFileBrowser()));
1068     }
1069 
1070 progressDialog->cancel();
1071 delete progressDialog;
1072     if(PageItem::decoratePages())
1073     {
1074         m_pagesScene->setBackgroundBrush(QBrush(Qt::darkGray));
1075     }
1076     else
1077     {
1078         m_pagesScene->setBackgroundBrush(QBrush(PageItem::invertColors() ? Qt::black : Qt::white));
1079     }
1080 }
1081 
1082 
prepareOutline()1083 void DocumentView::prepareOutline()
1084 {
1085      //m_outlineModel->clear();
1086      m_outlineModel->setDocument(m_document);
1087 }
1088 
1089 
1090 
prepareProperties()1091 void DocumentView::prepareProperties()
1092 {
1093 //     m_propertiesModel->clear();
1094 //
1095 //     QStringList keys = m_document->infoKeys();
1096 //
1097 //     m_propertiesModel->setRowCount(keys.count());
1098 //     m_propertiesModel->setColumnCount(2);
1099 //
1100 //     for(int index = 0; index < keys.count(); index++)
1101 //     {
1102 //         QString key = keys.at(index);
1103 //         QString value = m_document->info(key);
1104 //
1105 //         if(value.startsWith("D:"))
1106 //         {
1107 //             value = m_document->date(key).toString();
1108 //         }
1109 //
1110 //         m_propertiesModel->setItem(index, 0, new QStandardItem(key));
1111 //         m_propertiesModel->setItem(index, 1, new QStandardItem(value));
1112 //     }
1113 }
1114 
prepareScene()1115 void DocumentView::prepareScene()
1116 {
1117     // prepare scale factor and rotation
1118 
1119     for(int index = 0; index < m_numberOfPages; index++)
1120     {
1121         PageItem* page = m_pages.at(index);
1122         QSizeF size = page->size();
1123 
1124         if(m_scaleMode != ScaleFactor)
1125         {
1126             qreal visibleWidth = 0.0;
1127             qreal visibleHeight = 0.0;
1128 
1129             qreal pageWidth = 0.0;
1130             qreal pageHeight = 0.0;
1131 
1132             qreal scaleFactor = 1.0;
1133 
1134             if(m_twoPagesMode)
1135             {
1136                 visibleWidth = 0.5 * (viewport()->width() - 6.0 - 3.0 * s_pageSpacing);
1137             }
1138             else
1139             {
1140                 visibleWidth = viewport()->width() - 6.0 - 2.0 * s_pageSpacing;
1141             }
1142             visibleHeight = viewport()->height() - 2.0 * s_pageSpacing;
1143 
1144             switch(m_rotation)
1145             {
1146             case QPdf::Rotate0:
1147             case QPdf::Rotate180:
1148                 pageWidth = physicalDpiX() / 72.0 * size.width();
1149                 pageHeight = physicalDpiY() / 72.0 * size.height();
1150                 break;
1151             case QPdf::Rotate90:
1152             case QPdf::Rotate270:
1153                 pageWidth = physicalDpiX() / 72.0 * size.height();
1154                 pageHeight = physicalDpiY() / 72.0 * size.width();
1155                 break;
1156             }
1157 
1158             switch(m_scaleMode)
1159             {
1160             case ScaleFactor:
1161                 break;
1162             case FitToPageWidth:
1163                 scaleFactor = visibleWidth / pageWidth;
1164                 break;
1165             case FitToPageSize:
1166                 scaleFactor = qMin(visibleWidth / pageWidth, visibleHeight / pageHeight);
1167                 break;
1168             }
1169 
1170             page->setScaleFactor(scaleFactor);
1171         }
1172         else
1173         {
1174             page->setScaleFactor(m_scaleFactor);
1175         }
1176 
1177         page->setRotation(m_rotation);
1178     }
1179 
1180     // prepare layout
1181 
1182     m_heightToIndex.clear();
1183 
1184     qreal pageHeight = 0.0;
1185 
1186     qreal left = 0.0;
1187     qreal right = 0.0;
1188     qreal height = s_pageSpacing;
1189 
1190     for(int index = 0; index < m_numberOfPages; index++)
1191     {
1192         PageItem* page = m_pages.at(index);
1193         QRectF boundingRect = page->boundingRect();
1194 
1195         if(m_twoPagesMode)
1196         {
1197             if(index % 2 == 0)
1198             {
1199                 page->setPos(-boundingRect.left() - boundingRect.width() - 0.5 * s_pageSpacing, height - boundingRect.top());
1200 
1201                 m_heightToIndex.insert(-height + s_pageSpacing + 0.3 * pageHeight, index);
1202 
1203                 pageHeight = boundingRect.height();
1204 
1205                 left = qMin(left, -boundingRect.width() - 1.5f * s_pageSpacing);
1206             }
1207             else
1208             {
1209                 page->setPos(-boundingRect.left() + 0.5 * s_pageSpacing, height - boundingRect.top());
1210 
1211                 pageHeight = qMax(pageHeight, boundingRect.height());
1212 
1213                 right = qMax(right, boundingRect.width() + 1.5f * s_pageSpacing);
1214                 height += pageHeight + s_pageSpacing;
1215             }
1216         }
1217         else
1218         {
1219             page->setPos(-boundingRect.left() - 0.5 * boundingRect.width(), height - boundingRect.top());
1220 
1221             m_heightToIndex.insert(-height + s_pageSpacing + 0.3 * pageHeight, index);
1222 
1223             pageHeight = boundingRect.height();
1224 
1225             left = qMin(left, -0.5f * boundingRect.width() - s_pageSpacing);
1226             right = qMax(right, 0.5f * boundingRect.width() + s_pageSpacing);
1227             height += pageHeight + s_pageSpacing;
1228         }
1229     }
1230 
1231     if(m_twoPagesMode && m_numberOfPages % 2 != 0)
1232     {
1233         right = qMax(right, 0.5f * s_pageSpacing);
1234         height += pageHeight + s_pageSpacing;
1235     }
1236 
1237     m_pagesScene->setSceneRect(left, 0.0, right - left, height);
1238 }
1239 
prepareView(qreal changeLeft,qreal changeTop)1240 void DocumentView::prepareView(qreal changeLeft, qreal changeTop)
1241 {
1242     qreal left = m_pagesScene->sceneRect().left();
1243     qreal top = m_pagesScene->sceneRect().top();
1244     qreal width = m_pagesScene->sceneRect().width();
1245     qreal height = m_pagesScene->sceneRect().height();
1246 
1247     int horizontalValue = 0;
1248     int verticalValue = 0;
1249 
1250     for(int index = 0; index < m_pages.count(); index++)
1251     {
1252         PageItem* page = m_pages.at(index);
1253 
1254         if(m_continuousMode)
1255         {
1256             page->setVisible(true);
1257 
1258             if(index == m_currentPage - 1)
1259             {
1260                 QRectF boundingRect = page->boundingRect().translated(page->pos());
1261 
1262                 horizontalValue = qFloor(boundingRect.left() + changeLeft * boundingRect.width());
1263                 verticalValue = qFloor(boundingRect.top() + changeTop * boundingRect.height());
1264             }
1265         }
1266         else
1267         {
1268             if(index == m_currentPage - 1)
1269             {
1270                 page->setVisible(true);
1271 
1272                 QRectF boundingRect = page->boundingRect().translated(page->pos());
1273 
1274                 top = boundingRect.top() - s_pageSpacing;
1275                 height = boundingRect.height() + 2.0 * s_pageSpacing;
1276 
1277                 horizontalValue = qFloor(boundingRect.left() + changeLeft * boundingRect.width());
1278                 verticalValue = qFloor(boundingRect.top() + changeTop * boundingRect.height());
1279             }
1280             else if(m_twoPagesMode && index == m_currentPage)
1281             {
1282                 page->setVisible(true);
1283 
1284                 QRectF boundingRect = page->boundingRect().translated(page->pos());
1285 
1286                 top = qMin(top, boundingRect.top() - s_pageSpacing);
1287                 height = qMax(height, boundingRect.height() + 2.0f * s_pageSpacing);
1288             }
1289             else
1290             {
1291                 page->setVisible(false);
1292 
1293                 page->cancelRender();
1294             }
1295         }
1296 
1297     }
1298 
1299     setSceneRect(left, top, width, height);
1300 
1301     horizontalScrollBar()->setValue(horizontalValue);
1302     verticalScrollBar()->setValue(verticalValue);
1303     viewport()->update();
1304 }
1305 
prepareHighlight()1306 void DocumentView::prepareHighlight()
1307 {
1308 
1309         m_highlight->setVisible(false);
1310 }
1311 
showRect(int index,const QRectF & r)1312 void DocumentView::showRect(int index, const QRectF &r)
1313 {
1314 QGraphicsRectItem* h=new QGraphicsRectItem();
1315 jumpToPage(index+1);
1316 if (index >= m_pages.count()) return;
1317 PageItem* page = m_pages.at(index);
1318 h->setPos(page->pos());
1319 h->setTransform(page->transform());
1320 h->setRect(r.normalized());
1321 h->setVisible(true);
1322 disconnect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(on_verticalScrollBar_valueChanged(int)));
1323 centerOn(h);
1324 connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(on_verticalScrollBar_valueChanged(int)));
1325 
1326 }
1327 
on_syncpage(int index,const QPointF & pagePos)1328 void DocumentView::on_syncpage(int index, const QPointF& pagePos)
1329 {
1330 QPointF pos((pagePos.x()) / scaleFactor() / physicalDpiX() * 72.0,(pagePos.y()) / scaleFactor() / physicalDpiY() * 72.0 );
1331 emit syncpage(index, pos);
1332 }
1333 
countWords()1334 void DocumentView::countWords()
1335 {
1336 QString pdf_text="";
1337 int numwords=0;
1338 int pagewords=0;
1339 QProgressDialog progress("",tr("Cancel"), 0, m_document->pageCount(), this);
1340 progress.setWindowTitle("Texmaker");
1341 progress.setWindowModality(Qt::WindowModal);
1342 for (int i = 0; i < m_document->pageCount(); ++i)
1343   {
1344   progress.setValue(i);
1345   qApp->processEvents();
1346   if (progress.wasCanceled()) return;
1347   pagewords=0;
1348   pdf_text=m_document->checkTextAt(i, m_pages.at(i)->boundingRect(), m_pages.at(i)->boundingRect());
1349   pdf_text=pdf_text.simplified();
1350   pagewords=pdf_text.count(" ");
1351   if (!pdf_text.isEmpty()) pagewords++;
1352   numwords+=pagewords;
1353   }
1354 progress.setValue(m_document->pageCount());
1355 QMessageBox::information( this,"Texmaker",tr("Number of words in the document")+QString(" : ")+QString::number(numwords));
1356 }
1357 
pngExport(int page)1358 void DocumentView::pngExport(int page)
1359 {
1360 QImage image = m_pages.at(page)->exportImagePage();
1361 if (image.isNull()) return;
1362 QString currentDir=QDir::homePath();
1363 QFileInfo fi(m_filePath);
1364 if (fi.exists() && fi.isReadable()) currentDir=fi.absolutePath();
1365 QString fn = QFileDialog::getSaveFileName(this,tr("Save As"),currentDir,"Png Image (*.png)");
1366 if ( !fn.isEmpty() )
1367   {
1368   image.save(fn,"PNG");
1369   }
1370 }
1371 
countPageWords(int page)1372 void DocumentView::countPageWords(int page)
1373 {
1374 QString pdf_text="";
1375 int numwords=0;
1376 int pagewords=0;
1377 pdf_text=m_document->checkTextAt(page, m_pages.at(page)->boundingRect(), m_pages.at(page)->boundingRect());
1378 pdf_text=pdf_text.simplified();
1379 pagewords=pdf_text.count(" ");
1380 if (!pdf_text.isEmpty()) pagewords++;
1381 numwords+=pagewords;
1382 QMessageBox::information( this,"Texmaker",tr("Number of words in the page")+QString(" : ")+QString::number(numwords));
1383 }
1384 
openFileBrowser()1385 void DocumentView::openFileBrowser()
1386 {
1387 QString currentDir="file://";
1388 QFileInfo fi(m_filePath);
1389 if (fi.exists() && fi.isReadable()) currentDir+=fi.absolutePath();
1390 QDesktopServices::openUrl(QUrl(currentDir));
1391 }
1392 
1393 
1394