~kulthauskante/npresenter/main

« back to all changes in this revision

Viewing changes to nPresenter.cpp

  • Committer: Karsten Krispin
  • Date: 2010-06-20 04:17:18 UTC
  • Revision ID: karsten@nonlimited.org-20100620041718-8ao7jp8fabg3rcsd
plenty of changes:
 * biggest change is rewrite of pdf/Document
  - it now is a singleton class which handles its loaded document by itself
  - caching is done in a seperate thread.
  - Poppler has been made "thread-safe". At least it works with threads now. ;)
  - document understands Viewport Layout.

* nPresenter
 - added help screen on start up
 - you can cycle through Viewport Layouts which Document now provides
 - interaction with new Document-Class is checked in. Could still be cleaned up a bit.

* pdf/Page
 - removed - all done in Document now

* nPresenter.doxygen
 - added configuration for doxygen.
 - We now can generate docs. Hurray! :)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#include "nPresenter.h"
2
 
#include "pdf/Page.h"
 
2
 
3
3
#include "widgets/WaitingIndicator.h"
4
4
#include "widgets/SectionViewer.h"
5
 
 
6
5
#include "widgets/PreviewCurrentPageWidget.h"
7
6
#include "widgets/PreviewNextPageWidget.h"
8
 
 
9
7
#include "widgets/ClockWidget.h"
10
8
 
11
9
 
25
23
                qDebug() << "nPresenter is singleton...";
26
24
                exit(0);
27
25
        }
 
26
        _nPresenterInstance  = this;
 
27
        
 
28
        
 
29
        _layoutNames.append("1");
 
30
        _layoutNames.append("1:N");
 
31
        _layoutNames.append("N:1");
 
32
        _layoutNamesCurrent = 0;
28
33
        
29
34
        
30
35
        this->resize(1280, 750);
31
36
        this->setWindowState(Qt::WindowMaximized);
32
37
        this->setWindowTitle("nPresenter::Notes");
33
38
        
34
 
        _nPresenterInstance  = this;
35
 
        _doc = 0;
36
 
 
37
39
        this->setupWidgets();
38
40
 
39
 
        this->connect(&_futureWatcher, SIGNAL(finished()), this, SIGNAL(currentPageReady()));
40
 
 
 
41
        
 
42
        _updateCount = 0;
 
43
        
41
44
        _freezeEnabled = false;
42
45
        _blackoutEnabled = true;
43
46
 
51
54
 
52
55
}
53
56
 
54
 
void nPresenter::updatePages()
55
 
{
56
 
 
57
 
        if(!_doc)
58
 
                return;
59
 
 
60
 
        if(_futureWatcher.isRunning())
61
 
        {
62
 
                _futureWatcher.cancel();
63
 
                _futureWatcher.waitForFinished();
64
 
        }
65
 
        
66
 
        QList<int> keys = _pages.keys();
67
 
        while(!keys.isEmpty())
68
 
                delete _pages.take(keys.takeFirst());
69
 
        
70
 
        _renderFuture = QtConcurrent::run(this, &nPresenter::renderPages);
71
 
        _futureWatcher.setFuture(_renderFuture);
72
 
        emit waitingOnPage();
73
 
        
74
 
        
75
 
}
76
 
 
77
 
void nPresenter::renderPages()
78
 
{
79
 
        
80
 
        int numPages = _doc->numPages();
81
 
        for(int i = 0; i < numPages; i++)
82
 
        {
83
 
                _pages.insert(i, _doc->page(i));
84
 
                _pages[i]->render();
85
 
        }       
86
 
}
87
57
 
88
58
void nPresenter::setupWidgets()
89
59
{
172
142
                                                widget,
173
143
                                                SLOT(enableFreeze(bool))
174
144
                                                );
175
 
 
 
145
                connect(&_document,
 
146
                                                SIGNAL(requestedViewportReady(Viewports,int,QSize)),
 
147
                                                widget,
 
148
                                                SLOT(viewportIsReady(Viewports,int,QSize)));
176
149
                connect(this,
177
 
                                                SIGNAL(currentPageReady()),
 
150
                                                SIGNAL(currentPageChanged(int)),
178
151
                                                widget,
179
 
                                                SLOT(slideChanged()));
 
152
                                                SLOT(requestPage(int)));
 
153
                
 
154
                connect(widget, SIGNAL(viewportSizeChanged(ViewportWidget*)),
 
155
                                                this, SLOT(viewportSizesChanged()));
180
156
        }
181
157
 
182
158
        _waitingIndicator = new WaitingIndicator();
183
159
        _waitingIndicator->setParent(this);
184
160
        _waitingIndicator->resize(100, 100);
185
161
        
 
162
        
186
163
        connect(this, SIGNAL(waitingOnPage()),
187
164
                                        _waitingIndicator, SLOT(show()));
188
 
        connect(this, SIGNAL(currentPageReady()),
 
165
        connect(&_document, SIGNAL(finishedRendering()),
189
166
                                        _waitingIndicator, SLOT(hide()));
190
167
        
191
168
        
196
173
 
197
174
}
198
175
 
199
 
Document * nPresenter::document()
200
 
