• Skip to content
  • Skip to link menu
KDE 4.0 API Reference
  • KDE API Reference
  • kdegraphics
  • Sitemap
  • Contact Us
 

okular

generator.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2005   by Piotr Szymanski <niedakh@gmail.com>           *
00003  *                                                                         *
00004  *   This program is free software; you can redistribute it and/or modify  *
00005  *   it under the terms of the GNU General Public License as published by  *
00006  *   the Free Software Foundation; either version 2 of the License, or     *
00007  *   (at your option) any later version.                                   *
00008  ***************************************************************************/
00009 
00010 #include "generator.h"
00011 #include "generator_p.h"
00012 
00013 #include <qeventloop.h>
00014 #include <QtGui/QPrinter>
00015 
00016 #include <kdebug.h>
00017 #include <kicon.h>
00018 #include <klocale.h>
00019 
00020 #include "document.h"
00021 #include "document_p.h"
00022 #include "page.h"
00023 #include "textpage.h"
00024 
00025 using namespace Okular;
00026 
00027 GeneratorPrivate::GeneratorPrivate()
00028     : m_document( 0 ),
00029       mPixmapGenerationThread( 0 ), mTextPageGenerationThread( 0 ),
00030       m_mutex( 0 ), m_threadsMutex( 0 ), mPixmapReady( true ), mTextPageReady( true ),
00031       m_closing( false ), m_closingLoop( 0 )
00032 {
00033 }
00034 
00035 GeneratorPrivate::~GeneratorPrivate()
00036 {
00037     if ( mPixmapGenerationThread )
00038         mPixmapGenerationThread->wait();
00039 
00040     delete mPixmapGenerationThread;
00041 
00042     if ( mTextPageGenerationThread )
00043         mTextPageGenerationThread->wait();
00044 
00045     delete mTextPageGenerationThread;
00046 
00047     delete m_mutex;
00048     delete m_threadsMutex;
00049 }
00050 
00051 PixmapGenerationThread* GeneratorPrivate::pixmapGenerationThread()
00052 {
00053     if ( mPixmapGenerationThread )
00054         return mPixmapGenerationThread;
00055 
00056     Q_Q( Generator );
00057     mPixmapGenerationThread = new PixmapGenerationThread( q );
00058     QObject::connect( mPixmapGenerationThread, SIGNAL( finished() ),
00059                       q, SLOT( pixmapGenerationFinished() ),
00060                       Qt::QueuedConnection );
00061 
00062     return mPixmapGenerationThread;
00063 }
00064 
00065 TextPageGenerationThread* GeneratorPrivate::textPageGenerationThread()
00066 {
00067     if ( mTextPageGenerationThread )
00068         return mTextPageGenerationThread;
00069 
00070     Q_Q( Generator );
00071     mTextPageGenerationThread = new TextPageGenerationThread( q );
00072     QObject::connect( mTextPageGenerationThread, SIGNAL( finished() ),
00073                       q, SLOT( textpageGenerationFinished() ),
00074                       Qt::QueuedConnection );
00075 
00076     return mTextPageGenerationThread;
00077 }
00078 
00079 void GeneratorPrivate::pixmapGenerationFinished()
00080 {
00081     Q_Q( Generator );
00082     PixmapRequest *request = mPixmapGenerationThread->request();
00083     mPixmapGenerationThread->endGeneration();
00084 
00085     QMutexLocker locker( threadsLock() );
00086     mPixmapReady = true;
00087 
00088     if ( m_closing )
00089     {
00090         delete request;
00091         if ( mTextPageReady )
00092         {
00093             locker.unlock();
00094             m_closingLoop->quit();
00095         }
00096         return;
00097     }
00098 
00099     request->page()->setPixmap( request->id(), new QPixmap( QPixmap::fromImage( mPixmapGenerationThread->image() ) ) );
00100 
00101     q->signalPixmapRequestDone( request );
00102 }
00103 
00104 void GeneratorPrivate::textpageGenerationFinished()
00105 {
00106     Page *page = mTextPageGenerationThread->page();
00107     mTextPageGenerationThread->endGeneration();
00108 
00109     QMutexLocker locker( threadsLock() );
00110     mTextPageReady = true;
00111 
00112     if ( m_closing )
00113     {
00114         delete mTextPageGenerationThread->textPage();
00115         if ( mPixmapReady )
00116         {
00117             locker.unlock();
00118             m_closingLoop->quit();
00119         }
00120         return;
00121     }
00122 
00123     if ( mTextPageGenerationThread->textPage() )
00124         page->setTextPage( mTextPageGenerationThread->textPage() );
00125 }
00126 
00127 QMutex* GeneratorPrivate::threadsLock()
00128 {
00129     if ( !m_threadsMutex )
00130         m_threadsMutex = new QMutex();
00131     return m_threadsMutex;
00132 }
00133 
00134 
00135 Generator::Generator( QObject *parent, const QVariantList &args )
00136     : QObject( parent ), d_ptr( new GeneratorPrivate() )
00137 {
00138     d_ptr->q_ptr = this;
00139     Q_UNUSED( args )
00140 }
00141 
00142 Generator::Generator( GeneratorPrivate &dd, QObject *parent, const QVariantList &args )
00143     : QObject( parent ), d_ptr( &dd )
00144 {
00145     d_ptr->q_ptr = this;
00146     Q_UNUSED( args )
00147 }
00148 
00149 Generator::~Generator()
00150 {
00151     delete d_ptr;
00152 }
00153 
00154 bool Generator::loadDocumentFromData( const QByteArray &, QVector< Page * > & )
00155 {
00156     return false;
00157 }
00158 
00159 bool Generator::closeDocument()
00160 {
00161     Q_D( Generator );
00162 
00163     d->m_closing = true;
00164 
00165     d->threadsLock()->lock();
00166     if ( !( d->mPixmapReady && d->mTextPageReady ) )
00167     {
00168         QEventLoop loop;
00169         d->m_closingLoop = &loop;
00170 
00171         d->threadsLock()->unlock();
00172 
00173         loop.exec();
00174 
00175         d->m_closingLoop = 0;
00176     }
00177     else
00178     {
00179         d->threadsLock()->unlock();
00180     }
00181 
00182     bool ret = doCloseDocument();
00183 
00184     d->m_closing = false;
00185 
00186     return ret;
00187 }
00188 
00189 bool Generator::canGeneratePixmap() const
00190 {
00191     Q_D( const Generator );
00192     return d->mPixmapReady;
00193 }
00194 
00195 void Generator::generatePixmap( PixmapRequest *request )
00196 {
00197     Q_D( Generator );
00198     d->mPixmapReady = false;
00199 
00200     if ( hasFeature( Threaded ) )
00201     {
00202         d->pixmapGenerationThread()->startGeneration( request );
00203 
00208         if ( hasFeature( TextExtraction ) && !request->page()->hasTextPage() && canGenerateTextPage() ) {
00209             d->mTextPageReady = false;
00210             d->textPageGenerationThread()->startGeneration( request->page() );
00211         }
00212 
00213         return;
00214     }
00215 
00216     request->page()->setPixmap( request->id(), new QPixmap( QPixmap::fromImage( image( request ) ) ) );
00217 
00218     d->mPixmapReady = true;
00219 
00220     signalPixmapRequestDone( request );
00221 }
00222 
00223 bool Generator::canGenerateTextPage() const
00224 {
00225     Q_D( const Generator );
00226     return d->mTextPageReady;
00227 }
00228 
00229 void Generator::generateTextPage( Page *page )
00230 {
00231     Q_D( Generator );
00232     page->setTextPage( textPage( page ) );
00233     d->mTextPageReady = true;
00234 }
00235 
00236 QImage Generator::image( PixmapRequest * )
00237 {
00238     return QImage();
00239 }
00240 
00241 TextPage* Generator::textPage( Page* )
00242 {
00243     return 0;
00244 }
00245 
00246 const DocumentInfo * Generator::generateDocumentInfo()
00247 {
00248     return 0;
00249 }
00250 
00251 const DocumentSynopsis * Generator::generateDocumentSynopsis()
00252 {
00253     return 0;
00254 }
00255 
00256 FontInfo::List Generator::fontsForPage( int )
00257 {
00258     return FontInfo::List();
00259 }
00260 
00261 const QList<EmbeddedFile*> * Generator::embeddedFiles() const
00262 {
00263     return 0;
00264 }
00265 
00266 Generator::PageSizeMetric Generator::pagesSizeMetric() const
00267 {
00268     return None;
00269 }
00270 
00271 bool Generator::isAllowed( Permission ) const
00272 {
00273     return true;
00274 }
00275 
00276 void Generator::rotationChanged( Rotation, Rotation )
00277 {
00278 }
00279 
00280 PageSize::List Generator::pageSizes() const
00281 {
00282     return PageSize::List();
00283 }
00284 
00285 void Generator::pageSizeChanged( const PageSize &, const PageSize & )
00286 {
00287 }
00288 
00289 bool Generator::print( QPrinter& )
00290 {
00291     return false;
00292 }
00293 
00294 QVariant Generator::metaData( const QString&, const QVariant& ) const
00295 {
00296     return QVariant();
00297 }
00298 
00299 ExportFormat::List Generator::exportFormats() const
00300 {
00301     return ExportFormat::List();
00302 }
00303 
00304 bool Generator::exportTo( const QString&, const ExportFormat& )
00305 {
00306     return false;
00307 }
00308 
00309 bool Generator::hasFeature( GeneratorFeature feature ) const
00310 {
00311     Q_D( const Generator );
00312     return d->m_features.contains( feature );
00313 }
00314 
00315 void Generator::signalPixmapRequestDone( PixmapRequest * request )
00316 {
00317     Q_D( Generator );
00318     if ( d->m_document )
00319         d->m_document->requestDone( request );
00320     else
00321     {
00322         delete request;
00323     }
00324 }
00325 
00326 const Document * Generator::document() const
00327 {
00328     Q_D( const Generator );
00329     return d->m_document->m_parent;
00330 }
00331 
00332 void Generator::setFeature( GeneratorFeature feature, bool on )
00333 {
00334     Q_D( Generator );
00335     if ( on )
00336         d->m_features.insert( feature );
00337     else
00338         d->m_features.remove( feature );
00339 }
00340 
00341 QVariant Generator::documentMetaData( const QString &key, const QVariant &option ) const
00342 {
00343     Q_D( const Generator );
00344     if ( !d->m_document )
00345         return QVariant();
00346 
00347     return d->m_document->documentMetaData( key, option );
00348 }
00349 
00350 QMutex* Generator::userMutex() const
00351 {
00352     Q_D( const Generator );
00353     if ( !d->m_mutex )
00354     {
00355         d->m_mutex = new QMutex();
00356     }
00357     return d->m_mutex;
00358 }
00359 
00360 
00361 PixmapRequest::PixmapRequest( int id, int pageNumber, int width, int height, int priority, bool asynchronous )
00362   : d( new PixmapRequestPrivate )
00363 {
00364     d->mId = id;
00365     d->mPageNumber = pageNumber;
00366     d->mWidth = width;
00367     d->mHeight = height;
00368     d->mPriority = priority;
00369     d->mAsynchronous = asynchronous;
00370 }
00371 
00372 PixmapRequest::~PixmapRequest()
00373 {
00374     delete d;
00375 }
00376 
00377 int PixmapRequest::id() const
00378 {
00379     return d->mId;
00380 }
00381 
00382 int PixmapRequest::pageNumber() const
00383 {
00384     return d->mPageNumber;
00385 }
00386 
00387 int PixmapRequest::width() const
00388 {
00389     return d->mWidth;
00390 }
00391 
00392 int PixmapRequest::height() const
00393 {
00394     return d->mHeight;
00395 }
00396 
00397 int PixmapRequest::priority() const
00398 {
00399     return d->mPriority;
00400 }
00401 
00402 bool PixmapRequest::asynchronous() const
00403 {
00404     return d->mAsynchronous;
00405 }
00406 
00407 Page* PixmapRequest::page() const
00408 {
00409     return d->mPage;
00410 }
00411 
00412 void PixmapRequestPrivate::swap()
00413 {
00414     qSwap( mWidth, mHeight );
00415 }
00416 
00417 class Okular::ExportFormatPrivate : public QSharedData
00418 {
00419     public:
00420         ExportFormatPrivate( const QString &description, const KMimeType::Ptr &mimeType, const KIcon &icon = KIcon() )
00421             : QSharedData(), mDescription( description ), mMimeType( mimeType ), mIcon( icon )
00422         {
00423         }
00424         ~ExportFormatPrivate()
00425         {
00426         }
00427 
00428         QString mDescription;
00429         KMimeType::Ptr mMimeType;
00430         KIcon mIcon;
00431 };
00432 
00433 ExportFormat::ExportFormat()
00434     : d( new ExportFormatPrivate( QString(), KMimeType::Ptr() ) )
00435 {
00436 }
00437 
00438 ExportFormat::ExportFormat( const QString &description, const KMimeType::Ptr &mimeType )
00439     : d( new ExportFormatPrivate( description, mimeType ) )
00440 {
00441 }
00442 
00443 ExportFormat::ExportFormat( const KIcon &icon, const QString &description, const KMimeType::Ptr &mimeType )
00444     : d( new ExportFormatPrivate( description, mimeType, icon ) )
00445 {
00446 }
00447 
00448 ExportFormat::~ExportFormat()
00449 {
00450 }
00451 
00452 ExportFormat::ExportFormat( const ExportFormat &other )
00453     : d( other.d )
00454 {
00455 }
00456 
00457 ExportFormat& ExportFormat::operator=( const ExportFormat &other )
00458 {
00459     if ( this == &other )
00460         return *this;
00461 
00462     d = other.d;
00463 
00464     return *this;
00465 }
00466 
00467 QString ExportFormat::description() const
00468 {
00469     return d->mDescription;
00470 }
00471 
00472 KMimeType::Ptr ExportFormat::mimeType() const
00473 {
00474     return d->mMimeType;
00475 }
00476 
00477 KIcon ExportFormat::icon() const
00478 {
00479     return d->mIcon;
00480 }
00481 
00482 bool ExportFormat::isNull() const
00483 {
00484     return d->mMimeType.isNull() || d->mDescription.isNull();
00485 }
00486 
00487 ExportFormat ExportFormat::standardFormat( StandardExportFormat type )
00488 {
00489     switch ( type )
00490     {
00491         case PlainText:
00492             return ExportFormat( KIcon( "text-x-generic" ), i18n( "Plain &Text..." ), KMimeType::mimeType( "text/plain" ) );
00493             break;
00494         case PDF:
00495             return ExportFormat( KIcon( "application-pdf" ), i18n( "PDF" ), KMimeType::mimeType( "application/pdf" ) );
00496             break;
00497     }
00498     return ExportFormat();
00499 }
00500 
00501 bool ExportFormat::operator==( const ExportFormat &other ) const
00502 {
00503     return d == other.d;
00504 }
00505 
00506 bool ExportFormat::operator!=( const ExportFormat &other ) const
00507 {
00508     return d != other.d;
00509 }
00510 
00511 QDebug operator<<( QDebug str, const Okular::PixmapRequest &req )
00512 {
00513     QString s = QString( "%1 PixmapRequest (id: %2) (%3x%4), prio %5, pageNo %6" )
00514         .arg( QString( req.asynchronous() ? "Async" : "Sync" ) )
00515         .arg( req.id() )
00516         .arg( req.width() )
00517         .arg( req.height() )
00518         .arg( req.priority() )
00519         .arg( req.pageNumber() );
00520     str << qPrintable( s );
00521     return str;
00522 }
00523 
00524 #include "generator.moc"

okular

Skip menu "okular"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdegraphics

Skip menu "kdegraphics"
  • okular
Generated for kdegraphics by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal