diff --git a/autotests/mainshelltest.cpp b/autotests/mainshelltest.cpp index 118cfbc1c..90b5ec5a4 100644 --- a/autotests/mainshelltest.cpp +++ b/autotests/mainshelltest.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include "../shell/okular_main.h" @@ -108,6 +109,7 @@ Shell *findShell(Shell *ignore = 0) void MainShellTest::initTestCase() { + QStandardPaths::setTestModeEnabled(true); // Don't pollute people's okular settings Okular::Settings::instance( QStringLiteral("mainshelltest") ); @@ -331,8 +333,7 @@ void MainShellTest::testShell() QCOMPARE(p.state(), QProcess::Running); p.terminate(); p.waitForFinished(); - QCOMPARE(p.exitCode(), 0); - + QVERIFY(p.state() != QProcess::Running); // It opened on a new process, so no change for us QCOMPARE(s->m_tabs.count(), 1); QCOMPARE(part->url().url(), QString("file://%1").arg(paths[0])); diff --git a/core/document.cpp b/core/document.cpp index 145d84c77..4010f17f5 100644 --- a/core/document.cpp +++ b/core/document.cpp @@ -55,6 +55,7 @@ #include #include #include +#include // local includes #include "action.h" @@ -1209,86 +1210,90 @@ void DocumentPrivate::saveDocumentInfo() const return; QFile infoFile( m_xmlFileName ); - if (infoFile.open( QIODevice::WriteOnly | QIODevice::Truncate) ) + qCDebug(OkularCoreDebug) << "About to save document info to" << m_xmlFileName; + if (!infoFile.open( QIODevice::WriteOnly | QIODevice::Truncate)) { - // 1. Create DOM - QDomDocument doc( QStringLiteral("documentInfo") ); - QDomProcessingInstruction xmlPi = doc.createProcessingInstruction( - QStringLiteral( "xml" ), QStringLiteral( "version=\"1.0\" encoding=\"utf-8\"" ) ); - doc.appendChild( xmlPi ); - QDomElement root = doc.createElement( QStringLiteral("documentInfo") ); - root.setAttribute( QStringLiteral("url"), m_url.toDisplayString(QUrl::PreferLocalFile) ); - doc.appendChild( root ); - - // 2.1. Save page attributes (bookmark state, annotations, ... ) to DOM - QDomElement pageList = doc.createElement( QStringLiteral("pageList") ); - root.appendChild( pageList ); - PageItems saveWhat = AllPageItems; - if ( m_annotationsNeedSaveAs ) - { - /* In this case, if the user makes a modification, he's requested to - * save to a new document. Therefore, if there are existing local - * annotations, we save them back unmodified in the original - * document's metadata, so that it appears that it was not changed */ - saveWhat |= OriginalAnnotationPageItems; - } - // .... save pages that hold data - QVector< Page * >::const_iterator pIt = m_pagesVector.constBegin(), pEnd = m_pagesVector.constEnd(); - for ( ; pIt != pEnd; ++pIt ) - (*pIt)->d->saveLocalContents( pageList, doc, saveWhat ); + qCWarning(OkularCoreDebug) << "Failed to open docdata file" << m_xmlFileName; + return; - // 2.2. Save document info (current viewport, history, ... ) to DOM - QDomElement generalInfo = doc.createElement( QStringLiteral("generalInfo") ); - root.appendChild( generalInfo ); - // create rotation node - if ( m_rotation != Rotation0 ) - { - QDomElement rotationNode = doc.createElement( QStringLiteral("rotation") ); - generalInfo.appendChild( rotationNode ); - rotationNode.appendChild( doc.createTextNode( QString::number( (int)m_rotation ) ) ); - } - // ... save history up to OKULAR_HISTORY_SAVEDSTEPS viewports - QLinkedList< DocumentViewport >::const_iterator backIterator = m_viewportIterator; - if ( backIterator != m_viewportHistory.constEnd() ) - { - // go back up to OKULAR_HISTORY_SAVEDSTEPS steps from the current viewportIterator - int backSteps = OKULAR_HISTORY_SAVEDSTEPS; - while ( backSteps-- && backIterator != m_viewportHistory.constBegin() ) - --backIterator; - - // create history root node - QDomElement historyNode = doc.createElement( QStringLiteral("history") ); - generalInfo.appendChild( historyNode ); - - // add old[backIterator] and present[viewportIterator] items - QLinkedList< DocumentViewport >::const_iterator endIt = m_viewportIterator; - ++endIt; - while ( backIterator != endIt ) - { - QString name = (backIterator == m_viewportIterator) ? "current" : "oldPage"; - QDomElement historyEntry = doc.createElement( name ); - historyEntry.setAttribute( QStringLiteral("viewport"), (*backIterator).toString() ); - historyNode.appendChild( historyEntry ); - ++backIterator; - } - } - // create views root node - QDomElement viewsNode = doc.createElement( QStringLiteral("views") ); - generalInfo.appendChild( viewsNode ); - Q_FOREACH ( View * view, m_views ) + } + // 1. Create DOM + QDomDocument doc( QStringLiteral("documentInfo") ); + QDomProcessingInstruction xmlPi = doc.createProcessingInstruction( + QStringLiteral( "xml" ), QStringLiteral( "version=\"1.0\" encoding=\"utf-8\"" ) ); + doc.appendChild( xmlPi ); + QDomElement root = doc.createElement( QStringLiteral("documentInfo") ); + root.setAttribute( QStringLiteral("url"), m_url.toDisplayString(QUrl::PreferLocalFile) ); + doc.appendChild( root ); + + // 2.1. Save page attributes (bookmark state, annotations, ... ) to DOM + QDomElement pageList = doc.createElement( QStringLiteral("pageList") ); + root.appendChild( pageList ); + PageItems saveWhat = AllPageItems; + if ( m_annotationsNeedSaveAs ) + { + /* In this case, if the user makes a modification, he's requested to + * save to a new document. Therefore, if there are existing local + * annotations, we save them back unmodified in the original + * document's metadata, so that it appears that it was not changed */ + saveWhat |= OriginalAnnotationPageItems; + } + // .... save pages that hold data + QVector< Page * >::const_iterator pIt = m_pagesVector.constBegin(), pEnd = m_pagesVector.constEnd(); + for ( ; pIt != pEnd; ++pIt ) + (*pIt)->d->saveLocalContents( pageList, doc, saveWhat ); + + // 2.2. Save document info (current viewport, history, ... ) to DOM + QDomElement generalInfo = doc.createElement( QStringLiteral("generalInfo") ); + root.appendChild( generalInfo ); + // create rotation node + if ( m_rotation != Rotation0 ) + { + QDomElement rotationNode = doc.createElement( QStringLiteral("rotation") ); + generalInfo.appendChild( rotationNode ); + rotationNode.appendChild( doc.createTextNode( QString::number( (int)m_rotation ) ) ); + } + // ... save history up to OKULAR_HISTORY_SAVEDSTEPS viewports + QLinkedList< DocumentViewport >::const_iterator backIterator = m_viewportIterator; + if ( backIterator != m_viewportHistory.constEnd() ) + { + // go back up to OKULAR_HISTORY_SAVEDSTEPS steps from the current viewportIterator + int backSteps = OKULAR_HISTORY_SAVEDSTEPS; + while ( backSteps-- && backIterator != m_viewportHistory.constBegin() ) + --backIterator; + + // create history root node + QDomElement historyNode = doc.createElement( QStringLiteral("history") ); + generalInfo.appendChild( historyNode ); + + // add old[backIterator] and present[viewportIterator] items + QLinkedList< DocumentViewport >::const_iterator endIt = m_viewportIterator; + ++endIt; + while ( backIterator != endIt ) { - QDomElement viewEntry = doc.createElement( QStringLiteral("view") ); - viewEntry.setAttribute( QStringLiteral("name"), view->name() ); - viewsNode.appendChild( viewEntry ); - saveViewsInfo( view, viewEntry ); + QString name = (backIterator == m_viewportIterator) ? "current" : "oldPage"; + QDomElement historyEntry = doc.createElement( name ); + historyEntry.setAttribute( QStringLiteral("viewport"), (*backIterator).toString() ); + historyNode.appendChild( historyEntry ); + ++backIterator; } - - // 3. Save DOM to XML file - QString xml = doc.toString(); - QTextStream os( &infoFile ); - os.setCodec( "UTF-8" ); - os << xml; } + // create views root node + QDomElement viewsNode = doc.createElement( QStringLiteral("views") ); + generalInfo.appendChild( viewsNode ); + Q_FOREACH ( View * view, m_views ) + { + QDomElement viewEntry = doc.createElement( QStringLiteral("view") ); + viewEntry.setAttribute( QStringLiteral("name"), view->name() ); + viewsNode.appendChild( viewEntry ); + saveViewsInfo( view, viewEntry ); + } + + // 3. Save DOM to XML file + QString xml = doc.toString(); + QTextStream os( &infoFile ); + os.setCodec( "UTF-8" ); + os << xml; infoFile.close(); } @@ -2213,18 +2218,32 @@ Document::~Document() QString DocumentPrivate::docDataFileName(const QUrl &url, qint64 document_size) { + QString fn = url.fileName(); fn = QString::number( document_size ) + '.' + fn + ".xml"; - QString newokular = "okular/docdata/" + fn; - QString newokularfile = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + newokular ; - if ( !QFile::exists( newokularfile ) ) - { - QString oldkpdf = "kpdf/" + fn; - QString oldkpdffile = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + oldkpdf ; - if ( QFile::exists( oldkpdffile ) ) + QString docdataDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + + QStringLiteral("/okular/docdata"); + // make sure that the okular/docdata/ directory exists (probably this used to be handled by KStandardDirs) + if (!QFileInfo::exists(docdataDir)) + { + qCDebug(OkularCoreDebug) << "creating docdata folder" << docdataDir; + QDir().mkpath(docdataDir); + } + QString newokularfile = docdataDir + QLatin1Char('/') + fn; + // we don't want to accidentally migrate old files when running unit tests + if (!QFile::exists( newokularfile ) && !QStandardPaths::isTestModeEnabled()) + { + // see if an KDE4 file still exists + static Kdelibs4Migration k4migration; + QString oldfile = k4migration.locateLocal("data", QStringLiteral("okular/docdata/") + fn); + if (oldfile.isEmpty()) + { + oldfile = k4migration.locateLocal("data", QStringLiteral("kpdf/") + fn); + } + if ( !oldfile.isEmpty() && QFile::exists( oldfile ) ) { // ### copy or move? - if ( !QFile::copy( oldkpdffile, newokularfile ) ) + if ( !QFile::copy( oldfile, newokularfile ) ) return QString(); } } diff --git a/shell/main.cpp b/shell/main.cpp index b426746af..f67eb8c8f 100644 --- a/shell/main.cpp +++ b/shell/main.cpp @@ -42,6 +42,8 @@ int main(int argc, char** argv) QCommandLineParser parser; KAboutData::setApplicationData(aboutData); + // The KDE4 version accepted flags such as -unique with a single dash -> preserve compatibility + parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); parser.addVersionOption(); parser.addHelpOption(); aboutData.setupCommandLine(&parser); diff --git a/shell/okular_main.cpp b/shell/okular_main.cpp index fdee69458..9bdc1feed 100644 --- a/shell/okular_main.cpp +++ b/shell/okular_main.cpp @@ -166,7 +166,7 @@ Status main(const QStringList &paths, const QString &serializedOptions) { // Page only makes sense if we are opening one file const QString page = ShellUtils::page(serializedOptions); - if ( shell->openDocument( ShellUtils::urlFromArg(paths[i], ShellUtils::qfileExistFunc(), page), serializedOptions) ) + if ( shell->openDocument( ShellUtils::urlFromArg(paths[i], ShellUtils::qfileExistFunc(), page).url(), serializedOptions) ) { ++i; } diff --git a/shell/shell.cpp b/shell/shell.cpp index e69ecbb5e..1c4c8e9c2 100644 --- a/shell/shell.cpp +++ b/shell/shell.cpp @@ -167,7 +167,7 @@ Shell::~Shell() // Open a new document if we have space for it // This can hang if called on a unique instance and openUrl pops a messageBox -bool Shell::openDocument( const QUrl& url, const QString &serializedOptions ) +bool Shell::openDocument( const QString& urlString, const QString &serializedOptions ) { if( m_tabs.size() <= 0 ) return false; @@ -182,7 +182,7 @@ bool Shell::openDocument( const QUrl& url, const QString &serializedOptions ) return false; } - openUrl( url, serializedOptions ); + openUrl( QUrl( urlString, QUrl::StrictMode) , serializedOptions ); return true; } diff --git a/shell/shell.h b/shell/shell.h index c16a0b266..d1bb51bee 100644 --- a/shell/shell.h +++ b/shell/shell.h @@ -69,7 +69,7 @@ public: public slots: Q_SCRIPTABLE Q_NOREPLY void tryRaise(); - Q_SCRIPTABLE bool openDocument(const QUrl &url, const QString &serializedOptions = QString() ); + Q_SCRIPTABLE bool openDocument(const QString &urlString, const QString &serializedOptions = QString() ); Q_SCRIPTABLE bool canOpenDocs( int numDocs, int desktop ); protected: