mirror of
https://invent.kde.org/graphics/okular
synced 2024-08-27 11:40:07 +00:00
Add the ability to read from standard input, eg
$ command_that_produce_a_document | okular - Expand a but the Generator API so a generator can directly read from the raw data read from stdin. Generators that can not read from raw data will open the temporary file with the saved data. svn path=/trunk/playground/graphics/okular/; revision=622774
This commit is contained in:
parent
b9514f2310
commit
24ec1e37c5
|
@ -24,9 +24,11 @@
|
|||
#include <klibloader.h>
|
||||
#include <klocale.h>
|
||||
#include <kmessagebox.h>
|
||||
#include <kmimetype.h>
|
||||
#include <kmimetypetrader.h>
|
||||
#include <krun.h>
|
||||
#include <kstandarddirs.h>
|
||||
#include <ktemporaryfile.h>
|
||||
#include <ktoolinvocation.h>
|
||||
|
||||
// local includes
|
||||
|
@ -83,6 +85,7 @@ class Document::Private
|
|||
Private( Document *parent, QHash<QString, Generator*> * generators )
|
||||
: m_parent( parent ),
|
||||
m_lastSearchID( -1 ),
|
||||
m_tempFile( 0 ),
|
||||
m_allocatedPixmapsTotalMemory( 0 ),
|
||||
m_warnedOutOfMemory( false ),
|
||||
m_rotation( Rotation0 ),
|
||||
|
@ -125,6 +128,7 @@ class Document::Private
|
|||
// cached stuff
|
||||
QString m_docFileName;
|
||||
QString m_xmlFileName;
|
||||
KTemporaryFile *m_tempFile;
|
||||
|
||||
// viewport stuff
|
||||
QLinkedList< DocumentViewport > m_viewportHistory;
|
||||
|
@ -322,6 +326,9 @@ void Document::Private::loadDocumentInfo()
|
|||
// are still uninitialized at this point so don't access them
|
||||
{
|
||||
//kDebug() << "Using '" << d->m_xmlFileName << "' as document info file." << endl;
|
||||
if ( m_xmlFileName.isEmpty() )
|
||||
return;
|
||||
|
||||
QFile infoFile( m_xmlFileName );
|
||||
if ( !infoFile.exists() || !infoFile.open( QIODevice::ReadOnly ) )
|
||||
return;
|
||||
|
@ -585,25 +592,40 @@ static bool kserviceMoreThan( const KService::Ptr &s1, const KService::Ptr &s2 )
|
|||
return s1->property( "X-KDE-Priority" ).toInt() > s2->property( "X-KDE-Priority" ).toInt();
|
||||
}
|
||||
|
||||
bool Document::openDocument( const QString & docFile, const KUrl& url, const KMimeType::Ptr &mime )
|
||||
bool Document::openDocument( const QString & docFile, const KUrl& url, const KMimeType::Ptr &_mime )
|
||||
{
|
||||
// docFile is always local so we can use QFile on it
|
||||
QFile fileReadTest( docFile );
|
||||
if ( !fileReadTest.open( QIODevice::ReadOnly ) )
|
||||
KMimeType::Ptr mime = _mime;
|
||||
QByteArray filedata;
|
||||
bool isstdin = url.fileName( KUrl::ObeyTrailingSlash ) == QLatin1String( "-" );
|
||||
if ( !isstdin )
|
||||
{
|
||||
d->m_docFileName.clear();
|
||||
return false;
|
||||
}
|
||||
// determine the related "xml document-info" filename
|
||||
d->m_url = url;
|
||||
d->m_docFileName = docFile;
|
||||
QString fn = docFile.contains('/') ? docFile.section('/', -1, -1) : docFile;
|
||||
fn = "kpdf/" + QString::number(fileReadTest.size()) + '.' + fn + ".xml";
|
||||
fileReadTest.close();
|
||||
d->m_xmlFileName = KStandardDirs::locateLocal( "data", fn );
|
||||
if ( mime.count() <= 0 )
|
||||
return false;
|
||||
|
||||
if (mime.count()<=0)
|
||||
return false;
|
||||
// docFile is always local so we can use QFile on it
|
||||
QFile fileReadTest( docFile );
|
||||
if ( !fileReadTest.open( QIODevice::ReadOnly ) )
|
||||
{
|
||||
d->m_docFileName.clear();
|
||||
return false;
|
||||
}
|
||||
// determine the related "xml document-info" filename
|
||||
d->m_url = url;
|
||||
d->m_docFileName = docFile;
|
||||
QString fn = docFile.contains('/') ? docFile.section('/', -1, -1) : docFile;
|
||||
fn = "kpdf/" + QString::number(fileReadTest.size()) + '.' + fn + ".xml";
|
||||
fileReadTest.close();
|
||||
d->m_xmlFileName = KStandardDirs::locateLocal( "data", fn );
|
||||
}
|
||||
else
|
||||
{
|
||||
QFile qstdin;
|
||||
qstdin.open( stdin, QIODevice::ReadOnly );
|
||||
filedata = qstdin.readAll();
|
||||
mime = KMimeType::findByContent( filedata );
|
||||
if ( !mime || mime->name() == QLatin1String( "application/octet-stream" ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
// 0. load Generator
|
||||
// request only valid non-disabled plugins suitable for the mimetype
|
||||
|
@ -688,7 +710,34 @@ bool Document::openDocument( const QString & docFile, const KUrl& url, const KMi
|
|||
|
||||
// 1. load Document (and set busy cursor while loading)
|
||||
QApplication::setOverrideCursor( Qt::WaitCursor );
|
||||
bool openOk = d->m_generator->loadDocument( docFile, d->m_pagesVector );
|
||||
bool openOk = false;
|
||||
if ( !isstdin )
|
||||
{
|
||||
openOk = d->m_generator->loadDocument( docFile, d->m_pagesVector );
|
||||
}
|
||||
else if ( !filedata.isEmpty() )
|
||||
{
|
||||
if ( d->m_generator->hasFeature( Generator::ReadRawData ) )
|
||||
{
|
||||
openOk = d->m_generator->loadDocumentFromData( filedata, d->m_pagesVector );
|
||||
}
|
||||
else
|
||||
{
|
||||
d->m_tempFile = new KTemporaryFile();
|
||||
if ( !d->m_tempFile->open() )
|
||||
{
|
||||
delete d->m_tempFile;
|
||||
d->m_tempFile = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
d->m_tempFile->write( filedata );
|
||||
QString tmpFileName = d->m_tempFile->fileName();
|
||||
d->m_tempFile->close();
|
||||
openOk = d->m_generator->loadDocument( tmpFileName, d->m_pagesVector );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( int i = 0; i < d->m_pagesVector.count(); ++i )
|
||||
connect( d->m_pagesVector[ i ], SIGNAL( rotationFinished( int ) ),
|
||||
|
@ -799,6 +848,10 @@ void Document::closeDocument()
|
|||
}
|
||||
d->m_generator = 0;
|
||||
d->m_url = KUrl();
|
||||
d->m_docFileName = QString();
|
||||
d->m_xmlFileName = QString();
|
||||
delete d->m_tempFile;
|
||||
d->m_tempFile = 0;
|
||||
// remove requests left in queue
|
||||
QLinkedList< PixmapRequest * >::const_iterator sIt = d->m_pixmapRequestsStack.begin();
|
||||
QLinkedList< PixmapRequest * >::const_iterator sEnd = d->m_pixmapRequestsStack.end();
|
||||
|
|
|
@ -36,6 +36,11 @@ Generator::~Generator()
|
|||
delete d;
|
||||
}
|
||||
|
||||
bool Generator::loadDocumentFromData( const QByteArray &, QVector< Page * > & )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Generator::canGenerateTextPage() const
|
||||
{
|
||||
return false;
|
||||
|
@ -123,6 +128,12 @@ void Generator::setDocument( Document *document )
|
|||
d->m_document = document;
|
||||
}
|
||||
|
||||
bool Generator::hasFeature( GeneratorFeature ) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Generator::signalRequestDone( PixmapRequest * request )
|
||||
{
|
||||
if ( d->m_document )
|
||||
|
|
|
@ -138,6 +138,11 @@ class OKULAR_EXPORT Generator : public QObject
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum GeneratorFeature
|
||||
{
|
||||
ReadRawData ///< Whether the Generator can read a document directly from its raw data.
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new generator.
|
||||
*/
|
||||
|
@ -161,6 +166,16 @@ class OKULAR_EXPORT Generator : public QObject
|
|||
*/
|
||||
virtual bool loadDocument( const QString & fileName, QVector< Page * > & pagesVector ) = 0;
|
||||
|
||||
/**
|
||||
* Loads the document from the raw data @p fileData and fills the
|
||||
* @p pagesVector with the parsed pages.
|
||||
*
|
||||
* @note the Generator has to have the feature @ref ReadRawData enabled
|
||||
*
|
||||
* @returns true on success, false otherwise.
|
||||
*/
|
||||
virtual bool loadDocumentFromData( const QByteArray & fileData, QVector< Page * > & pagesVector );
|
||||
|
||||
/**
|
||||
* This method is called when the document is closed and not used
|
||||
* any longer.
|
||||
|
@ -288,6 +303,11 @@ class OKULAR_EXPORT Generator : public QObject
|
|||
*/
|
||||
virtual bool exportTo( const QString &fileName, const ExportFormat &format );
|
||||
|
||||
/**
|
||||
* Query for the specified @p feature.
|
||||
*/
|
||||
virtual bool hasFeature( GeneratorFeature feature ) const;
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* This signal should be emitted whenever an error occurred in the generator.
|
||||
|
|
Loading…
Reference in a new issue