{
201
 
        return instance()._doc;
202
 
}
203
 
 
204
 
Page & nPresenter::currentPage()
205
 
{
206
 
        Page & nullPage = instance()._nullPage;
207
 
        int currentPage = instance()._currentPage;
208
 
        
209
 
        if(!instance()._pages.contains(currentPage))
210
 
                return nullPage;
211
 
        if(instance()._pages[currentPage] == 0)
212
 
                return nullPage;
213
 
        
214
 
        return *instance()._pages[currentPage];
215
 
}
216
 
 
217
 
Page & nPresenter::nextPage()
218
 
{
219
 
        Page & nullPage = instance()._nullPage;
220
 
        int currentPage = instance()._currentPage+1;
221
 
        
222
 
        if(!instance()._pages.contains(currentPage))
223
 
                return nullPage;
224
 
        if(instance()._pages[currentPage] == 0)
225
 
                return nullPage;
226
 
        
227
 
        return *instance()._pages[currentPage];
228
 
}
229
 
 
230
 
 
231
 
QSize nPresenter::notesViewportSize()
232
 
{
233
 
        return instance()._notesViewport.viewportSize();
234
 
}
235
 
 
236
 
QRectF nPresenter::notesViewport()
237
 
{
238
 
        return QRectF(0.5, 0.0, 0.5, 1.0);
239
 
}
240
 
 
241
 
QSize nPresenter::presentationViewportSize()
242
 
{
243
 
        //qDebug() << "viewportSize:" << instance()._notesViewport.viewportSize();
244
 
        return instance()._presentationViewport.viewportSize();
245
 
        
246
 
}
247
 
 
248
 
QRectF nPresenter::presentationViewport()
249
 
{
250
 
        return QRectF(0.0, 0.0, 0.5, 1.0);
251
 
}
 
176
Document & nPresenter::document()
 
177
{
 
178
        return instance()._document;
 
179
}
 
180
 
 
181
int nPresenter::currentPage()
 
182
{
 
183
        return instance()._currentPage;
 
184
}
 
185
 
 
186
QRectF nPresenter::viewport(Document::Viewports viewport)
 
187
{
 
188
        if(viewport == Document::NotesViewport)
 
189
                return QRectF(0.5, 0.0, 0.5, 1.0);
 
190
        if(viewport == Document::PresentationOneViewport)
 
191
                return QRectF(0.0, 0.0, 0.5, 1.0);
 
192
        
 
193
        return QRectF();
 
194
}
 
195
 
252
196
 
253
197
void nPresenter::mouseReleaseEvent(QMouseEvent *event)
254
198
{
292
236
        {
293
237
                _freezeEnabled = !_freezeEnabled;
294
238
                emit this->freezeEnabled(_freezeEnabled);
295
 
                if(!_freezeEnabled && this->document())
296
 
                        emit this->currentPageReady();
297
239
        }
298
240
 
299
241
        /* key O - open a document*/
316
258
                if(!success)
317
259
                        return;
318
260
                
319
 
                
320
 
                this->updatePages();
321
 
                
322
261
                /* Check whether current page is inside document page bounds.
323
262
                         If so, set to current page.
324
263
                         So you can reload your document during presentation */
325
264
                         
326
265
                int newCurrentPage = _currentPage;
327
 
                if(newCurrentPage < 0 || newCurrentPage >= (_doc->numPages()-1))
 
266
                if(newCurrentPage < 0 || newCurrentPage >= (_document.numPages()-1))
328
267
                        newCurrentPage = 0;
329
268
                
330
269
                this->toPage(newCurrentPage);
331
 
        }
332
 
 
333
 
        /* key R - rerender pages */
334
 
        if(event->key() == Qt::Key_R)
335
 
                this->updatePages();
 
270
                this->requestAllPages();
 
271
                
 
272
                /* clear the help text */
 
273
                _notesViewport.update();
 
274
        }
 
275
 
 
276
        /* key L - cycle through viewpot layouts */
 
277
        if(event->key() == Qt::Key_L)
 
278
        { 
 
279
                _layoutNamesCurrent++;
 
280
                if(_layoutNamesCurrent >= _layoutNames.size())
 
281
                        _layoutNamesCurrent = 0;
 
282
                document().setViewportLayout(_layoutNames[_layoutNamesCurrent]);
 
283
                this->requestAllPages();
 
284
        }
 
285
 
336
286
 
337
287
        event->accept();
338
288
}
339
289
 
