[Okular-devel] Threaded API patch [Part 1]

Tobias Koenig tokoe at kde.org
Wed Jan 24 15:06:22 CET 2007


Hi,

attached the threaded API patch as requested by Pino

Ciao,
Tobias
-- 
Separate politics from religion and economy!
The Council of the European Union is an undemocratic and illegal institution!
-------------- next part --------------
Index: core/textdocumentgenerator.h
===================================================================
--- core/textdocumentgenerator.h	(Revision 626517)
+++ core/textdocumentgenerator.h	(Arbeitskopie)
@@ -93,11 +93,6 @@
         bool loadDocument( const QString & fileName, QVector<Okular::Page*> & pagesVector );
         bool closeDocument();
 
-        // [INHERITED] perform actions on document / pages
-        bool canGeneratePixmap( bool async ) const;
-        void generatePixmap( Okular::PixmapRequest * request );
-        void generateSyncTextPage( Okular::Page * page );
-
         bool hasFeature( GeneratorFeature feature ) const;
 
         // [INHERITED] print document using already configured kprinter
@@ -110,6 +105,12 @@
         const Okular::DocumentInfo* generateDocumentInfo();
         const Okular::DocumentSynopsis* generateDocumentSynopsis();
 
+    protected:
+        // [INHERITED] perform actions on document / pages
+        bool canGeneratePixmap() const;
+        void generatePixmap( Okular::PixmapRequest * request );
+        void generateSyncTextPage( Okular::Page * page );
+
     private:
         class Private;
         Private* const d;
Index: core/document.cpp
===================================================================
--- core/document.cpp	(Revision 626517)
+++ core/document.cpp	(Arbeitskopie)
@@ -547,7 +547,7 @@
         cleanupPixmapMemory( pixmapBytes );
 
     // submit the request to the generator
-    if ( m_generator->canGeneratePixmap( request->asynchronous() ) )
+    if ( m_generator->canRequestPixmap() )
     {
         kWarning() << "sending request id=" << request->id() << " " <<request->width() << "x" << request->height() << "@" << request->pageNumber() << " async == " << request->asynchronous() << endl;
         m_pixmapRequestsStack.removeAll ( request );
@@ -555,7 +555,7 @@
         if ( (int)m_rotation % 2 )
             request->swap();
 
-        m_generator->generatePixmap ( request );
+        m_generator->requestPixmap( request );
     }
     else
         // pino (7/4/2006): set the polling interval from 10 to 30
@@ -1255,7 +1255,7 @@
     // or else (if gen is running) it will be started when the new contents will
     //come from generator (in requestDone())</NO>
     // all handling of requests put into sendGeneratorRequest
-    //    if ( generator->canGeneratePixmap() )
+    //    if ( generator->canRequestPixmap() )
         d->sendGeneratorRequest();
 }
 
@@ -1267,7 +1267,7 @@
 
     // Memory management for TextPages
 
-    d->m_generator->generateSyncTextPage( kp );
+    d->m_generator->requestTextPage( kp );
 }
 
 void Document::addPageAnnotation( int page, Annotation * annotation )
