~adamreichold/qpdfview/trunk

« back to all changes in this revision

Viewing changes to presentationview.cpp

  • Committer: Adam Reichold
  • Date: 2012-07-01 17:37:17 UTC
  • Revision ID: adamreichold@myopera.com-20120701173717-rjw063ohuse3wcri
manual merge of future branch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 
 
3
Copyright 2012 Adam Reichold
 
4
 
 
5
This file is part of qpdfview.
 
6
 
 
7
qpdfview is free software: you can redistribute it and/or modify
 
8
it under the terms of the GNU General Public License as published by
 
9
the Free Software Foundation, either version 2 of the License, or
 
10
(at your option) any later version.
 
11
 
 
12
qpdfview is distributed in the hope that it will be useful,
 
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
GNU General Public License for more details.
 
16
 
 
17
You should have received a copy of the GNU General Public License
 
18
along with qpdfview.  If not, see <http://www.gnu.org/licenses/>.
 
19
 
 
20
*/
 
21
 
 
22
#include "presentationview.h"
 
23
 
 
24
PresentationView::PresentationView(QMutex* mutex, Poppler::Document* document) : QWidget(),
 
25
    m_mutex(0),
 
26
    m_document(0),
 
27
    m_numberOfPages(-1),
 
28
    m_currentPage(-1),
 
29
    m_returnToPage(-1),
 
30
    m_links(),
 
31
    m_scaleFactor(1.0),
 
32
    m_boundingRect(),
 
33
    m_linkTransform(),
 
34
    m_image1(),
 
35
    m_image2(),
 
36
    m_render(0)
 
37
{
 
38
    setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
 
39
    setWindowState(windowState() | Qt::WindowFullScreen);
 
40
    setMouseTracking(true);
 
41
 
 
42
    m_render = new QFutureWatcher< void >(this);
 
43
    connect(m_render, SIGNAL(finished()), SLOT(on_render_finished()));
 
44
 
 
45
    m_mutex = mutex;
 
46
    m_document = document;
 
47
 
 
48
    m_numberOfPages = m_document->numPages();
 
49
    m_currentPage = 1;
 
50
    m_returnToPage = -1;
 
51
 
 
52
    prepareView();
 
53
}
 
54
 
 
55
PresentationView::~PresentationView()
 
56
{
 
57
    m_render->cancel();
 
58
    m_render->waitForFinished();
 
59
}
 
60
 
 
61
int PresentationView::numberOfPages() const
 
62
{
 
63
    return m_numberOfPages;
 
64
}
 
65
 
 
66
int PresentationView::currentPage() const
 
67
{
 
68
    return m_currentPage;
 
69
}
 
70
 
 
71
void PresentationView::previousPage()
 
72
{
 
73
    jumpToPage(currentPage() - 1);
 
74
}
 
75
 
 
76
void PresentationView::nextPage()
 
77
{
 
78
    jumpToPage(currentPage() + 1);
 
79
}
 
80
 
 
81
void PresentationView::firstPage()
 
82
{
 
83
    jumpToPage(1);
 
84
}
 
85
 
 
86
void PresentationView::lastPage()
 
87
{
 
88
    jumpToPage(numberOfPages());
 
89
}
 
90
 
 
91
void PresentationView::jumpToPage(int page)
 
92
{
 
93
    if(m_currentPage != page && page >= 1 && page <= m_numberOfPages)
 
94
    {
 
95
        m_returnToPage = m_currentPage;
 
96
        m_currentPage = page;
 
97
 
 
98
        prepareView();
 
99
    }
 
100
}
 
101
 
 
102
void PresentationView::on_render_finished()
 
103
{
 
104
    if(!m_render->isCanceled())
 
105
    {
 
106
        m_image1 = m_image2;
 
107
    }
 
108
 
 
109
    if(!m_render->isRunning())
 
110
    {
 
111
        m_image2 = QImage();
 
112
    }
 
113
 
 
114
    update();
 
115
}
 
116
 
 
117
void PresentationView::resizeEvent(QResizeEvent* event)
 
118
{
 
119
    Q_UNUSED(event);
 
120
 
 
121
    prepareView();
 
122
}
 
123
 
 
124
void PresentationView::paintEvent(QPaintEvent* event)
 
125
{
 
126
    Q_UNUSED(event);
 
127
 
 
128
    QPainter painter;
 
129
    painter.begin(this);
 
130
 
 
131
    painter.fillRect(rect(), QBrush(Qt::black));
 
132
 
 
133
    if(!m_image1.isNull())
 
134
    {
 
135
        painter.drawImage(m_boundingRect.topLeft(), m_image1);
 
136
    }
 
137
    else
 
138
    {
 
139
        if(!m_render->isRunning())
 
140
        {
 
141
            m_render->setFuture(QtConcurrent::run(this, &PresentationView::render, m_currentPage - 1, m_scaleFactor));
 
142
        }
 
143
    }
 
144
 
 
145
    painter.end();
 
146
}
 
147
 
 
148
void PresentationView::keyPressEvent(QKeyEvent* event)
 
