source: terepaima/terepaima-0.4.16/sources/presentationview.cpp

desarrollostretch
Last change on this file was 1f4adec, checked in by aosorio <aosorio@…>, 8 years ago

Agregado proyecto base, esto luego del dh_make -f

  • Property mode set to 100644
File size: 14.0 KB
Line 
1/*
2
3Copyright 2012-2013 Adam Reichold
4
5This file is part of qpdfview.
6
7qpdfview is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 2 of the License, or
10(at your option) any later version.
11
12qpdfview is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with qpdfview.  If not, see <http://www.gnu.org/licenses/>.
19
20*/
21
22#include "presentationview.h"
23
24#include <QKeyEvent>
25#include <QShortcut>
26#include <QTimer>
27
28#include "settings.h"
29#include "model.h"
30#include "pageitem.h"
31#include "documentview.h"
32
33namespace
34{
35
36using namespace qpdfview;
37
38inline void adjustScaleFactor(RenderParam& renderParam, qreal scaleFactor)
39{
40    if(!qFuzzyCompare(renderParam.scaleFactor(), scaleFactor))
41    {
42        renderParam.setScaleFactor(scaleFactor);
43    }
44}
45
46} // anonymous
47
48namespace qpdfview
49{
50
51Settings* PresentationView::s_settings = 0;
52
53PresentationView::PresentationView(const QVector< Model::Page* >& pages, QWidget* parent) : QGraphicsView(parent),
54    m_prefetchTimer(0),
55    m_pages(pages),
56    m_currentPage(1),
57    m_past(),
58    m_future(),
59    m_scaleMode(FitToPageSizeMode),
60    m_scaleFactor(1.0),
61    m_rotation(RotateBy0),
62    m_renderFlags(0),
63    m_pageItems()
64{
65    if(s_settings == 0)
66    {
67        s_settings = Settings::instance();
68    }
69
70    setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
71    setWindowState(windowState() | Qt::WindowFullScreen);
72
73    setFrameShape(QFrame::NoFrame);
74
75    setAcceptDrops(false);
76    setDragMode(QGraphicsView::ScrollHandDrag);
77
78    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
79    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
80
81    setScene(new QGraphicsScene(this));
82
83    preparePages();
84    prepareBackground();
85
86    // prefetch
87
88    m_prefetchTimer = new QTimer(this);
89    m_prefetchTimer->setInterval(250);
90    m_prefetchTimer->setSingleShot(true);
91
92    connect(this, SIGNAL(currentPageChanged(int)), m_prefetchTimer, SLOT(start()));
93    connect(this, SIGNAL(scaleModeChanged(ScaleMode)), m_prefetchTimer, SLOT(start()));
94    connect(this, SIGNAL(scaleFactorChanged(qreal)), m_prefetchTimer, SLOT(start()));
95    connect(this, SIGNAL(rotationChanged(Rotation)), m_prefetchTimer, SLOT(start()));
96    connect(this, SIGNAL(renderFlagsChanged(qpdfview::RenderFlags)), m_prefetchTimer, SLOT(start()));
97
98    connect(m_prefetchTimer, SIGNAL(timeout()), SLOT(on_prefetch_timeout()));
99
100    if(s_settings->documentView().prefetch())
101    {
102        m_prefetchTimer->blockSignals(false);
103        m_prefetchTimer->start();
104    }
105    else
106    {
107        m_prefetchTimer->blockSignals(true);
108        m_prefetchTimer->stop();
109    }
110
111    prepareScene();
112    prepareView();
113}
114
115PresentationView::~PresentationView()
116{
117    qDeleteAll(m_pageItems);
118}
119
120void PresentationView::setScaleMode(ScaleMode scaleMode)
121{
122    if(m_scaleMode != scaleMode && scaleMode >= 0 && scaleMode < NumberOfScaleModes)
123    {
124        m_scaleMode = scaleMode;
125
126        prepareScene();
127        prepareView();
128
129        emit scaleModeChanged(m_scaleMode);
130    }
131}
132
133void PresentationView::setScaleFactor(qreal scaleFactor)
134{
135    if(!qFuzzyCompare(m_scaleFactor, scaleFactor)
136            && scaleFactor >= s_settings->documentView().minimumScaleFactor()
137            && scaleFactor <= s_settings->documentView().maximumScaleFactor())
138    {
139        m_scaleFactor = scaleFactor;
140
141        if(m_scaleMode == ScaleFactorMode)
142        {
143            prepareScene();
144            prepareView();
145        }
146
147        emit scaleFactorChanged(m_scaleFactor);
148    }
149}
150
151void PresentationView::setRotation(Rotation rotation)
152{
153    if(m_rotation != rotation)
154    {
155        m_rotation = rotation;
156
157        prepareScene();
158        prepareView();
159
160        emit rotationChanged(m_rotation);
161    }
162}
163
164void PresentationView::setRenderFlags(qpdfview::RenderFlags renderFlags)
165{
166    if(m_renderFlags != renderFlags)
167    {
168        const qpdfview::RenderFlags changedFlags = m_renderFlags ^ renderFlags;
169
170        m_renderFlags = renderFlags;
171
172        prepareScene();
173        prepareView();
174
175        if(changedFlags.testFlag(InvertColors))
176        {
177            prepareBackground();
178        }
179
180        emit renderFlagsChanged(m_renderFlags);
181    }
182}
183
184void PresentationView::show()
185{
186    QWidget::show();
187
188    prepareView();
189}
190
191void PresentationView::previousPage()
192{
193    jumpToPage(m_currentPage - 1);
194}
195
196void PresentationView::nextPage()
197{
198    jumpToPage(m_currentPage + 1);
199}
200
201void PresentationView::firstPage()
202{
203    jumpToPage(1);
204}
205
206void PresentationView::lastPage()
207{
208    jumpToPage(m_pages.count());
209}
210
211void PresentationView::jumpToPage(int page, bool trackChange)
212{
213    if(m_currentPage != page && page >= 1 && page <= m_pages.count())
214    {
215        if(trackChange)
216        {
217            m_past.append(m_currentPage);
218        }
219
220        m_currentPage = page;
221
222        prepareView();
223
224        emit currentPageChanged(m_currentPage, trackChange);
225    }
226}
227
228void PresentationView::jumpBackward()
229{
230    if(!m_past.isEmpty())
231    {
232        m_future.prepend(m_currentPage);
233
234        jumpToPage(m_past.takeLast(), false);
235    }
236}
237
238void PresentationView::jumpForward()
239{
240    if(!m_future.isEmpty())
241    {
242        m_past.append(m_currentPage);
243
244        jumpToPage(m_future.takeFirst(), false);
245    }
246}
247
248void PresentationView::zoomIn()
249{
250    if(scaleMode() != ScaleFactorMode)
251    {
252        const qreal currentScaleFactor = m_pageItems.at(m_currentPage - 1)->renderParam().scaleFactor();
253
254        setScaleFactor(qMin(currentScaleFactor * s_settings->documentView().zoomFactor(),
255                            s_settings->documentView().maximumScaleFactor()));
256
257        setScaleMode(ScaleFactorMode);
258    }
259    else
260    {
261        setScaleFactor(qMin(m_scaleFactor * s_settings->documentView().zoomFactor(),
262                            s_settings->documentView().maximumScaleFactor()));
263    }
264}
265
266void PresentationView::zoomOut()
267{
268    if(scaleMode() != ScaleFactorMode)
269    {
270        const qreal currentScaleFactor = m_pageItems.at(m_currentPage - 1)->renderParam().scaleFactor();
271
272        setScaleFactor(qMax(currentScaleFactor / s_settings->documentView().zoomFactor(),
273                            s_settings->documentView().minimumScaleFactor()));
274
275        setScaleMode(ScaleFactorMode);
276    }
277    else
278    {
279        setScaleFactor(qMax(m_scaleFactor / s_settings->documentView().zoomFactor(),
280                            s_settings->documentView().minimumScaleFactor()));
281    }
282}
283
284void PresentationView::originalSize()
285{
286    setScaleFactor(1.0);
287    setScaleMode(ScaleFactorMode);
288}
289
290void PresentationView::rotateLeft()
291{
292    switch(m_rotation)
293    {
294    default:
295    case RotateBy0:
296        setRotation(RotateBy270);
297        break;
298    case RotateBy90:
299        setRotation(RotateBy0);
300        break;
301    case RotateBy180:
302        setRotation(RotateBy90);
303        break;
304    case RotateBy270:
305        setRotation(RotateBy180);
306        break;
307    }
308}
309
310void PresentationView::rotateRight()
311{
312    switch(m_rotation)
313    {
314    default:
315    case RotateBy0:
316        setRotation(RotateBy90);
317        break;
318    case RotateBy90:
319        setRotation(RotateBy180);
320        break;
321    case RotateBy180:
322        setRotation(RotateBy270);
323        break;
324    case RotateBy270:
325        setRotation(RotateBy0);
326        break;
327    }
328}
329
330void PresentationView::on_prefetch_timeout()
331{
332    int fromPage = m_currentPage, toPage = m_currentPage;
333
334    fromPage -= s_settings->documentView().prefetchDistance() / 2;
335    toPage += s_settings->documentView().prefetchDistance();
336
337    fromPage = qMax(fromPage, 1);
338    toPage = qMin(toPage, m_pages.count());
339
340    const int maxCost = toPage - fromPage + 1;
341    int cost = 0;
342
343    for(int index = m_currentPage - 1; index <= toPage - 1; ++index)
344    {
345        cost += m_pageItems.at(index)->startRender(true);
346
347        if(cost >= maxCost)
348        {
349            return;
350        }
351    }
352
353    for(int index = m_currentPage - 1; index >= fromPage - 1; --index)
354    {
355        cost += m_pageItems.at(index)->startRender(true);
356
357        if(cost >= maxCost)
358        {
359            return;
360        }
361    }
362}
363
364void PresentationView::on_pages_cropRectChanged()
365{
366    prepareScene();
367    prepareView();
368}
369
370void PresentationView::on_pages_linkClicked(bool newTab, int page, qreal left, qreal top)
371{
372    Q_UNUSED(newTab);
373    Q_UNUSED(left);
374    Q_UNUSED(top);
375
376    page = qMax(page, 1);
377    page = qMin(page, m_pages.count());
378
379    jumpToPage(page, true);
380}
381
382void PresentationView::resizeEvent(QResizeEvent* event)
383{
384    QGraphicsView::resizeEvent(event);
385
386    prepareScene();
387    prepareView();
388}
389
390void PresentationView::keyPressEvent(QKeyEvent* event)
391{
392    switch(event->modifiers() + event->key())
393    {
394    case Qt::Key_PageUp:
395    case Qt::Key_Up:
396    case Qt::Key_Left:
397    case Qt::Key_Backspace:
398        previousPage();
399
400        event->accept();
401        return;
402    case Qt::Key_PageDown:
403    case Qt::Key_Down:
404    case Qt::Key_Right:
405    case Qt::Key_Space:
406        nextPage();
407
408        event->accept();
409        return;
410    case Qt::Key_Home:
411        firstPage();
412
413        event->accept();
414        return;
415    case Qt::Key_End:
416        lastPage();
417
418        event->accept();
419        return;
420    case Qt::CTRL + Qt::Key_Return:
421        jumpBackward();
422
423        event->accept();
424        return;
425    case Qt::CTRL + Qt::SHIFT + Qt::Key_Return:
426        jumpForward();
427
428        event->accept();
429        return;
430    case Qt::CTRL + Qt::Key_0:
431        originalSize();
432
433        event->accept();
434        return;
435    case Qt::CTRL + Qt::Key_9:
436        setScaleMode(FitToPageWidthMode);
437
438        event->accept();
439        return;
440    case Qt::CTRL + Qt::Key_8:
441        setScaleMode(FitToPageSizeMode);
442
443        event->accept();
444        return;
445    case Qt::CTRL + Qt::Key_Up:
446        zoomIn();
447
448        event->accept();
449        return;
450    case Qt::CTRL + Qt::Key_Down:
451        zoomOut();
452
453        event->accept();
454        return;
455    case Qt::CTRL + Qt::Key_Left:
456        rotateLeft();
457
458        event->accept();
459        return;
460    case Qt::CTRL + Qt::Key_Right:
461        rotateRight();
462
463        event->accept();
464        return;
465    case Qt::CTRL + Qt::Key_I:
466        setRenderFlags(renderFlags() ^ InvertColors);
467
468        event->accept();
469        return;
470    case Qt::CTRL + Qt::Key_U:
471        setRenderFlags(renderFlags() ^ ConvertToGrayscale);
472
473        event->accept();
474        return;
475    case Qt::CTRL + Qt::SHIFT + Qt::Key_U:
476        setRenderFlags(renderFlags() ^ TrimMargins);
477
478        event->accept();
479        return;
480    case Qt::Key_F12:
481    case Qt::Key_Escape:
482        close();
483
484        event->accept();
485        return;
486    }
487
488    QWidget::keyPressEvent(event);
489}
490
491void PresentationView::wheelEvent(QWheelEvent* event)
492{
493    if(event->modifiers() == s_settings->documentView().zoomModifiers())
494    {
495        if(event->delta() > 0)
496        {
497            zoomIn();
498        }
499        else
500        {
501            zoomOut();
502        }
503
504        event->accept();
505        return;
506    }
507    else if(event->modifiers() == s_settings->documentView().rotateModifiers())
508    {
509        if(event->delta() > 0)
510        {
511            rotateLeft();
512        }
513        else
514        {
515            rotateRight();
516        }
517
518        event->accept();
519        return;
520    }
521    else if(event->modifiers() == Qt::NoModifier)
522    {
523        if(event->delta() > 0 && m_currentPage != 1)
524        {
525            previousPage();
526
527            event->accept();
528            return;
529        }
530        else if(event->delta() < 0 && m_currentPage != m_pages.count())
531        {
532            nextPage();
533
534            event->accept();
535            return;
536        }
537    }
538
539    QGraphicsView::wheelEvent(event);
540}
541
542void PresentationView::preparePages()
543{
544    for(int index = 0; index < m_pages.count(); ++index)
545    {
546        PageItem* page = new PageItem(m_pages.at(index), index, PageItem::PresentationMode);
547
548        scene()->addItem(page);
549        m_pageItems.append(page);
550
551        connect(page, SIGNAL(cropRectChanged()), SLOT(on_pages_cropRectChanged()));
552
553        connect(page, SIGNAL(linkClicked(bool,int,qreal,qreal)), SLOT(on_pages_linkClicked(bool,int,qreal,qreal)));
554    }
555}
556
557void PresentationView::prepareBackground()
558{
559    QColor backgroundColor = s_settings->presentationView().backgroundColor();
560
561    if(!backgroundColor.isValid())
562    {
563        backgroundColor = s_settings->pageItem().paperColor();
564    }
565
566    if(m_renderFlags.testFlag(InvertColors))
567    {
568        backgroundColor.setRgb(~backgroundColor.rgb());
569    }
570
571    scene()->setBackgroundBrush(QBrush(backgroundColor));
572}
573
574void PresentationView::prepareScene()
575{
576    RenderParam renderParam(logicalDpiX(), logicalDpiY(), 1.0,
577                            scaleFactor(), rotation(), renderFlags());
578
579#if QT_VERSION >= QT_VERSION_CHECK(5,1,0)
580
581    if(s_settings->pageItem().useDevicePixelRatio())
582    {
583        renderParam.setDevicePixelRatio(devicePixelRatio());
584    }
585
586#endif // QT_VERSION
587
588    const qreal visibleWidth = viewport()->width();
589    const qreal visibleHeight = viewport()->height();
590
591    foreach(PageItem* page, m_pageItems)
592    {
593        const QSizeF displayedSize = page->displayedSize(renderParam);
594
595        if(m_scaleMode == FitToPageWidthMode)
596        {
597            adjustScaleFactor(renderParam, visibleWidth / displayedSize.width());
598        }
599        else if(m_scaleMode == FitToPageSizeMode)
600        {
601            adjustScaleFactor(renderParam, qMin(visibleWidth / displayedSize.width(), visibleHeight / displayedSize.height()));
602        }
603
604        page->setRenderParam(renderParam);
605    }
606}
607
608void PresentationView::prepareView()
609{
610    for(int index = 0; index < m_pageItems.count(); ++index)
611    {
612        PageItem* page = m_pageItems.at(index);
613
614        if(index == m_currentPage - 1)
615        {
616            page->setVisible(true);
617
618            setSceneRect(page->boundingRect().translated(page->pos()));
619        }
620        else
621        {
622            page->setVisible(false);
623
624            page->cancelRender();
625        }
626
627    }
628
629    viewport()->update();
630}
631
632} // qpdfview
Note: See TracBrowser for help on using the repository browser.