@@ -2047,7 +2047,7 @@
 void Document::requestDone( PixmapRequest * req )
 {
 #ifndef NDEBUG
-    if ( !d->m_generator->canGeneratePixmap( req->asynchronous() ) )
+    if ( !d->m_generator->canRequestPixmap() )
         kDebug() << "requestDone with generator not in READY state." << endl;
 #endif
 
Index: core/threadedgenerator.cpp
===================================================================
--- core/threadedgenerator.cpp	(Revision 0)
+++ core/threadedgenerator.cpp	(Revision 0)
@@ -0,0 +1,109 @@
+/***************************************************************************
+ *   Copyright (C) 2007  Tobias Koenig <tokoe at kde.org>                     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ ***************************************************************************/
+
+#include "core/page.h"
+#include "core/textpage.h"
+
+#include "threadedgenerator.h"
+#include "threadedgenerator_p.h"
+
+using namespace Okular;
+
+class ThreadedGenerator::Private
+{
+    public:
+        Private( ThreadedGenerator *parent )
+            : mParent( parent ), mReady( true )
+        {
+            mPixmapGenerationThread = new PixmapGenerationThread( mParent );
+            mParent->connect( mPixmapGenerationThread, SIGNAL( finished() ),
+                              mParent, SLOT( pixmapGenerationFinished() ),
+                              Qt::QueuedConnection );
+        }
+
+        ~Private()
+        {
+            if ( mPixmapGenerationThread )
+                mPixmapGenerationThread->wait();
+
+            delete mPixmapGenerationThread;
+        }
+
+        void pixmapGenerationFinished();
+        void textpageGenerationFinished();
+
+        ThreadedGenerator *mParent;
+        PixmapGenerationThread *mPixmapGenerationThread;
+        bool mReady;
+};
+
+void ThreadedGenerator::Private::pixmapGenerationFinished()
+{
+    PixmapRequest *request = mPixmapGenerationThread->request();
+    mPixmapGenerationThread->endGeneration();
+
+    request->page()->setPixmap( request->id(), new QPixmap( QPixmap::fromImage( mPixmapGenerationThread->image() ) ) );
+
+    mReady = true;
+
+    mParent->signalRequestDone( request );
+}
+
+void ThreadedGenerator::Private::textpageGenerationFinished()
+{
+}
+
+ThreadedGenerator::ThreadedGenerator()
+    : d( new Private( this ) )
+{
+}
+
+ThreadedGenerator::~ThreadedGenerator()
+{
+    delete d;
+}
+
+bool ThreadedGenerator::canRequestPixmap() const
+{
+    return d->mReady;
+}
+
+void ThreadedGenerator::requestPixmap( PixmapRequest * request )
+{
+    d->mReady = false;
+
+    d->mPixmapGenerationThread->startGeneration( request );
+}
+
+void ThreadedGenerator::requestTextPage( Page* )
+{
+}
+
+TextPage* ThreadedGenerator::textPage( Page* )
+{
+    return 0;
+}
+
+bool ThreadedGenerator::canGeneratePixmap() const
+{
+    // dummy implementation
+    return false;
+}
+
+void ThreadedGenerator::generatePixmap( PixmapRequest* )
+{
+    // dummy implementation
+}
+
+void ThreadedGenerator::generateSyncTextPage( Page* )
+{
+    // dummy implementation
+}
+
+#include "threadedgenerator.moc"
Index: core/textdocumentgenerator.cpp
===================================================================
--- core/textdocumentgenerator.cpp	(Revision 626517)
+++ core/textdocumentgenerator.cpp	(Arbeitskopie)
@@ -238,7 +238,7 @@
     return true;
 }
 
-bool TextDocumentGenerator::canGeneratePixmap( bool ) const
+bool TextDocumentGenerator::canGeneratePixmap() const
 {
     return true;
 }
Index: core/generator.h
===================================================================
--- core/generator.h	(Revision 626517)
+++ core/generator.h	(Arbeitskopie)
@@ -197,24 +197,23 @@
         virtual bool closeDocument() = 0;
 
         /**
-         * This method returns whether the generator can create pixmaps for
-         * each page in a synchronous or asynchronous way, depending on @p async.
+         * This method returns whether the generator is ready to
+         * handle a new pixmap request.
          */
-        virtual bool canGeneratePixmap( bool async ) const = 0;
+        virtual bool canRequestPixmap() const;
 
         /**
-         * This method is called to create a pixmap for a page. The page number,
-         * width and height is encapsulated in the page @p request.
+         * This method can be called to trigger the generation of
+         * a new pixmap as described by @p request.
          */
-        virtual void generatePixmap( PixmapRequest * request ) = 0;
+        virtual void requestPixmap( PixmapRequest * request );
 
         /**
-         * This method is called to create a so called 'text page' for the given @p page.
-         *
-         * A text page is an abstract description of the readable text of the page.
-         * It's used for search and text extraction.
+         * This method can be called to trigger the generation of
+         * a text page for the given @p page.
+         * @see TextPage
          */
-        virtual void generateSyncTextPage( Page *page );
+        virtual void requestTextPage( Page * page );
 
         /**
          * Returns the general information object of the document or 0 if
@@ -335,6 +334,26 @@
         void signalRequestDone( PixmapRequest * request );
 
         /**
+         * This method is called to check whether the generator is ready
+         * to handle a new request for pixmap generation.
+         */
+        virtual bool canGeneratePixmap() const = 0;
+
+        /**
+         * This method is called to create a pixmap for a page. The page number,
+         * width and height is encapsulated in the page @p request.
+         */
+        virtual void generatePixmap( PixmapRequest * request ) = 0;
+
+        /**
+         * This method is called to create a so called 'text page' for the given @p page.
+         *
+         * A text page is an abstract description of the readable text of the page.
+         * It's used for search and text extraction.
+         */
+        virtual void generateSyncTextPage( Page *page );
+
+        /**
          * Returns a pointer to the document.
          */
         Document * document() const;