149
{
 
150
    if(event->modifiers() == Qt::NoModifier)
 
151
    {
 
152
        switch(event->key())
 
153
        {
 
154
        case Qt::Key_PageUp:
 
155
        case Qt::Key_Up:
 
156
        case Qt::Key_Left:
 
157
        case Qt::Key_Backspace:
 
158
            previousPage();
 
159
 
 
160
            event->accept();
 
161
            return;
 
162
        case Qt::Key_PageDown:
 
163
        case Qt::Key_Down:
 
164
        case Qt::Key_Right:
 
165
        case Qt::Key_Space:
 
166
            nextPage();
 
167
 
 
168
            event->accept();
 
169
            return;
 
170
        case Qt::Key_Home:
 
171
            firstPage();
 
172
 
 
173
            event->accept();
 
174
            return;
 
175
        case Qt::Key_End:
 
176
            lastPage();
 
177
 
 
178
            event->accept();
 
179
            return;
 
180
        case Qt::Key_Return:
 
181
            jumpToPage(m_returnToPage);
 
182
 
 
183
            event->accept();
 
184
            return;
 
185
        case Qt::Key_F12:
 
186
        case Qt::Key_Escape:
 
187
            close();
 
188
 
 
189
            event->accept();
 
190
            return;
 
191
        }
 
192
    }
 
193
 
 
194
    QWidget::keyPressEvent(event);
 
195
}
 
196
 
 
197
void PresentationView::mouseMoveEvent(QMouseEvent* event)
 
198
{
 
199
    QApplication::restoreOverrideCursor();
 
200
 
 
201
    foreach(Poppler::Link* link, m_links)
 
202
    {
 
203
        if(m_linkTransform.mapRect(link->linkArea().normalized()).contains(event->pos()))
 
204
        {
 
205
            if(link->linkType() == Poppler::Link::Goto)
 
206
            {
 
207
                if(!static_cast< Poppler::LinkGoto* >(link)->isExternal())
 
208
                {
 
209
                    QApplication::setOverrideCursor(Qt::PointingHandCursor);
 
210
                    QToolTip::showText(event->globalPos(), tr("Go to page %1.").arg(static_cast< Poppler::LinkGoto* >(link)->destination().pageNumber()));
 
211
 
 
212
                    return;
 
213
                }
 
214
            }
 
215
        }
 
216
    }
 
217
 
 
218
    QToolTip::hideText();
 
219
}
 
220
 
 
221
void PresentationView::mousePressEvent(QMouseEvent* event)
 
222
{
 
223
    foreach(Poppler::Link* link, m_links)
 
224
    {
 
225
        if(m_linkTransform.mapRect(link->linkArea().normalized()).contains(event->pos()))
 
226
        {
 
227
            if(link->linkType() == Poppler::Link::Goto)
 
228
            {
 
229
                Poppler::LinkGoto* linkGoto = static_cast< Poppler::LinkGoto* >(link);
 
230
 
 
231
                if(!linkGoto->isExternal())
 
232
                {
 
233
                    int page = linkGoto->destination().pageNumber();
 
234
 
 
235
                    page = page >= 1 ? page : 1;
 
236
                    page = page <= m_numberOfPages ? page : m_numberOfPages;
 
237
 
 
238
                    jumpToPage(page);
 
239
                }
 
240
            }
 
241
 
 
242
            return;
 
243
        }
 
244
    }
 
245
}
 
246
 
 
247
void PresentationView::prepareView()
 
248
{
 
249
    m_mutex->lock();
 
250
 
 
251
    Poppler::Page* page = m_document->page(m_currentPage - 1);
 
252
 
 
253
    qDeleteAll(m_links);
 
254
    m_links = page->links();
 
255
 
 
256
    QSizeF size = page->pageSizeF();
 
257
 
 
258
    delete page;
 
259
 
 
260
    m_mutex->unlock();
 
261
 
 
262
    {
 
263
        m_scaleFactor = qMin(width() / size.width(), height() / size.height());
 
264
 
 
265
        m_boundingRect.setLeft(0.5 * (width() - m_scaleFactor * size.width()));
 
266
        m_boundingRect.setTop(0.5 * (height() - m_scaleFactor * size.height()));
 
267
        m_boundingRect.setWidth(m_scaleFactor * size.width());
 
268
        m_boundingRect.setHeight(m_scaleFactor * size.height());
 
269
 
 
270
        m_linkTransform.reset();
 
271
        m_linkTransform.translate(m_boundingRect.left(), m_boundingRect.top());
 
272
        m_linkTransform.scale(m_boundingRect.width(), m_boundingRect.height());
 
273
    }
 
274
 
 
275
    m_image1 = QImage();
 
276
    m_render->cancel();
 
277
 
 
278
    update();
 
279
}
 
280
 
 
281
void PresentationView::render(int index, qreal scaleFactor)
 
282
{
 
283
    QMutexLocker mutexLocker(m_mutex);
 
284
 
 
285
    if(m_render->isCanceled())
 
286
    {
 
287
        return;
 
288
    }
 
289
 
 
290
    Poppler::Page* page = m_document->page(index);
 
291
 
 
292
    m_image2 = page->renderToImage(scaleFactor * 72.0, scaleFactor * 72.0);
 
293
 
 
294
    delete page;
 
295
}