From 77daa9627baea4c2ad83f6a60eed89605689c05c Mon Sep 17 00:00:00 2001 From: Fabio D'Urso Date: Tue, 30 Jul 2013 17:00:32 +0200 Subject: [PATCH] Fix the issue exposed by the previous patch Cherry-picked from a556126816875b7e2a4da3924d400e1c8bce6530 The patch de-singletons the PageController class. The PageController is now per-document and it gets deleted when the document is closed. As consequence of this, the RotationJob's done signal will not be delivered if the document has been closed, and thus this fixes the crash. --- core/document.cpp | 8 ++++++-- core/document_p.h | 3 +++ core/page.cpp | 4 ++-- core/pagecontroller.cpp | 27 +++------------------------ core/pagecontroller_p.h | 11 ++--------- 5 files changed, 16 insertions(+), 37 deletions(-) diff --git a/core/document.cpp b/core/document.cpp index 6731d8788..6d462f6ea 100644 --- a/core/document.cpp +++ b/core/document.cpp @@ -2009,8 +2009,6 @@ Document::Document( QWidget *widget ) d->m_undoStack = new QUndoStack(this); d->m_tiledObserver = 0; - connect( PageController::self(), SIGNAL(rotationFinished(int,Okular::Page*)), - this, SLOT(rotationFinished(int,Okular::Page*)) ); connect( SettingsCore::self(), SIGNAL(configChanged()), this, SLOT(_o_configChanged()) ); connect( d->m_undoStack, SIGNAL( canUndoChanged(bool) ), this, SIGNAL( canUndoChanged(bool))); connect( d->m_undoStack, SIGNAL( canRedoChanged(bool) ), this, SIGNAL( canRedoChanged(bool) ) ); @@ -2184,6 +2182,9 @@ bool Document::openDocument( const QString & docFile, const KUrl& url, const KMi } d->m_generatorName = offer->name(); + d->m_pageController = new PageController(); + connect( d->m_pageController, SIGNAL(rotationFinished(int,Okular::Page*)), + this, SLOT(rotationFinished(int,Okular::Page*)) ); bool containsExternalAnnotations = false; foreach ( Page * p, d->m_pagesVector ) @@ -2285,6 +2286,9 @@ void Document::closeDocument() if ( !d->m_generator ) return; + delete d->m_pageController; + d->m_pageController = 0; + delete d->m_scripter; d->m_scripter = 0; diff --git a/core/document_p.h b/core/document_p.h index 081fef812..3a257de42 100644 --- a/core/document_p.h +++ b/core/document_p.h @@ -38,6 +38,7 @@ struct RunningSearch; namespace Okular { class ConfigInterface; +class PageController; class SaveInterface; class Scripter; class View; @@ -97,6 +98,7 @@ class DocumentPrivate m_saveBookmarksTimer( 0 ), m_generator( 0 ), m_generatorsLoaded( false ), + m_pageController( 0 ), m_closingLoop( 0 ), m_scripter( 0 ), m_archiveData( 0 ), @@ -250,6 +252,7 @@ class DocumentPrivate // cache of the mimetype we support QStringList m_supportedMimeTypes; + PageController *m_pageController; QEventLoop *m_closingLoop; Scripter *m_scripter; diff --git a/core/page.cpp b/core/page.cpp index d1abc2fb5..0bafa997e 100644 --- a/core/page.cpp +++ b/core/page.cpp @@ -389,7 +389,7 @@ void PagePrivate::rotateAt( Rotation orientation ) RotationJob *job = new RotationJob( object.m_pixmap->toImage(), object.m_rotation, m_rotation, it.key() ); job->setPage( this ); - PageController::self()->addRotationJob(job); + m_doc->m_pageController->addRotationJob(job); } /** @@ -540,7 +540,7 @@ void Page::setPixmap( DocumentObserver *observer, QPixmap *pixmap, const Normali RotationJob *job = new RotationJob( pixmap->toImage(), Rotation0, d->m_rotation, observer ); job->setPage( d ); job->setRect( TilesManager::toRotatedRect( rect, d->m_rotation ) ); - PageController::self()->addRotationJob(job); + d->m_doc->m_pageController->addRotationJob(job); delete pixmap; } diff --git a/core/pagecontroller.cpp b/core/pagecontroller.cpp index 6997b1c25..94756f0de 100644 --- a/core/pagecontroller.cpp +++ b/core/pagecontroller.cpp @@ -17,8 +17,6 @@ #include "page_p.h" #include "rotationjob_p.h" -K_GLOBAL_STATIC( Okular::PageController, page_controller_self ) - using namespace Okular; PageController::PageController() @@ -30,23 +28,16 @@ PageController::~PageController() { } -PageController * PageController::self() -{ - return page_controller_self; -} - void PageController::addRotationJob(RotationJob *job) { - initWeaver(); + connect( job, SIGNAL(done(ThreadWeaver::Job*)), + this, SLOT(imageRotationDone(ThreadWeaver::Job*)) ); ThreadWeaver::Weaver::instance()->enqueue(job); } void PageController::imageRotationDone(ThreadWeaver::Job *j) { - RotationJob *job = qobject_cast< RotationJob * >(j); - - if ( !job ) - return; + RotationJob *job = static_cast< RotationJob * >( j ); if ( job->page() ) { @@ -58,16 +49,4 @@ void PageController::imageRotationDone(ThreadWeaver::Job *j) job->deleteLater(); } -void PageController::initWeaver() -{ - static bool weaverInited = false; - if ( weaverInited ) - return; - - connect( ThreadWeaver::Weaver::instance(), SIGNAL(jobDone(ThreadWeaver::Job*)), - this, SLOT(imageRotationDone(ThreadWeaver::Job*)) ); - - weaverInited = true; -} - #include "pagecontroller_p.moc" diff --git a/core/pagecontroller_p.h b/core/pagecontroller_p.h index a4d4df91b..55fe7bf36 100644 --- a/core/pagecontroller_p.h +++ b/core/pagecontroller_p.h @@ -21,20 +21,16 @@ namespace Okular { class Page; class RotationJob; +/* There is one PageController per document. It receives notifications of + * completed RotationJobs */ class PageController : public QObject { Q_OBJECT public: - /** - * Constructor. No NOT use this, NEVER! Use the static self() instead. - */ PageController(); - ~PageController(); - static PageController * self(); - void addRotationJob( RotationJob *job ); signals: @@ -42,9 +38,6 @@ class PageController : public QObject private slots: void imageRotationDone(ThreadWeaver::Job*); - - private: - void initWeaver(); }; }