Index: core/threadedgenerator_p.h
===================================================================
--- core/threadedgenerator_p.h	(Revision 0)
+++ core/threadedgenerator_p.h	(Revision 0)
@@ -0,0 +1,65 @@
+/***************************************************************************
+ *   Copyright (C) 2007  Tobias Koenig <tokoe at kde.org>                     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ ***************************************************************************/
+
+#ifndef OKULAR_THREADEDGENERATOR_P_H
+#define OKULAR_THREADEDGENERATOR_P_H
+
+#include <QtCore/QThread>
+
+namespace Okular {
+
+class PixmapGenerationThread : public QThread
+{
+    public:
+        PixmapGenerationThread( ThreadedGenerator *generator )
+            : mGenerator( generator ), mRequest( 0 )
+        {
+        }
+
+        void startGeneration( PixmapRequest *request )
+        {
+            mRequest = request;
+
+            start( QThread::InheritPriority );
+        }
+
+        void endGeneration()
+        {
+            mRequest = 0;
+        }
+
+        PixmapRequest *request() const
+        {
+            return mRequest;
+        }
+
+        QImage image() const
+        {
+            return mImage;
+        }
+
+    protected:
+        virtual void run()
+        {
+            mImage = QImage();
+
+            if ( mRequest )
+                mImage = mGenerator->image( mRequest );
+        }
+
+    private:
+        ThreadedGenerator *mGenerator;
+        PixmapRequest *mRequest;
+        QImage mImage;
+};
+
+
+}
+
+#endif
Index: core/generator.cpp
===================================================================
--- core/generator.cpp	(Revision 626517)
+++ core/generator.cpp	(Arbeitskopie)
@@ -41,6 +41,21 @@
     return false;
 }
 
+bool Generator::canRequestPixmap() const
+{
+    return canGeneratePixmap();
+}
+
+void Generator::requestPixmap( PixmapRequest *request )
+{
+    generatePixmap( request );
+}
+
+void Generator::requestTextPage( Page *page )
+{
+    generateSyncTextPage( page );
+}
+
 void Generator::generateSyncTextPage( Page* )
 {
 }
Index: core/threadedgenerator.h
===================================================================
--- core/threadedgenerator.h	(Revision 0)
+++ core/threadedgenerator.h	(Revision 0)
@@ -0,0 +1,102 @@
+/***************************************************************************
+ *   Copyright (C) 2007  Tobias Koenig <tokoe at kde.org>                     *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ ***************************************************************************/
+
+#ifndef OKULAR_THREADEDGENERATOR_H
+#define OKULAR_THREADEDGENERATOR_H
+
+#include <okular/core/okular_export.h>
+
+#include <okular/core/generator.h>
+
+namespace Okular {
+
+/**
+ * ThreadedGenerator is meant to be a base class for Okular generators
+ * which supports multithreaded generation of page pixmaps, text pages
+ * and other data structures.
+ */
+class OKULAR_EXPORT ThreadedGenerator : public Generator
+{
+    friend class PixmapGenerationThread;
+    friend class TextPageGenerationThread;
+
+    Q_OBJECT
+
+    public:
+        /**
+         * Creates a new threaded generator.
+         */
+        ThreadedGenerator();
+
+        /**
+         * Destroys the threaded generator.
+         */
+        ~ThreadedGenerator();
+
+        /**
+         * Returns whether the generator is ready to
+         * handle a new pixmap generation request.
+         */
+        bool canRequestPixmap() const;
+
+        /**
+         * This method can be called to trigger the generation of
+         * a new pixmap as described by @p request.
+         */
+        void requestPixmap( PixmapRequest * request );
+
+        /**
+         * This method can be called to trigger the generation of
+         * a text page for the given @p page.
+         * @see TextPage
+         */
+        void requestTextPage( Page * page );
+
+    protected:
+        /**
+         * Returns the image of the page as specified in
+         * the passed pixmap @p request.
+         *
+         * Note: This method is executed in its own separated thread!
+         */
+        virtual QImage image( PixmapRequest *page ) = 0;
+
+        /**
+         * Returns the text page for the given @p page.
+         *
+         * Note: This method is executed in its own separated thread!
+         */
+        virtual TextPage* textPage( Page *page );
+
+        /**
+         * @internal
+         */
+        bool canGeneratePixmap() const;
+
+        /**
+         * @internal
+         */
+        void generatePixmap( PixmapRequest* );
+
+        /**
+         * @internal
+         */
+        void generateSyncTextPage( Page* );
+
+    private:
+        class Private;
+        Private* const d;
+
+        Q_PRIVATE_SLOT( d, void pixmapGenerationFinished() )
+        Q_PRIVATE_SLOT( d, void textpageGenerationFinished() )
+};
+
+}
+
+#endif
Index: generators/comicbook/generator_comicbook.h
===================================================================
--- generators/comicbook/generator_comicbook.h	(Revision 626517)
+++ generators/comicbook/generator_comicbook.h	(Arbeitskopie)
@@ -10,13 +10,11 @@
 #ifndef GENERATOR_COMICBOOK_H
 #define GENERATOR_COMICBOOK_H
 
