diff --git a/autotests/mainshelltest.cpp b/autotests/mainshelltest.cpp --- a/autotests/mainshelltest.cpp +++ b/autotests/mainshelltest.cpp @@ -19,6 +19,7 @@ #include "../shell/shell.h" #include "../shell/shellutils.h" #include "../core/document_p.h" +#include "../ui/findbar.h" #include "../ui/presentationwidget.h" #include "../part.h" #include "../settings.h" @@ -40,6 +41,9 @@ QWidget *presentationWidget(Okular::Part *part) const { return part->m_presentationWidget; } + FindBar *findWidget(Okular::Part *part) const { + return part->m_findBar; + } }; } @@ -175,39 +179,42 @@ QTest::addColumn("externalProcessExpectedPage"); QTest::addColumn("externalProcessExpectPresentation"); QTest::addColumn("externalProcessExpectPrintDialog"); + QTest::addColumn("externalProcessExpectFind"); const QStringList contentsEpub = QStringList(QStringLiteral(KDESRCDIR "data/contents.epub")); const QStringList file1 = QStringList(QStringLiteral(KDESRCDIR "data/file1.pdf")); QStringList file1AndToc; file1AndToc << QStringLiteral(KDESRCDIR "data/file1.pdf"); file1AndToc << QStringLiteral(KDESRCDIR "data/tocreload.pdf"); const QString tocReload = QStringLiteral(KDESRCDIR "data/tocreload.pdf"); - const QString optionsPage2 = ShellUtils::serializeOptions(false, false, false, false, false, QStringLiteral("2")); - const QString optionsPage2Presentation = ShellUtils::serializeOptions(true, false, false, false, false, QStringLiteral("2")); - const QString optionsPrint = ShellUtils::serializeOptions(false, true, false, false, false, QString()); - const QString optionsUnique = ShellUtils::serializeOptions(false, false, false, true, false, QString()); - - QTest::newRow("just show shell") << QStringList() << QString() << false << QString() << 0u << false << false << false << 0u << false << false; - QTest::newRow("open file") << file1 << QString() << false << QString() << 0u << false << false << false << 0u << false << false; - QTest::newRow("two files no tabs") << file1AndToc << QString() << false << QString() << 0u << false << false << false << 0u << false << false; - QTest::newRow("two files with tabs") << file1AndToc << QString() << true << QString() << 0u << false << false << false << 0u << false << false; - QTest::newRow("two files sequence no tabs") << file1 << QString() << false << tocReload << 0u << false << false << false << 0u << false << false; - QTest::newRow("two files sequence with tabs") << file1 << QString() << true << tocReload << 0u << false << false << false << 0u << false << false; - QTest::newRow("open file page number") << contentsEpub << optionsPage2 << false << QString() << 1u << false << false << false << 0u << false << false; - QTest::newRow("open file page number and presentation") << contentsEpub << optionsPage2Presentation << false << QString() << 1u << true << false << false << 0u << false << false; - QTest::newRow("open file print") << file1 << optionsPrint << false << QString() << 0u << false << true << false << 0u << false << false; - QTest::newRow("open two files unique") << file1 << optionsUnique << false << tocReload << 0u << false << false << true << 0u << false << false; - QTest::newRow("open two files unique tabs") << file1 << optionsUnique << true << tocReload << 0u << false << false << true << 0u << false << false; - QTest::newRow("page number attach tabs") << file1 << QString() << true << contentsEpub[0] << 0u << false << false << false << 2u << false << false; - QTest::newRow("presentation attach tabs") << file1 << QString() << true << contentsEpub[0] << 0u << false << false << false << 2u << true << false; - QTest::newRow("print attach tabs") << file1 << QString() << true << contentsEpub[0] << 0u << false << true << false << 2u << false << true; - QTest::newRow("page number attach unique") << file1 << optionsUnique << false << contentsEpub[0] << 0u << false << false << true << 3u << false << false; - QTest::newRow("presentation attach unique") << file1 << optionsUnique << false << contentsEpub[0] << 0u << false << false << true << 2u << true << false; - QTest::newRow("print attach unique") << file1 << optionsUnique << false << contentsEpub[0] << 0u << false << false << true << 2u << false << true; - QTest::newRow("page number attach unique tabs") << file1 << optionsUnique << true << contentsEpub[0] << 0u << false << false << true << 3u << false << false; - QTest::newRow("presentation attach unique tabs") << file1 << optionsUnique << true << contentsEpub[0] << 0u << false << false << true << 2u << true << false; - QTest::newRow("print attach unique tabs") << file1 << optionsUnique << true << contentsEpub[0] << 0u << false << false << true << 2u << false << true; + const QString optionsPage2 = ShellUtils::serializeOptions(false, false, false, false, false, QStringLiteral("2"), QString()); + const QString optionsPage2Presentation = ShellUtils::serializeOptions(true, false, false, false, false, QStringLiteral("2"), QString()); + const QString optionsPrint = ShellUtils::serializeOptions(false, true, false, false, false, QString(), QString()); + const QString optionsUnique = ShellUtils::serializeOptions(false, false, false, true, false, QString(), QString()); + const QString optionsFind = ShellUtils::serializeOptions(false, false, false, false ,false , QString(), QStringLiteral("si:next-testing parameters!")); + + QTest::newRow("just show shell") << QStringList() << QString() << false << QString() << 0u << false << false << false << 0u << false << false << QString(); + QTest::newRow("open file") << file1 << QString() << false << QString() << 0u << false << false << false << 0u << false << false << QString(); + QTest::newRow("two files no tabs") << file1AndToc << QString() << false << QString() << 0u << false << false << false << 0u << false << false << QString(); + QTest::newRow("two files with tabs") << file1AndToc << QString() << true << QString() << 0u << false << false << false << 0u << false << false << QString(); + QTest::newRow("two files sequence no tabs") << file1 << QString() << false << tocReload << 0u << false << false << false << 0u << false << false << QString(); + QTest::newRow("two files sequence with tabs") << file1 << QString() << true << tocReload << 0u << false << false << false << 0u << false << false << QString(); + QTest::newRow("open file page number") << contentsEpub << optionsPage2 << false << QString() << 1u << false << false << false << 0u << false << false << QString(); + QTest::newRow("open file page number and presentation") << contentsEpub << optionsPage2Presentation << false << QString() << 1u << true << false << false << 0u << false << false << QString(); + QTest::newRow("open file find") << file1 << optionsFind << false << QString() << 0u << false << false << false << 0u << false << false << QString("si:next-testing parameters!"); + QTest::newRow("open file print") << file1 << optionsPrint << false << QString() << 0u << false << true << false << 0u << false << false << QString(); + QTest::newRow("open two files unique") << file1 << optionsUnique << false << tocReload << 0u << false << false << true << 0u << false << false << QString(); + QTest::newRow("open two files unique tabs") << file1 << optionsUnique << true << tocReload << 0u << false << false << true << 0u << false << false << QString(); + QTest::newRow("page number attach tabs") << file1 << QString() << true << contentsEpub[0] << 0u << false << false << false << 2u << false << false << QString(); + QTest::newRow("presentation attach tabs") << file1 << QString() << true << contentsEpub[0] << 0u << false << false << false << 2u << true << false << QString(); + QTest::newRow("print attach tabs") << file1 << QString() << true << contentsEpub[0] << 0u << false << true << false << 2u << false << true << QString(); + QTest::newRow("page number attach unique") << file1 << optionsUnique << false << contentsEpub[0] << 0u << false << false << true << 3u << false << false << QString(); + QTest::newRow("presentation attach unique") << file1 << optionsUnique << false << contentsEpub[0] << 0u << false << false << true << 2u << true << false << QString(); + QTest::newRow("print attach unique") << file1 << optionsUnique << false << contentsEpub[0] << 0u << false << false << true << 2u << false << true << QString(); + QTest::newRow("page number attach unique tabs") << file1 << optionsUnique << true << contentsEpub[0] << 0u << false << false << true << 3u << false << false << QString(); + QTest::newRow("presentation attach unique tabs") << file1 << optionsUnique << true << contentsEpub[0] << 0u << false << false << true << 2u << true << false << QString(); + QTest::newRow("print attach unique tabs") << file1 << optionsUnique << true << contentsEpub[0] << 0u << false << false << true << 2u << false << true << QString(); } void MainShellTest::testShell() @@ -223,6 +230,8 @@ QFETCH(uint, externalProcessExpectedPage); QFETCH(bool, externalProcessExpectPresentation); QFETCH(bool, externalProcessExpectPrintDialog); + QFETCH(QString, externalProcessExpectFind); + QScopedPointer helper; @@ -246,6 +255,11 @@ QVERIFY(part); QCOMPARE(part->url().url(), QStringLiteral("file://%1").arg(paths[0])); QCOMPARE(partDocument(part)->currentPage(), expectedPage); + // Testing if the bar is shown or hidden as expected + QCOMPARE(findWidget(part)->isHidden(), externalProcessExpectFind.isEmpty()); + // Checking if the encryption/decryption worked + QCOMPARE(externalProcessExpectFind, ShellUtils::find(serializedOptions)); + } else if (paths.count() == 2) { @@ -405,9 +419,9 @@ const QStringList paths = QStringList(QStringLiteral(KDESRCDIR "data/contents.epub")); QString serializedOptions; if (mode == 1 || mode == 3) - serializedOptions = ShellUtils::serializeOptions(false, false, false, false, false, QString()); + serializedOptions = ShellUtils::serializeOptions(false, false, false, false, false, QString(), QString()); else - serializedOptions = ShellUtils::serializeOptions(false, false, false, true, false, QString()); + serializedOptions = ShellUtils::serializeOptions(false, false, false, true, false, QString(), QString()); Okular::Settings::self()->setShellOpenFileInTabs(mode == 3); @@ -458,10 +472,11 @@ { QTest::addColumn("serializedOptions"); - QTest::newRow("startInPresentation") << ShellUtils::serializeOptions(true, false, false, false, false, QString()); - QTest::newRow("showPrintDialog") << ShellUtils::serializeOptions(false, true, false, false, false, QString()); - QTest::newRow("unique") << ShellUtils::serializeOptions(false, false, false, true, false, QString()); - QTest::newRow("pageNumger") << ShellUtils::serializeOptions(false, false, false, false, false, QStringLiteral("3")); + QTest::newRow("startInPresentation") << ShellUtils::serializeOptions(true, false, false, false, false, QString(), QString()); + QTest::newRow("showPrintDialog") << ShellUtils::serializeOptions(false, true, false, false, false, QString(), QString()); + QTest::newRow("unique") << ShellUtils::serializeOptions(false, false, false, true, false, QString(), QString()); + QTest::newRow("pageNumber") << ShellUtils::serializeOptions(false, false, false, false, false, QStringLiteral("3"), QString()); + QTest::newRow("find") << ShellUtils::serializeOptions(false, false, false, false, false, QString(), QStringLiteral("silly")); } void MainShellTest::test2FilesError() @@ -488,7 +503,7 @@ QStringList twoDocPaths( oneDocPaths ); twoDocPaths << QStringLiteral(KDESRCDIR "data/formSamples.pdf"); - const QString options = ShellUtils::serializeOptions(false, false, false, false, false, QString()); + const QString options = ShellUtils::serializeOptions(false, false, false, false, false, QString(), QString()); QTest::newRow("1 doc, 1 window, tabs") << oneDocPaths << options << true << true; QTest::newRow("2 docs, 1 window, tabs") << twoDocPaths << options << true << true; diff --git a/core/document.cpp b/core/document.cpp --- a/core/document.cpp +++ b/core/document.cpp @@ -3773,7 +3773,7 @@ SearchType type, bool moveViewport, const QColor & color ) { d->m_searchCancelled = false; - + // safety checks: don't perform searches on empty or unsearchable docs if ( !d->m_generator || !d->m_generator->hasFeature( Generator::TextExtraction ) || d->m_pagesVector.isEmpty() ) { diff --git a/generators/poppler/generator_pdf.cpp b/generators/poppler/generator_pdf.cpp --- a/generators/poppler/generator_pdf.cpp +++ b/generators/poppler/generator_pdf.cpp @@ -2001,7 +2001,7 @@ { Q_UNUSED(errorText); Poppler::PDFConverter *pdfConv = pdfdoc->pdfConverter(); - + pdfConv->setOutputFileName( fileName ); if ( options & SaveChanges ) pdfConv->setPDFOptions( pdfConv->pdfOptions() | Poppler::PDFConverter::WithChanges ); diff --git a/part.h b/part.h --- a/part.h +++ b/part.h @@ -168,6 +168,7 @@ Q_SCRIPTABLE Q_NOREPLY void reload(); Q_SCRIPTABLE Q_NOREPLY void enableStartWithPrint(); Q_SCRIPTABLE Q_NOREPLY void enableExitAfterPrint(); + Q_SCRIPTABLE Q_NOREPLY void enableStartWithFind(const QString &text); Q_SIGNALS: void enablePrintAction(bool enable); @@ -407,6 +408,9 @@ QString m_registerDbusName; + // String to search in document startup + QString m_textToFindOnOpen; + private Q_SLOTS: void slotAnnotationPreferences(); void slotHandleActivatedSourceReference(const QString& absFileName, int line, int col, bool *handled); diff --git a/part.cpp b/part.cpp --- a/part.cpp +++ b/part.cpp @@ -1597,6 +1597,14 @@ if ( keepFileOpen() ) m_keeper->open( fileNameToOpen ); #endif + + // Tries to find the text passed from terminal after the file is open + if(!m_textToFindOnOpen.isEmpty()) + { + m_findBar->startSearch(m_textToFindOnOpen); + m_textToFindOnOpen = QString(); + } + } if ( m_exportAsText ) m_exportAsText->setEnabled( ok && m_document->canExportToText() ); if ( m_exportAs ) m_exportAs->setEnabled( ok ); @@ -1720,7 +1728,7 @@ resetStartArguments(); KMessageBox::error( widget(), i18n("Could not open %1", url.toDisplayString() ) ); } - + return openOk; } @@ -3612,6 +3620,11 @@ ReadWritePart::setReadWrite( readwrite ); } +void Part::enableStartWithFind(const QString &text) +{ + m_textToFindOnOpen = QString(text); +} + } // namespace Okular #include "part.moc" diff --git a/shell/main.cpp b/shell/main.cpp --- a/shell/main.cpp +++ b/shell/main.cpp @@ -53,6 +53,7 @@ parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("print-and-exit"), i18n("Start with print dialog and exit after printing"))); parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("unique"), i18n("\"Unique instance\" control"))); parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("noraise"), i18n("Not raise window"))); + parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("find"), i18n("Find a string on the text"), QStringLiteral("string"))); parser.addPositionalArgument(QStringLiteral("urls"), i18n("Documents to open. Specify '-' to read from stdin.")); parser.process(app); @@ -81,7 +82,7 @@ break; } } - + return app.exec(); } diff --git a/shell/okular_main.cpp b/shell/okular_main.cpp --- a/shell/okular_main.cpp +++ b/shell/okular_main.cpp @@ -149,6 +149,12 @@ return Error; } + if(!ShellUtils::find(serializedOptions).isEmpty() && paths.count() > 1) + { + QTextStream stream(stderr); + stream << i18n( "Error: Can't open more than one document with the --find switch" ) << endl; + return Error; + } // try to attach to existing session, unique or not if (attachUniqueInstance(paths, serializedOptions) || attachExistingInstance(paths, serializedOptions)) { @@ -181,7 +187,7 @@ shell->show(); } } - + return Success; } diff --git a/shell/shell.cpp b/shell/shell.cpp --- a/shell/shell.cpp +++ b/shell/shell.cpp @@ -681,12 +681,15 @@ void Shell::applyOptionsToPart( QObject* part, const QString &serializedOptions ) { KDocumentViewer* const doc = qobject_cast(part); + const QString find = ShellUtils::find(serializedOptions); if ( ShellUtils::startInPresentation(serializedOptions) ) doc->startPresentation(); if ( ShellUtils::showPrintDialog(serializedOptions) ) QMetaObject::invokeMethod( part, "enableStartWithPrint" ); if ( ShellUtils::showPrintDialogAndExit(serializedOptions) ) QMetaObject::invokeMethod( part, "enableExitAfterPrint" ); + if(!find.isEmpty()) + QMetaObject::invokeMethod( part, "enableStartWithFind", Q_ARG( const QString &, find )); } void Shell::connectPart( QObject* part ) diff --git a/shell/shellutils.h b/shell/shellutils.h --- a/shell/shellutils.h +++ b/shell/shellutils.h @@ -24,14 +24,15 @@ FileExistFunc qfileExistFunc(); QUrl urlFromArg(const QString& _arg, FileExistFunc exist_func, const QString& pageArg = QString() ); QString serializeOptions(const QCommandLineParser &args); -QString serializeOptions(bool startInPresentation, bool showPrintDialog, bool showPrintDialogAndExit, bool unique, bool noRaise, const QString &page); +QString serializeOptions(bool startInPresentation, bool showPrintDialog, bool showPrintDialogAndExit, bool unique, bool noRaise, const QString &page, const QString &find); bool unserializeOptions(const QString &serializedOptions, bool *presentation, bool *print, bool *print_and_exit, bool *unique, bool *noraise, QString *page); bool unique(const QString &serializedOptions); bool noRaise(const QString &serializedOptions); bool startInPresentation(const QString &serializedOptions); bool showPrintDialog(const QString &serializedOptions); bool showPrintDialogAndExit(const QString &serializedOptions); QString page(const QString &serializedOptions); +QString find(const QString &serializedOptions); } diff --git a/shell/shellutils.cpp b/shell/shellutils.cpp --- a/shell/shellutils.cpp +++ b/shell/shellutils.cpp @@ -58,7 +58,7 @@ if ( !pageArg.isEmpty() ) { url.setFragment( pageArg ); - } + } return url; } @@ -70,26 +70,29 @@ const bool unique = args.isSet(QStringLiteral("unique")) && args.positionalArguments().count() <= 1; const bool noRaise = args.isSet(QStringLiteral("noraise")); const QString page = args.value(QStringLiteral("page")); + const QString find = args.value(QStringLiteral("find")); - return serializeOptions(startInPresentation, showPrintDialog, showPrintDialogAndExit, unique, noRaise, page); + return serializeOptions(startInPresentation, showPrintDialog, showPrintDialogAndExit, unique, noRaise, page, find); } -QString serializeOptions(bool startInPresentation, bool showPrintDialog, bool showPrintDialogAndExit, bool unique, bool noRaise, const QString &page) +QString serializeOptions(bool startInPresentation, bool showPrintDialog, bool showPrintDialogAndExit, bool unique, bool noRaise, const QString &page, const QString &find) { - return QStringLiteral("%1:%2:%3:%4:%5:%6").arg(startInPresentation).arg(showPrintDialog).arg(showPrintDialogAndExit).arg(unique).arg(noRaise).arg(page); + return QStringLiteral("%1:%2:%3:%4:%5:%6:%7").arg(startInPresentation).arg(showPrintDialog).arg(showPrintDialogAndExit).arg(unique).arg(noRaise).arg(page).arg(QString(find.toLatin1().toBase64())); } -bool unserializeOptions(const QString &serializedOptions, bool *presentation, bool *print, bool *print_and_exit, bool *unique, bool *noraise, QString *page) +bool unserializeOptions(const QString &serializedOptions, bool *presentation, bool *print, bool *print_and_exit, bool *unique, bool *noraise, QString *page, QString *find) { const QStringList args = serializedOptions.split(QStringLiteral(":")); - if (args.count() == 6) + + if (args.count() == 7) { *presentation = args[0] == QLatin1String("1"); *print = args[1] == QLatin1String("1"); *print_and_exit = args[2] == QLatin1String("1"); *unique = args[3] == QLatin1String("1"); *noraise = args[4] == QLatin1String("1"); *page = args[5]; + *find = args[6]; return true; } return false; @@ -99,43 +102,51 @@ { bool result, dummy; QString dummyString; - return unserializeOptions(serializedOptions, &result, &dummy, &dummy, &dummy, &dummy, &dummyString) && result; + return unserializeOptions(serializedOptions, &result, &dummy, &dummy, &dummy, &dummy, &dummyString, &dummyString) && result; } bool showPrintDialog(const QString &serializedOptions) { bool result, dummy; QString dummyString; - return unserializeOptions(serializedOptions, &dummy, &result, &dummy, &dummy, &dummy, &dummyString) && result; + return unserializeOptions(serializedOptions, &dummy, &result, &dummy, &dummy, &dummy, &dummyString, &dummyString) && result; } bool showPrintDialogAndExit(const QString &serializedOptions) { bool result, dummy; QString dummyString; - return unserializeOptions(serializedOptions, &dummy, &dummy, &result, &dummy, &dummy, &dummyString) && result; + return unserializeOptions(serializedOptions, &dummy, &dummy, &result, &dummy, &dummy, &dummyString, &dummyString) && result; } bool unique(const QString &serializedOptions) { bool result, dummy; QString dummyString; - return unserializeOptions(serializedOptions, &dummy, &dummy, &dummy, &result, &dummy, &dummyString) && result; + return unserializeOptions(serializedOptions, &dummy, &dummy, &dummy, &result, &dummy, &dummyString, &dummyString) && result; } bool noRaise(const QString &serializedOptions) { bool result, dummy; QString dummyString; - return unserializeOptions(serializedOptions, &dummy, &dummy, &dummy, &dummy, &result, &dummyString) && result; + return unserializeOptions(serializedOptions, &dummy, &dummy, &dummy, &dummy, &result, &dummyString, &dummyString) && result; } QString page(const QString &serializedOptions) { - QString result; + QString result, dummyString; bool dummy; - unserializeOptions(serializedOptions, &dummy, &dummy, &dummy, &dummy, &dummy, &result); + unserializeOptions(serializedOptions, &dummy, &dummy, &dummy, &dummy, &dummy, &result, &dummyString); return result; } +QString find(const QString &serializedOptions) +{ + QString result, dummyString; + bool dummy; + unserializeOptions(serializedOptions, &dummy, &dummy, &dummy, &dummy, &dummy, &dummyString, &result); + return QString(QByteArray::fromBase64(result.toLatin1())); +} + } diff --git a/ui/findbar.h b/ui/findbar.h --- a/ui/findbar.h +++ b/ui/findbar.h @@ -33,6 +33,7 @@ void focusAndSetCursor(); bool maybeHide(); + void startSearch(const QString & findText); Q_SIGNALS: void forwardKeyPressEvent( QKeyEvent* ); diff --git a/ui/findbar.cpp b/ui/findbar.cpp --- a/ui/findbar.cpp +++ b/ui/findbar.cpp @@ -197,4 +197,10 @@ close(); } +void FindBar::startSearch(const QString & findText) +{ + m_search->lineEdit()->setText( findText ); + show(); +} + #include "moc_findbar.cpp"