340
290
bool nPresenter::loadDocument(QString path)
341
291
{
342
 
        /* delete previous doc */
343
 
        Document * newDoc = 0;
344
 
        try {
345
 
                newDoc = new Document(path);
346
 
        }
347
 
        catch(...)
348
 
        {
349
 
                qDebug() << "nPresenter::loadDocument(): " << path << "failed.";
350
 
                return false;
351
 
        }
352
 
 
353
 
        if(!newDoc)
354
 
                return false;
355
 
        
356
 
        
357
 
        if(_futureWatcher.isRunning())
358
 
        {
359
 
                _futureWatcher.cancel();
360
 
                _futureWatcher.waitForFinished();
361
 
        }
362
 
        
363
 
        if(_doc)
364
 
                delete _doc;
365
 
        
366
 
        /* clear page cache */
367
 
        QList<int> keys = _pages.keys();
368
 
        while(!keys.empty())
369
 
                delete _pages.take(keys.takeFirst());
370
 
                
371
 
        _doc = newDoc;
372
 
        
373
 
        emit this->waitingOnPage();
 
292
        
 
293
        if(!_document.open(path))
 
294
                return false;
 
295
        
374
296
        emit this->documentChanged();
375
 
        this->updatePages();
376
297
        
377
298
        return true;
378
299
}
380
301
void nPresenter::showEvent(QShowEvent * event)
381
302
{
382
303
        event->accept();
383
 
        this->updatePages();
384
304
}
385
305
 
386
306
void nPresenter::hideEvent(QHideEvent *event)
394
314
        
395
315
        /* react on layout changes */
396
316
        
397
 
        if(event->type() == QEvent::MouseButtonRelease)
398
 
        {
399
 
                QMouseEvent * mEvent = dynamic_cast<QMouseEvent*>(event);
400
 
                if(!this->childAt(mEvent->pos()))
401
 
                        this->updatePages();
402
 
                        
403
 
        }
 
317
//      if(event->type() == QEvent::MouseButtonRelease)
 
318
//      {
 
319
//                      
 
320
//      }
404
321
        
405
322
        if(event->type() == QEvent::Resize || event->type() == QEvent::Paint)
406
323
        {
426
343
void nPresenter::toPage(int pageNum)
427
344
{
428
345
 
429
 
        if(!this->document())
 
346
        if(!this->document().loaded())
430
347
                return;
431
348
 
 
349
        /* page mus be inside page count boundaries */
432
350
        if(pageNum < 0)
433
351
                pageNum = 0;
434
352
 
435
 
        if(pageNum >= this->document()->numPages())
436
 
                pageNum = this->document()->numPages()-1;
 
353
        if(pageNum >= this->document().numPages())
 
354
                pageNum = this->document().numPages()-1;
437
355
 
438
356
        _currentPage = pageNum;
439
357
 
440
 
        /* signal that that the current page has changed */
 
358
        /* stop any active rendering so that the new page will show up fast */
 
359
        document().abortRendering();
 
360
 
 
361
        /* finally signal that the current page has changed */
441
362
        emit this->currentPageChanged(_currentPage);
442
 
 
443
 
        /* if the page is already rendered, signal that the page is ready */
444
 
        if(_pages.contains(_currentPage))
445
 
                emit this->currentPageReady();
446
 
 
 
363
        
 
364
        if(!document().isPageRendered(this->currentPage()))
 
365
        {
 
366
                //document().abortRendering();
 
367
                emit waitingOnPage();
 
368
        }
 
369
 
 
370
                
447
371
}
448
372
 
449
373
void nPresenter::toNextPage()
450
374
{
451
 
        if(_currentPage+1 < this->document()->numPages())
 
375
        if(_currentPage+1 < this->document().numPages())
452
376
                this->toPage(_currentPage + 1);
453
377
}
454
378
 
458
382
                this->toPage(_currentPage - 1);
459
383
}
460
384
 
461
 
 
 
385
void nPresenter::viewportSizesChanged()
 
386
{
 
387
        
 
388
        /* no document loaded. no need to update */
 
389
        if(!document().loaded())
 
390
                return;
 
391
 
 
392
        _updateCount++;
 
393
        QTimer::singleShot(500, this, SLOT(sizeChangeTimeout()));
 
394
}
 
395
 
 
396
void nPresenter::sizeChangeTimeout()
 
397
{
 
398
        _updateCount--;
 
399
        
 
400
        /* still updates active. */
 
401
        if(_updateCount > 0)
 
402
                return;
 
403
        
 
404
        this->requestAllPages();
 
405
        
 
406
}
 
407
 
 
408
void nPresenter::requestAllPages()
 
409
{
 
410
        this->document().abortRendering();
 
411
        this->document().clearCache();
 
412
        
 
413
        QList<QWidget*> widgets = qApp->allWidgets();
 
414
        //QList<QWidget*> widgets = this->findChildren<QWidget*>();
 
415
        int pageCount = document().numPages();
 
416
        
 
417
        /* first request the current page */
 
418
        for(int i = 0; i < widgets.size(); i++)
 
419
        {       
 
420
                ViewportWidget * widget = qobject_cast<ViewportWidget*>(widgets[i]);
 
421
                if(!widget)
 
422
                        continue;
 
423
                widget->requestPage(this->currentPage());
 
424
        }
 
425
        
 
426
        /* then do the rest */
 
427
        while(!widgets.empty())
 
428
        {
 
429
                ViewportWidget * widget = qobject_cast<ViewportWidget*>(widgets.takeFirst());
 
430
                
 
431
                if(!widget)
 
432
                        continue;
 
433
                
 
434
                for(int i = 0; i < pageCount; i++)
 
435
                        widget->requestPage(i);
 
436
        }
 
437
 
 
438
        emit waitingOnPage();
 
439
}