-#include <okular/core/generator.h>
+#include <okular/core/threadedgenerator.h>
 
 #include "document.h"
 
-class GeneratorThread;
-
-class ComicBookGenerator : public Okular::Generator
+class ComicBookGenerator : public Okular::ThreadedGenerator
 {
     Q_OBJECT
 
@@ -28,22 +26,16 @@
         bool loadDocument( const QString & fileName, QVector<Okular::Page*> & pagesVector );
         bool closeDocument();
 
-        // [INHERITED] perform actions on document / pages
-        bool canGeneratePixmap( bool async ) const;
-        void generatePixmap( Okular::PixmapRequest * request );
-
         // [INHERITED] print document using already configured kprinter
         bool print( KPrinter& printer );
 
         bool hasFeature( GeneratorFeature feature ) const;
 
-    private Q_SLOTS:
-        void threadFinished();
+    protected:
+        QImage image( Okular::PixmapRequest * request );
 
     private:
       ComicBook::Document mDocument;
-      GeneratorThread *mThread;
-      bool mReady;
 };
 
 #endif
Index: generators/comicbook/generator_comicbook.cpp
===================================================================
--- generators/comicbook/generator_comicbook.cpp	(Revision 626517)
+++ generators/comicbook/generator_comicbook.cpp	(Arbeitskopie)
@@ -7,7 +7,6 @@
  *   (at your option) any later version.                                   *
  ***************************************************************************/
 
-#include <QtCore/QThread>
 #include <QtGui/QPainter>
 
 #include <kprinter.h>
@@ -18,78 +17,13 @@
 
 OKULAR_EXPORT_PLUGIN(ComicBookGenerator)
 
-class GeneratorThread : public QThread
-{
-    public:
-        GeneratorThread();
-
-        void startGeneration( Okular::PixmapRequest* request, ComicBook::Document *document );
-        void endGeneration();
-
-        Okular::PixmapRequest *request() const;
-        QImage image();
-
-    private:
-        void run();
-
-        Okular::PixmapRequest* mRequest;
-        QImage mImage;
-        ComicBook::Document* mDocument;
-};
-
-GeneratorThread::GeneratorThread()
-  : QThread(), mRequest( 0 ), mDocument( 0 )
-{
-}
-
-void GeneratorThread::startGeneration( Okular::PixmapRequest* request, ComicBook::Document *document )
-{
-    mRequest = request;
-    mDocument = document;
-    start( QThread::InheritPriority );
-}
-
-void GeneratorThread::endGeneration()
-{
-    mRequest = 0;
-    mDocument = 0;
-}
-
-Okular::PixmapRequest* GeneratorThread::request() const
-{
-    return mRequest;
-}
-
-QImage GeneratorThread::image()
-{
-    const QImage image = mImage;
-    mImage = QImage();
-
-    return image;
-}
-
-void GeneratorThread::run()
-{
-    int width = mRequest->width();
-    int height = mRequest->height();
-
-    mImage = mDocument->pageImage( mRequest->pageNumber() );
-    mImage = mImage.scaled( width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
-}
-
 ComicBookGenerator::ComicBookGenerator()
-    : Generator(), mReady( false )
+    : ThreadedGenerator()
 {
-    mThread = new GeneratorThread();
-    connect( mThread, SIGNAL( finished() ), this, SLOT( threadFinished() ), Qt::QueuedConnection );
 }
 
 ComicBookGenerator::~ComicBookGenerator()
 {
-    if ( mThread )
-        mThread->wait();
-
-    delete mThread;
 }
 
 bool ComicBookGenerator::loadDocument( const QString & fileName, QVector<Okular::Page*> & pagesVector )
@@ -105,57 +39,24 @@
         pagesVector[i] = page;
     }
 
-    mReady = true;
-
     return true;
 }
 
 bool ComicBookGenerator::closeDocument()
 {
-    mReady = false;
-
     return true;
 }
 
-bool ComicBookGenerator::canGeneratePixmap( bool ) const
+QImage ComicBookGenerator::image( Okular::PixmapRequest * request )
 {
-    return mReady;
-}
-
-void ComicBookGenerator::generatePixmap( Okular::PixmapRequest * request )
-{
-    mReady = false;
-
-    if ( request->asynchronous() ) {
-        mThread->startGeneration( request, &mDocument );
-        return;
-    }
-
     int width = request->width();
     int height = request->height();
 
     QImage image = mDocument.pageImage( request->pageNumber() );
-    image = image.scaled( width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
-    request->page()->setPixmap( request->id(), new QPixmap( QPixmap::fromImage( image ) ) );
 
-    mReady = true;
-
-    // signal that the request has been accomplished
-    signalRequestDone( request );
+    return image.scaled( width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
 }
 
-void ComicBookGenerator::threadFinished()
-{
-    Okular::PixmapRequest *request = mThread->request();
-    mThread->endGeneration();
-
-    request->page()->setPixmap( request->id(), new QPixmap( QPixmap::fromImage( mThread->image() ) ) );
-
-    mReady = true;
-
-    signalRequestDone( request );
-}
-
 bool ComicBookGenerator::print( KPrinter& printer )
 {
     QPainter p( &printer );
Index: generators/CMakeLists.txt
===================================================================
--- generators/CMakeLists.txt	(Revision 626517)
+++ generators/CMakeLists.txt	(Arbeitskopie)
@@ -1,33 +1,33 @@
 # let's enable the generators properly configured
 
-if(POPPLER_FOUND)
-  add_subdirectory(poppler)
-endif(POPPLER_FOUND)
+#if(POPPLER_FOUND)
+#  add_subdirectory(poppler)
+#endif(POPPLER_FOUND)
 
-if(LIBGS_FOUND)
-  add_subdirectory(ghostview)
-endif(LIBGS_FOUND)
+#if(LIBGS_FOUND)
+#  add_subdirectory(ghostview)
+#endif(LIBGS_FOUND)
 
-add_subdirectory( kimgio )
+#add_subdirectory( kimgio )
 
-if(CHM_FOUND)
-  add_subdirectory( chm )
-endif(CHM_FOUND)
+#if(CHM_FOUND)
+#  add_subdirectory( chm )
+#endif(CHM_FOUND)
 
-if(DJVULIBRE_FOUND)
-  add_subdirectory(djvu)
-endif(DJVULIBRE_FOUND)
+#if(DJVULIBRE_FOUND)
+#  add_subdirectory(djvu)
+#endif(DJVULIBRE_FOUND)
 
-add_subdirectory(dvi)
+#add_subdirectory(dvi)
 
-if(TIFF_FOUND)
-  add_subdirectory(tiff)
-endif(TIFF_FOUND)
+#if(TIFF_FOUND)
+#  add_subdirectory(tiff)
+#endif(TIFF_FOUND)
 
-add_subdirectory(xps)
+#add_subdirectory(xps)
 
-add_subdirectory(ooo)
+#add_subdirectory(ooo)
 
-add_subdirectory(fictionbook)
+#add_subdirectory(fictionbook)
 
 add_subdirectory(comicbook)
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt	(Revision 626517)
+++ CMakeLists.txt	(Arbeitskopie)
@@ -48,6 +48,7 @@
    core/sourcereference.cpp
    core/textdocumentgenerator.cpp
    core/textpage.cpp
+   core/threadedgenerator.cpp
    core/utils.cpp
 )
 
@@ -65,6 +66,7 @@
            core/sourcereference.h
            core/textdocumentgenerator.h
            core/textpage.h
+           core/threadedgenerator.h
            core/utils.h
          DESTINATION ${INCLUDE_INSTALL_DIR}/okular/core )
 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://mail.kde.org/pipermail/okular-devel/attachments/20070124/9e01f77e/attachment.pgp 


More information about the Okular-devel mailing list