diff --git a/Mainpage.dox b/Mainpage.dox index 0481d59b0..4ca9dbaab 100644 --- a/Mainpage.dox +++ b/Mainpage.dox @@ -859,6 +859,3 @@ the pages vector with them. Afterwards we fill our Okular::DocumentInfo object with data. Since extracting the HTML meta data would need a lot of code we work with static data here. [to be continued] */ - -// DOXYGEN_EXCLUDE = conf generators shell ui -// DOXYGEN_FILE_PATTERNS = core/*.h *.dox diff --git a/autotests/generatorstest.cpp b/autotests/generatorstest.cpp index 9d63c91f0..e8e196211 100644 --- a/autotests/generatorstest.cpp +++ b/autotests/generatorstest.cpp @@ -46,6 +46,7 @@ void GeneratorsTest::testLoadsCorrectly() foreach (const QString& lib, generatorLibs) { KPluginLoader loader(lib); QVERIFY2(!loader.fileName().isEmpty(), qPrintable(lib)); + qDebug() << loader.fileName(); auto factory = loader.factory(); if (!factory) { qWarning() << "Could not get KPluginFactory for" << lib; diff --git a/autotests/parttest.cpp b/autotests/parttest.cpp index 46d359d31..96085d75d 100644 --- a/autotests/parttest.cpp +++ b/autotests/parttest.cpp @@ -130,7 +130,20 @@ void PartTest::testFowardPDF() QProcess process; process.setWorkingDirectory(workDir.path()); process.start(QStringLiteral("pdflatex"), QStringList() << QStringLiteral("-synctex=1") << QStringLiteral("-interaction=nonstopmode") << texDestination); + bool started = process.waitForStarted(); + if (!started) { + qDebug() << "start error:" << process.error(); + qDebug() << "start stdout:" << process.readAllStandardOutput(); + qDebug() << "start stderr:" << process.readAllStandardError(); + } + QVERIFY(started); + process.waitForFinished(); + if (process.exitStatus() != QProcess::NormalExit || process.exitCode() != 0) { + qDebug() << "exit error:" << process.error() << "status" << process.exitStatus() << "code" << process.exitCode(); + qDebug() << "exit stdout:" << process.readAllStandardOutput(); + qDebug() << "exit stderr:" << process.readAllStandardError(); + } const QString pdfResult = workDir.path() + QStringLiteral("/synctextest.pdf"); diff --git a/cmake/modules/FindPoppler.cmake b/cmake/modules/FindPoppler.cmake new file mode 100644 index 000000000..11af41eef --- /dev/null +++ b/cmake/modules/FindPoppler.cmake @@ -0,0 +1,181 @@ +# - Try to find the poppler PDF library +# Once done this will define +# +# POPPLER_FOUND - system has poppler +# POPPLER_INCLUDE_DIR - the poppler include directory +# POPPLER_LIBRARY - Link this to use poppler +# + +# Copyright (c) 2006-2010, Pino Toscano, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +if(POPPLER_INCLUDE_DIR AND POPPLER_LIBRARY) + + # in cache already + set(POPPLER_FOUND TRUE) + +else(POPPLER_INCLUDE_DIR AND POPPLER_LIBRARY) + +set(_poppler_version_bad FALSE) + +if(NOT WIN32) + # use pkg-config to get the directories and then use these values + # in the FIND_PATH() and FIND_LIBRARY() calls + include(FindPkgConfig) + pkg_check_modules(_pc_poppler poppler-qt4) + if(_pc_poppler_FOUND) + if(NOT "${_pc_poppler_VERSION}" VERSION_GREATER 0.5.3) + set(_poppler_version_bad TRUE) + endif(NOT "${_pc_poppler_VERSION}" VERSION_GREATER 0.5.3) + endif(_pc_poppler_FOUND) +endif(NOT WIN32) + +if(NOT _poppler_version_bad) + set(POPPLER_FOUND FALSE) + + find_library(POPPLER_LIBRARY poppler-qt4 + HINTS ${_pc_poppler_LIBRARY_DIRS} + ) + + find_path(POPPLER_INCLUDE_DIR poppler-qt4.h + HINTS ${_pc_poppler_INCLUDE_DIRS} + PATH_SUFFIXES poppler/qt4 + ) + find_path(POPPLER_INCLUDE_DIR_core qt4/poppler-qt4.h + HINTS ${_pc_poppler_INCLUDE_DIRS} + PATH_SUFFIXES poppler + ) + + if(POPPLER_LIBRARY AND POPPLER_INCLUDE_DIR AND POPPLER_INCLUDE_DIR_core) + list(APPEND POPPLER_INCLUDE_DIR "${POPPLER_INCLUDE_DIR_core}") + set(POPPLER_FOUND TRUE) + endif(POPPLER_LIBRARY AND POPPLER_INCLUDE_DIR AND POPPLER_INCLUDE_DIR_core) +endif(NOT _poppler_version_bad) + +if (POPPLER_FOUND) + include(CheckCXXSourceCompiles) + + # check whether we're using poppler 0.6 + set(CMAKE_REQUIRED_INCLUDES ${POPPLER_INCLUDE_DIR} ${QT_INCLUDE_DIR}) + set(CMAKE_REQUIRED_LIBRARIES ${POPPLER_LIBRARY} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTXML_LIBRARY}) + +check_cxx_source_compiles(" +#include +int main() +{ + Poppler::Document::RenderHint hint = Poppler::Document::TextHinting; + return 0; +} +" HAVE_POPPLER_0_12_1) + +check_cxx_source_compiles(" +#include + +void debugFunction(const QString &message, const QVariant &closure) +{ +} + +int main() +{ + Poppler::setDebugErrorFunction(debugFunction, QVariant()); + return 0; +} +" HAVE_POPPLER_0_16) + +check_cxx_source_compiles(" +#include +#include + +int main() +{ + Poppler::ScreenAnnotation *annot = 0; + Poppler::LinkRendition *link = 0; + const Poppler::LinkMovie::Operation operation = Poppler::LinkMovie::Play; + return 0; +} +" HAVE_POPPLER_0_20) + +check_cxx_source_compiles(" +#include +#include +#include + +int main() +{ + Poppler::MovieObject *movie = 0; + Poppler::Document *doc = 0; + movie->showPosterImage(); + + const Poppler::Annotation::AdditionalActionType type = Poppler::Annotation::PageOpeningAction; + const Poppler::LinkRendition::RenditionAction action = Poppler::LinkRendition::NoRendition; + const Poppler::Document::FormType formType = doc->formType(); + + return 0; +} +" HAVE_POPPLER_0_22) + +check_cxx_source_compiles(" +#include +int main() +{ + Poppler::Document::RenderHint hint = Poppler::Document::ThinLineSolid; + return 0; +} +" HAVE_POPPLER_0_24) + +check_cxx_source_compiles(" +#include +int main() +{ + Poppler::Page *p = 0; + p->annotations( QSet() << Poppler::Annotation::ASound ); + return 0; +} +" HAVE_POPPLER_0_28) + +check_cxx_source_compiles(" +#include +int main() +{ + Poppler::PageTransition *p = 0; + return p->durationReal(); +} +" HAVE_POPPLER_0_37) + + set(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_LIBRARIES) + if (HAVE_POPPLER_0_37) + set(popplerVersionMessage "0.37") + elseif (HAVE_POPPLER_0_28) + set(popplerVersionMessage "0.28") + elseif (HAVE_POPPLER_0_24) + set(popplerVersionMessage "0.24") + elseif (HAVE_POPPLER_0_22) + set(popplerVersionMessage "0.22") + elseif (HAVE_POPPLER_0_20) + set(popplerVersionMessage "0.20") + elseif (HAVE_POPPLER_0_16) + set(popplerVersionMessage "0.16") + elseif (HAVE_POPPLER_0_12_1) + set(popplerVersionMessage "0.12.1") + else (HAVE_POPPLER_0_28) + set(popplerVersionMessage "0.5.4") + endif () + if (NOT Poppler_FIND_QUIETLY) + message(STATUS "Found Poppler-Qt4: ${POPPLER_LIBRARY}, (>= ${popplerVersionMessage})") + endif (NOT Poppler_FIND_QUIETLY) +else (POPPLER_FOUND) + if (Poppler_FIND_REQUIRED) + message(FATAL_ERROR "Could NOT find Poppler-Qt4") + endif (Poppler_FIND_REQUIRED) + message(STATUS "Could not find OPTIONAL package Poppler-Qt4") +endif (POPPLER_FOUND) + +# ensure that they are cached +set(POPPLER_INCLUDE_DIR ${POPPLER_INCLUDE_DIR} CACHE INTERNAL "The Poppler-Qt4 include path") +set(POPPLER_LIBRARY ${POPPLER_LIBRARY} CACHE INTERNAL "The Poppler-Qt4 library") +set(HAVE_POPPLER_0_12_1 ${HAVE_POPPLER_0_12_1} CACHE INTERNAL "Whether the version of Poppler-Qt4 is >= 0.12.1") + +endif(POPPLER_INCLUDE_DIR AND POPPLER_LIBRARY) diff --git a/conf/dlggeneral.cpp b/conf/dlggeneral.cpp index 994552262..964a655bc 100644 --- a/conf/dlggeneral.cpp +++ b/conf/dlggeneral.cpp @@ -26,6 +26,7 @@ DlgGeneral::DlgGeneral( QWidget * parent, Okular::EmbedMode embedMode ) m_dlg->kcfg_SyncThumbnailsViewport->setVisible( false ); m_dlg->kcfg_DisplayDocumentTitle->setVisible( false ); m_dlg->kcfg_WatchFile->setVisible( false ); + m_dlg->kcfg_rtlReadingDirection->setVisible(false); } m_dlg->kcfg_ShellOpenFileInTabs->setVisible( embedMode == Okular::NativeShellMode ); } diff --git a/conf/dlggeneralbase.ui b/conf/dlggeneralbase.ui index c180533ab..323d74c81 100644 --- a/conf/dlggeneralbase.ui +++ b/conf/dlggeneralbase.ui @@ -11,7 +11,16 @@ - + + 0 + + + 0 + + + 0 + + 0 @@ -23,7 +32,16 @@ 6 - + + 9 + + + 9 + + + 9 + + 9 @@ -31,7 +49,16 @@ 6 - + + 0 + + + 0 + + + 0 + + 0 @@ -130,7 +157,16 @@ 6 - + + 0 + + + 0 + + + 0 + + 0 @@ -173,7 +209,16 @@ 6 - + + 9 + + + 9 + + + 9 + + 9 @@ -181,7 +226,16 @@ 6 - + + 0 + + + 0 + + + 0 + + 0 @@ -219,16 +273,22 @@ 6 - + + 0 + + + 0 + + + 0 + + 0 - - - - 0 - 0 - + + + Right to left reading direction diff --git a/conf/okular.kcfg b/conf/okular.kcfg index d90fe23ab..e06dd91ba 100644 --- a/conf/okular.kcfg +++ b/conf/okular.kcfg @@ -134,6 +134,9 @@ true + + false + Name diff --git a/core/area.h b/core/area.h index ccd9fbee7..56a69b248 100644 --- a/core/area.h +++ b/core/area.h @@ -684,9 +684,6 @@ bool RegularArea::intersects( const NormalizedShape& rec template bool RegularArea::intersects( const RegularArea *area ) const { - if ( !this ) - return false; - if ( this->isEmpty() ) return false; @@ -707,9 +704,6 @@ bool RegularArea::intersects( const RegularArea void RegularArea::appendArea( const RegularArea *area ) { - if ( !this ) - return; - typename QList::const_iterator areaIt = area->begin(), areaItEnd = area->end(); for ( ; areaIt != areaItEnd; ++areaIt ) this->append( *areaIt ); @@ -805,9 +799,6 @@ bool RegularArea::contains( double x, double y ) const template bool RegularArea::contains( const NormalizedShape& shape ) const { - if ( !this ) - return false; - if ( this->isEmpty() ) return false; diff --git a/core/document.cpp b/core/document.cpp index 848aadd10..8bc037e85 100644 --- a/core/document.cpp +++ b/core/document.cpp @@ -817,6 +817,7 @@ bool DocumentPrivate::openRelativeFile( const QString & fileName ) Generator * DocumentPrivate::loadGeneratorLibrary( const KPluginMetaData &service ) { KPluginLoader loader( service.fileName() ); + qDebug() << service.fileName(); KPluginFactory *factory = loader.factory(); if ( !factory ) { diff --git a/core/version.h b/core/version.h new file mode 100644 index 000000000..477e1a65f --- /dev/null +++ b/core/version.h @@ -0,0 +1,24 @@ +/*************************************************************************** + * Copyright (C) 2008 by Pino Toscano * + * * + * 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_VERSION_H_ +#define _OKULAR_VERSION_H_ + +#define OKULAR_VERSION_STRING "0.26.70" +#define OKULAR_VERSION_MAJOR 0 +#define OKULAR_VERSION_MINOR 26 +#define OKULAR_VERSION_RELEASE 70 +#define OKULAR_MAKE_VERSION( a,b,c ) (((a) << 16) | ((b) << 8) | (c)) + +#define OKULAR_VERSION \ + OKULAR_MAKE_VERSION(OKULAR_VERSION_MAJOR,OKULAR_VERSION_MINOR,OKULAR_VERSION_RELEASE) + +#define OKULAR_IS_VERSION(a,b,c) ( OKULAR_VERSION >= OKULAR_MAKE_VERSION(a,b,c) ) + +#endif diff --git a/doc/configure.png b/doc/configure.png index 8e78819d1..96ce2ee5a 100644 Binary files a/doc/configure.png and b/doc/configure.png differ diff --git a/doc/index.docbook b/doc/index.docbook index 44b198b8f..81eca456b 100644 --- a/doc/index.docbook +++ b/doc/index.docbook @@ -37,8 +37,8 @@ Context menu actions like Rename Bookmarks etc.) &FDLNotice; - 2015-09-17 - 0.24 (Applications 15.12) + 2016-07-26 + 0.26 (Applications 16.08) &okular; is a &kde; universal document viewer based on &kpdf; code. @@ -2138,6 +2138,14 @@ Context menu actions like Rename Bookmarks etc.) use the backend with the highest priority. + + Right to left reading direction + + + Whether to use right to left reading direction by default for the opened files. Can be useful for some writing systems. + + + Overview columns @@ -2356,6 +2364,16 @@ Context menu actions like Rename Bookmarks etc.) + + Using Custom Stamps + + + Create the icon you want to use for your own stamp and save it in any graphics format supported by &okular; + Click the Add button, select type Stamp and enter a name for your stamp. + Enter the full path to your custom icon into the dropdown box in the Stamp Symbol group + + + diff --git a/generators/chm/okularApplication_chm.desktop b/generators/chm/okularApplication_chm.desktop index 01ff62a9b..70f22ec6c 100755 --- a/generators/chm/okularApplication_chm.desktop +++ b/generators/chm/okularApplication_chm.desktop @@ -137,6 +137,7 @@ Comment[et]=Universaalne dokumendinäitaja Comment[fi]=Yleinen asiakirjakatselin Comment[fr]=Afficheur de document universel Comment[gl]=Visor de documentos universal +Comment[ia]=Visor de documento universal Comment[is]=Fjölhæfur skjalaskoðari Comment[it]=Visore di documenti universale Comment[ko]=만능 문서 뷰어 diff --git a/generators/comicbook/document.cpp b/generators/comicbook/document.cpp index 54c4c3c74..34c4cb5a9 100644 --- a/generators/comicbook/document.cpp +++ b/generators/comicbook/document.cpp @@ -78,7 +78,7 @@ bool Document::open( const QString &fileName ) if ( !processArchive() ) { return false; } - } else if ( mime.inherits( QStringLiteral("application/x-cbr") ) || mime.inherits( QStringLiteral("application/x-rar") ) ) { + } else if ( mime.inherits( QStringLiteral("application/x-cbr") ) || mime.inherits( QStringLiteral("application/x-rar") ) || mime.inherits( QStringLiteral("application/vnd.rar") ) ) { if ( !Unrar::isAvailable() ) { mLastErrorString = i18n( "Cannot open document, unrar was not found." ); return false; diff --git a/generators/comicbook/okularApplication_comicbook.desktop b/generators/comicbook/okularApplication_comicbook.desktop index 7c3d5843b..bcd87e5b5 100755 --- a/generators/comicbook/okularApplication_comicbook.desktop +++ b/generators/comicbook/okularApplication_comicbook.desktop @@ -137,6 +137,7 @@ Comment[et]=Universaalne dokumendinäitaja Comment[fi]=Yleinen asiakirjakatselin Comment[fr]=Afficheur de document universel Comment[gl]=Visor de documentos universal +Comment[ia]=Visor de documento universal Comment[is]=Fjölhæfur skjalaskoðari Comment[it]=Visore di documenti universale Comment[ko]=만능 문서 뷰어 diff --git a/generators/djvu/okularApplication_djvu.desktop b/generators/djvu/okularApplication_djvu.desktop index 07780d157..138a09cec 100755 --- a/generators/djvu/okularApplication_djvu.desktop +++ b/generators/djvu/okularApplication_djvu.desktop @@ -137,6 +137,7 @@ Comment[et]=Universaalne dokumendinäitaja Comment[fi]=Yleinen asiakirjakatselin Comment[fr]=Afficheur de document universel Comment[gl]=Visor de documentos universal +Comment[ia]=Visor de documento universal Comment[is]=Fjölhæfur skjalaskoðari Comment[it]=Visore di documenti universale Comment[ko]=만능 문서 뷰어 diff --git a/generators/dvi/okularApplication_dvi.desktop b/generators/dvi/okularApplication_dvi.desktop index ebc9d2da1..5ac6c2bd2 100755 --- a/generators/dvi/okularApplication_dvi.desktop +++ b/generators/dvi/okularApplication_dvi.desktop @@ -137,6 +137,7 @@ Comment[et]=Universaalne dokumendinäitaja Comment[fi]=Yleinen asiakirjakatselin Comment[fr]=Afficheur de document universel Comment[gl]=Visor de documentos universal +Comment[ia]=Visor de documento universal Comment[is]=Fjölhæfur skjalaskoðari Comment[it]=Visore di documenti universale Comment[ko]=만능 문서 뷰어 diff --git a/generators/epub/okularApplication_epub.desktop b/generators/epub/okularApplication_epub.desktop index 41e393774..6183a8a3e 100755 --- a/generators/epub/okularApplication_epub.desktop +++ b/generators/epub/okularApplication_epub.desktop @@ -137,6 +137,7 @@ Comment[et]=Universaalne dokumendinäitaja Comment[fi]=Yleinen asiakirjakatselin Comment[fr]=Afficheur de document universel Comment[gl]=Visor de documentos universal +Comment[ia]=Visor de documento universal Comment[is]=Fjölhæfur skjalaskoðari Comment[it]=Visore di documenti universale Comment[ko]=만능 문서 뷰어 diff --git a/generators/fax/okularApplication_fax.desktop b/generators/fax/okularApplication_fax.desktop index e20b3d383..253c837ba 100755 --- a/generators/fax/okularApplication_fax.desktop +++ b/generators/fax/okularApplication_fax.desktop @@ -137,6 +137,7 @@ Comment[et]=Universaalne dokumendinäitaja Comment[fi]=Yleinen asiakirjakatselin Comment[fr]=Afficheur de document universel Comment[gl]=Visor de documentos universal +Comment[ia]=Visor de documento universal Comment[is]=Fjölhæfur skjalaskoðari Comment[it]=Visore di documenti universale Comment[ko]=만능 문서 뷰어 diff --git a/generators/fictionbook/okularApplication_fb.desktop b/generators/fictionbook/okularApplication_fb.desktop index 1727ea97e..e89c85319 100755 --- a/generators/fictionbook/okularApplication_fb.desktop +++ b/generators/fictionbook/okularApplication_fb.desktop @@ -137,6 +137,7 @@ Comment[et]=Universaalne dokumendinäitaja Comment[fi]=Yleinen asiakirjakatselin Comment[fr]=Afficheur de document universel Comment[gl]=Visor de documentos universal +Comment[ia]=Visor de documento universal Comment[is]=Fjölhæfur skjalaskoðari Comment[it]=Visore di documenti universale Comment[ko]=만능 문서 뷰어 diff --git a/generators/kimgio/okularApplication_kimgio.desktop b/generators/kimgio/okularApplication_kimgio.desktop index 47765c527..6b6e3b0d5 100755 --- a/generators/kimgio/okularApplication_kimgio.desktop +++ b/generators/kimgio/okularApplication_kimgio.desktop @@ -137,6 +137,7 @@ Comment[et]=Universaalne dokumendinäitaja Comment[fi]=Yleinen asiakirjakatselin Comment[fr]=Afficheur de document universel Comment[gl]=Visor de documentos universal +Comment[ia]=Visor de documento universal Comment[is]=Fjölhæfur skjalaskoðari Comment[it]=Visore di documenti universale Comment[ko]=만능 문서 뷰어 diff --git a/generators/mobipocket/okularApplication_mobi.desktop b/generators/mobipocket/okularApplication_mobi.desktop index eafc9437a..d1b223eff 100755 --- a/generators/mobipocket/okularApplication_mobi.desktop +++ b/generators/mobipocket/okularApplication_mobi.desktop @@ -137,6 +137,7 @@ Comment[et]=Universaalne dokumendinäitaja Comment[fi]=Yleinen asiakirjakatselin Comment[fr]=Afficheur de document universel Comment[gl]=Visor de documentos universal +Comment[ia]=Visor de documento universal Comment[is]=Fjölhæfur skjalaskoðari Comment[it]=Visore di documenti universale Comment[ko]=만능 문서 뷰어 diff --git a/generators/ooo/okularApplication_ooo.desktop b/generators/ooo/okularApplication_ooo.desktop index ec86f86a4..16fe3f05b 100755 --- a/generators/ooo/okularApplication_ooo.desktop +++ b/generators/ooo/okularApplication_ooo.desktop @@ -137,6 +137,7 @@ Comment[et]=Universaalne dokumendinäitaja Comment[fi]=Yleinen asiakirjakatselin Comment[fr]=Afficheur de document universel Comment[gl]=Visor de documentos universal +Comment[ia]=Visor de documento universal Comment[is]=Fjölhæfur skjalaskoðari Comment[it]=Visore di documenti universale Comment[ko]=만능 문서 뷰어 diff --git a/generators/plucker/okularApplication_plucker.desktop b/generators/plucker/okularApplication_plucker.desktop index 692a754d6..6fa4e6546 100755 --- a/generators/plucker/okularApplication_plucker.desktop +++ b/generators/plucker/okularApplication_plucker.desktop @@ -137,6 +137,7 @@ Comment[et]=Universaalne dokumendinäitaja Comment[fi]=Yleinen asiakirjakatselin Comment[fr]=Afficheur de document universel Comment[gl]=Visor de documentos universal +Comment[ia]=Visor de documento universal Comment[is]=Fjölhæfur skjalaskoðari Comment[it]=Visore di documenti universale Comment[ko]=만능 문서 뷰어 diff --git a/generators/poppler/okularApplication_pdf.desktop b/generators/poppler/okularApplication_pdf.desktop index 8ca9fcbde..363b1f003 100755 --- a/generators/poppler/okularApplication_pdf.desktop +++ b/generators/poppler/okularApplication_pdf.desktop @@ -137,6 +137,7 @@ Comment[et]=Universaalne dokumendinäitaja Comment[fi]=Yleinen asiakirjakatselin Comment[fr]=Afficheur de document universel Comment[gl]=Visor de documentos universal +Comment[ia]=Visor de documento universal Comment[is]=Fjölhæfur skjalaskoðari Comment[it]=Visore di documenti universale Comment[ko]=만능 문서 뷰어 diff --git a/generators/spectre/okularApplication_ghostview.desktop b/generators/spectre/okularApplication_ghostview.desktop index 682e29bf9..efd38bd35 100755 --- a/generators/spectre/okularApplication_ghostview.desktop +++ b/generators/spectre/okularApplication_ghostview.desktop @@ -137,6 +137,7 @@ Comment[et]=Universaalne dokumendinäitaja Comment[fi]=Yleinen asiakirjakatselin Comment[fr]=Afficheur de document universel Comment[gl]=Visor de documentos universal +Comment[ia]=Visor de documento universal Comment[is]=Fjölhæfur skjalaskoðari Comment[it]=Visore di documenti universale Comment[ko]=만능 문서 뷰어 diff --git a/generators/tiff/okularApplication_tiff.desktop b/generators/tiff/okularApplication_tiff.desktop index ba6ed2ddc..18002ee3c 100755 --- a/generators/tiff/okularApplication_tiff.desktop +++ b/generators/tiff/okularApplication_tiff.desktop @@ -137,6 +137,7 @@ Comment[et]=Universaalne dokumendinäitaja Comment[fi]=Yleinen asiakirjakatselin Comment[fr]=Afficheur de document universel Comment[gl]=Visor de documentos universal +Comment[ia]=Visor de documento universal Comment[is]=Fjölhæfur skjalaskoðari Comment[it]=Visore di documenti universale Comment[ko]=만능 문서 뷰어 diff --git a/generators/txt/okularApplication_txt.desktop b/generators/txt/okularApplication_txt.desktop index 03bf74a48..38cebd44a 100644 --- a/generators/txt/okularApplication_txt.desktop +++ b/generators/txt/okularApplication_txt.desktop @@ -137,6 +137,7 @@ Comment[et]=Universaalne dokumendinäitaja Comment[fi]=Yleinen asiakirjakatselin Comment[fr]=Afficheur de document universel Comment[gl]=Visor de documentos universal +Comment[ia]=Visor de documento universal Comment[is]=Fjölhæfur skjalaskoðari Comment[it]=Visore di documenti universale Comment[ko]=만능 문서 뷰어 diff --git a/generators/xps/okularApplication_xps.desktop b/generators/xps/okularApplication_xps.desktop index 3e5f0ee06..2cb3a3225 100755 --- a/generators/xps/okularApplication_xps.desktop +++ b/generators/xps/okularApplication_xps.desktop @@ -137,6 +137,7 @@ Comment[et]=Universaalne dokumendinäitaja Comment[fi]=Yleinen asiakirjakatselin Comment[fr]=Afficheur de document universel Comment[gl]=Visor de documentos universal +Comment[ia]=Visor de documento universal Comment[is]=Fjölhæfur skjalaskoðari Comment[it]=Visore di documenti universale Comment[ko]=만능 문서 뷰어 diff --git a/metainfo.yaml b/metainfo.yaml new file mode 100644 index 000000000..6f6f9cf57 --- /dev/null +++ b/metainfo.yaml @@ -0,0 +1,15 @@ +maintainer: aacid +description: Okular, the unified document viewer +platforms: + - name: Linux + - name: Windows + - name: MacOSX +release: true + +public_lib: true +public_source_dirs: + - core + - Mainpage.dox +logo: ui/data/icons/hi128-apps-okular.png +irc: okular +mailinglist: okular-devel diff --git a/shell/org.kde.okular.desktop b/shell/org.kde.okular.desktop index bf7fbbe50..0d3587255 100755 --- a/shell/org.kde.okular.desktop +++ b/shell/org.kde.okular.desktop @@ -136,6 +136,7 @@ Comment[et]=Universaalne dokumendinäitaja Comment[fi]=Yleinen asiakirjakatselin Comment[fr]=Afficheur de document universel Comment[gl]=Visor de documentos universal +Comment[ia]=Visor de documento universal Comment[is]=Fjölhæfur skjalaskoðari Comment[it]=Visore di documenti universale Comment[ko]=만능 문서 뷰어 diff --git a/ui/embeddedfilesdialog.cpp b/ui/embeddedfilesdialog.cpp index 4d1784126..f3916f63a 100644 --- a/ui/embeddedfilesdialog.cpp +++ b/ui/embeddedfilesdialog.cpp @@ -11,9 +11,12 @@ #include #include +#include #include +#include #include #include +#include #include #include @@ -25,6 +28,7 @@ #include #include #include +#include #include "core/document.h" #include "guiutils.h" @@ -54,9 +58,14 @@ EmbeddedFilesDialog::EmbeddedFilesDialog(QWidget *parent, const Okular::Document KGuiItem::assign(mUser1Button, KStandardGuiItem::save()); mUser1Button->setEnabled(false); + mUser2Button = new QPushButton; + buttonBox->addButton(mUser2Button, QDialogButtonBox::ActionRole); + KGuiItem::assign(mUser2Button, KGuiItem(i18nc("@action:button", "View"), "document-open")); + mUser1Button->setEnabled(false); + m_tw = new QTreeWidget(this); mainLayout->addWidget(m_tw); - mainLayout->addWidget(buttonBox); + mainLayout->addWidget(buttonBox); QStringList header; header.append(i18nc("@title:column", "Name")); @@ -73,11 +82,11 @@ EmbeddedFilesDialog::EmbeddedFilesDialog(QWidget *parent, const Okular::Document { QTreeWidgetItem *twi = new QTreeWidgetItem(); twi->setText(0, ef->name()); - QMimeDatabase db; - QMimeType mime = db.mimeTypeForFile( ef->name(), QMimeDatabase::MatchExtension); + QMimeDatabase db; + QMimeType mime = db.mimeTypeForFile( ef->name(), QMimeDatabase::MatchExtension); if (mime.isValid()) { - twi->setIcon(0, QIcon::fromTheme(mime.iconName())); + twi->setIcon(0, QIcon::fromTheme(mime.iconName())); } twi->setText(1, ef->description()); twi->setText(2, ef->size() <= 0 ? i18nc("Not available size", "N/A") : KFormat().formatByteSize(ef->size())); @@ -86,23 +95,26 @@ EmbeddedFilesDialog::EmbeddedFilesDialog(QWidget *parent, const Okular::Document twi->setData( 0, EmbeddedFileRole, qVariantFromValue( ef ) ); m_tw->addTopLevelItem(twi); } - // Having filled the columns, it is nice to resize them to be able to read the contents - for (int lv = 0; lv < m_tw->columnCount(); ++lv) { - m_tw->resizeColumnToContents(lv); - } - // This is a bit dubious, but I'm not seeing a nice way to say "expand to fit contents" - m_tw->setMinimumWidth(640); - m_tw->updateGeometry(); + // Having filled the columns, it is nice to resize them to be able to read the contents + for (int lv = 0; lv < m_tw->columnCount(); ++lv) { + m_tw->resizeColumnToContents(lv); + } + // This is a bit dubious, but I'm not seeing a nice way to say "expand to fit contents" + m_tw->setMinimumWidth(640); + m_tw->updateGeometry(); connect(mUser1Button, SIGNAL(clicked()), this, SLOT(saveFile())); + connect(mUser2Button, SIGNAL(clicked()), this, SLOT(viewFile())); connect(m_tw, &QWidget::customContextMenuRequested, this, &EmbeddedFilesDialog::attachViewContextMenu); connect(m_tw, &QTreeWidget::itemSelectionChanged, this, &EmbeddedFilesDialog::updateSaveButton); + connect(m_tw, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(viewFileItem(QTreeWidgetItem*,int))); } void EmbeddedFilesDialog::updateSaveButton() { bool enable = (m_tw->selectedItems().count() > 0); mUser1Button->setEnabled(enable); + mUser2Button->setEnabled(enable); } void EmbeddedFilesDialog::saveFile() @@ -115,6 +127,22 @@ void EmbeddedFilesDialog::saveFile() } } +void EmbeddedFilesDialog::viewFile() +{ + QList selected = m_tw->selectedItems(); + foreach(QTreeWidgetItem *twi, selected) + { + Okular::EmbeddedFile* ef = qvariant_cast< Okular::EmbeddedFile* >( twi->data( 0, EmbeddedFileRole ) ); + viewFile( ef ); + } +} + +void EmbeddedFilesDialog::viewFileItem( QTreeWidgetItem* item, int /*column*/ ) +{ + Okular::EmbeddedFile* ef = qvariant_cast< Okular::EmbeddedFile* >( item->data( 0, EmbeddedFileRole ) ); + viewFile( ef ); +} + void EmbeddedFilesDialog::attachViewContextMenu( const QPoint& /*pos*/ ) { QList selected = m_tw->selectedItems(); @@ -126,16 +154,47 @@ void EmbeddedFilesDialog::attachViewContextMenu( const QPoint& /*pos*/ ) QMenu menu( this ); QAction* saveAsAct = menu.addAction( QIcon::fromTheme( QStringLiteral("document-save-as") ), i18nc( "@action:inmenu", "&Save As..." ) ); + QAction* viewAct = menu.addAction( QIcon::fromTheme( QStringLiteral("document-open" ) ), i18nc( "@action:inmenu", "&View..." ) ); QAction* act = menu.exec( QCursor::pos() ); if ( !act ) return; + Okular::EmbeddedFile* ef = qvariant_cast< Okular::EmbeddedFile* >( selected.at( 0 )->data( 0, EmbeddedFileRole ) ); if ( act == saveAsAct ) { - Okular::EmbeddedFile* ef = qvariant_cast< Okular::EmbeddedFile* >( selected.at( 0 )->data( 0, EmbeddedFileRole ) ); saveFile( ef ); } + else if ( act == viewAct ) + { + viewFile( ef ); + } +} + +void EmbeddedFilesDialog::viewFile( Okular::EmbeddedFile* ef ) +{ + // get name and extension + QFileInfo fileInfo(ef->name()); + + // save in temporary directory with a unique name resembling the attachment name, + // using QTemporaryFile's XXXXXX placeholder + QTemporaryFile *tmpFile = new QTemporaryFile( + QDir::tempPath() + + QDir::separator() + + fileInfo.baseName() + + ".XXXXXX" + + (fileInfo.completeSuffix().isEmpty() ? QString("") : "." + fileInfo.completeSuffix()) + ); + GuiUtils::writeEmbeddedFile( ef, this, *tmpFile ); + + // set readonly to prevent the viewer application from modifying it + tmpFile->setPermissions( QFile::ReadOwner ); + + // keep temporary file alive while the dialog is open + m_openedFiles.push_back( QSharedPointer< QTemporaryFile >( tmpFile ) ); + + // view the temporary file with the default application + new KRun( QUrl( "file://" + tmpFile->fileName() ), this ); } void EmbeddedFilesDialog::saveFile( Okular::EmbeddedFile* ef ) diff --git a/ui/embeddedfilesdialog.h b/ui/embeddedfilesdialog.h index 7ec55a892..1def99245 100644 --- a/ui/embeddedfilesdialog.h +++ b/ui/embeddedfilesdialog.h @@ -14,6 +14,9 @@ class QTreeWidget; class QPushButton; +class QTemporaryFile; +class QTreeWidgetItem; + namespace Okular { class Document; class EmbeddedFile; @@ -29,12 +32,19 @@ Q_OBJECT void saveFile(); void attachViewContextMenu( const QPoint& pos ); void updateSaveButton(); + void viewFile(); + void viewFileItem( QTreeWidgetItem* index, int column ); private: void saveFile( Okular::EmbeddedFile* ); + void viewFile( Okular::EmbeddedFile* ); QTreeWidget *m_tw; - QPushButton *mUser1Button; + + + QPushButton *mUser1Button; + QPushButton *mUser2Button; + QList< QSharedPointer > m_openedFiles; }; #endif diff --git a/ui/guiutils.cpp b/ui/guiutils.cpp index 14bb85cd6..d4c9228a7 100644 --- a/ui/guiutils.cpp +++ b/ui/guiutils.cpp @@ -208,15 +208,18 @@ void saveEmbeddedFile( Okular::EmbeddedFile *ef, QWidget *parent ) const QString path = QFileDialog::getSaveFileName( parent, caption, ef->name() ); if ( path.isEmpty() ) return; + QFile targetFile( path ); + writeEmbeddedFile( ef, parent, targetFile ); +} - QFile f( path ); - if ( !f.open( QIODevice::WriteOnly ) ) +void writeEmbeddedFile( Okular::EmbeddedFile *ef, QWidget *parent, QFile& target ) { + if ( !target.open( QIODevice::WriteOnly ) ) { - KMessageBox::error( parent, i18n( "Could not open \"%1\" for writing. File was not saved.", path ) ); + KMessageBox::error( parent, i18n( "Could not open \"%1\" for writing. File was not saved.", target.fileName() ) ); return; } - f.write( ef->data() ); - f.close(); + target.write( ef->data() ); + target.close(); } Okular::Movie* renditionMovieFromScreenAnnotation( const Okular::ScreenAnnotation *annotation ) diff --git a/ui/guiutils.h b/ui/guiutils.h index cbfcb0461..295dfa93d 100644 --- a/ui/guiutils.h +++ b/ui/guiutils.h @@ -17,6 +17,7 @@ class QImage; class QPixmap; class QSize; class QWidget; +class QFile; class KIconLoader; namespace Okular { @@ -45,6 +46,7 @@ namespace GuiUtils KIconLoader* iconLoader(); void saveEmbeddedFile( Okular::EmbeddedFile *ef, QWidget *parent ); + void writeEmbeddedFile( Okular::EmbeddedFile *ef, QWidget *parent, QFile& targetFile ); /** * Returns the movie object that is referenced by a rendition action of the passed screen @p annotation diff --git a/ui/pagepainter.cpp b/ui/pagepainter.cpp index c96777313..aaf68e2da 100644 --- a/ui/pagepainter.cpp +++ b/ui/pagepainter.cpp @@ -61,10 +61,10 @@ void PagePainter::paintCroppedPageOnPainter( QPainter * destPainter, const Okula Okular::DocumentObserver *observer, int flags, int scaledWidth, int scaledHeight, const QRect &limits, const Okular::NormalizedRect &crop, Okular::NormalizedPoint *viewPortPoint ) { - /* Calculate the cropped geometry of the page */ - QRect scaledCrop = crop.geometry( scaledWidth, scaledHeight ); - int croppedWidth = scaledCrop.width(); - int croppedHeight = scaledCrop.height(); + /* Calculate the cropped geometry of the page */ + QRect scaledCrop = crop.geometry( scaledWidth, scaledHeight ); + int croppedWidth = scaledCrop.width(); + int croppedHeight = scaledCrop.height(); QColor paperColor = Qt::white; QColor backgroundColor = paperColor; diff --git a/ui/pageview.cpp b/ui/pageview.cpp index 339ba69c3..3e8d6501f 100644 --- a/ui/pageview.cpp +++ b/ui/pageview.cpp @@ -232,7 +232,7 @@ public: QAction * aFitWindowToPage; int setting_viewCols; - + bool rtl_Mode; // Keep track of whether tablet pen is currently pressed down bool penDown; }; @@ -349,6 +349,7 @@ PageView::PageView( QWidget *parent, Okular::Document *document ) d->actionCollection = 0; d->aPageSizes=0; d->setting_viewCols = Okular::Settings::viewColumns(); + d->rtl_Mode = Okular::Settings::rtlReadingDirection(); d->mouseModeActionGroup = 0; d->penDown = false; d->aMouseMagnifier = 0; @@ -828,6 +829,12 @@ void PageView::reparseConfig() slotRelayoutPages(); } + if (Okular::Settings::rtlReadingDirection() != d->rtl_Mode ) + { + d->rtl_Mode = Okular::Settings::rtlReadingDirection(); + slotRelayoutPages(); + } + updatePageStep(); if ( d->annotator ) @@ -4432,15 +4439,27 @@ void PageView::slotRelayoutPages() } else if ( facingPages ) { - // page edges 'touch' the center of the viewport - actualX = ( (centerFirstPage && item->pageNumber() % 2 == 1) || - (!centerFirstPage && item->pageNumber() % 2 == 0) ) ? - (fullWidth / 2) - item->croppedWidth() - 1 : (fullWidth / 2) + 1; + if (Okular::Settings::rtlReadingDirection()){ + // RTL reading mode + actualX = ( (centerFirstPage && item->pageNumber() % 2 == 0) || + (!centerFirstPage && item->pageNumber() % 2 == 1) ) ? + (fullWidth / 2) - item->croppedWidth() - 1 : (fullWidth / 2) + 1; + } else { + // page edges 'touch' the center of the viewport + actualX = ( (centerFirstPage && item->pageNumber() % 2 == 1) || + (!centerFirstPage && item->pageNumber() % 2 == 0) ) ? + (fullWidth / 2) - item->croppedWidth() - 1 : (fullWidth / 2) + 1; + } } else { // page is centered within its virtual column - actualX = insertX + (cWidth - item->croppedWidth()) / 2; + //actualX = insertX + (cWidth - item->croppedWidth()) / 2; + if (Okular::Settings::rtlReadingDirection()){ + actualX = fullWidth - insertX - cWidth +( (cWidth - item->croppedWidth()) / 2); + } else { + actualX = insertX + (cWidth - item->croppedWidth()) / 2; + } } item->moveTo( actualX, (continuousView ? insertY : origInsertY) + (rHeight - item->croppedHeight()) / 2 ); diff --git a/ui/pageviewannotator.cpp b/ui/pageviewannotator.cpp index 0b4a34a24..ae40cf45a 100644 --- a/ui/pageviewannotator.cpp +++ b/ui/pageviewannotator.cpp @@ -524,7 +524,7 @@ class TextSelectorEngine : public AnnotatorEngine delete selection; selection = 0; Okular::RegularAreaRect * newselection = m_pageView->textSelectionForItem( item(), start, end ); - if ( !newselection->isEmpty() ) + if ( newselection && !newselection->isEmpty() ) { const QList geom = newselection->geometry( (int)xScale, (int)yScale ); QRect newrect; diff --git a/ui/thumbnaillist.cpp b/ui/thumbnaillist.cpp index 16332ed48..a89021db4 100644 --- a/ui/thumbnaillist.cpp +++ b/ui/thumbnaillist.cpp @@ -732,31 +732,21 @@ void ThumbnailListPrivate::mouseReleaseEvent( QMouseEvent * e ) return e->ignore(); QRect r = item->visibleRect(); - const int margin = ThumbnailWidget::margin(); const QPoint p = e->pos() - item->pos(); - if ( r.contains( p - QPoint( margin / 2, margin / 2 ) ) ) - { - setCursor( Qt::OpenHandCursor ); - } - else + // jump center of viewport to cursor if it wasn't dragged + if ( m_mouseGrabPos.isNull() ) { - setCursor( Qt::ArrowCursor ); - if ( m_mouseGrabPos.isNull() ) - { - if ( m_document->viewport().pageNumber != item->pageNumber() ) - { - m_document->setViewportPage( item->pageNumber() ); - r = item->visibleRect(); - Okular::DocumentViewport vp = Okular::DocumentViewport( item->pageNumber() ); - vp.rePos.normalizedX = 0.5; - vp.rePos.normalizedY = (double) r.height() / 2.0 / (double) item->pixmapHeight(); - vp.rePos.pos = Okular::DocumentViewport::Center; - vp.rePos.enabled = true; - m_document->setViewport( vp ); - } - } + m_document->setViewportPage( item->pageNumber() ); + r = item->visibleRect(); + Okular::DocumentViewport vp = Okular::DocumentViewport( item->pageNumber() ); + vp.rePos.normalizedX = double(p.x()) / double(item->rect().width()); + vp.rePos.normalizedY = double(p.y()) / double(item->rect().height()); + vp.rePos.pos = Okular::DocumentViewport::Center; + vp.rePos.enabled = true; + m_document->setViewport( vp ); } + setCursor( Qt::OpenHandCursor ); m_mouseGrabPos.setX( 0 ); m_mouseGrabPos.setY( 0 ); } @@ -764,7 +754,25 @@ void ThumbnailListPrivate::mouseReleaseEvent( QMouseEvent * e ) void ThumbnailListPrivate::mouseMoveEvent( QMouseEvent * e ) { if ( e->buttons() == Qt::NoButton ) + { + ThumbnailWidget* item = itemFor( e->pos() ); + if ( !item ) // mouse on the spacing between items + return e->ignore(); + + QRect r = item->visibleRect(); + const int margin = ThumbnailWidget::margin(); + const QPoint p = e->pos() - item->pos(); + if ( r.contains( p - QPoint( margin / 2, margin / 2 ) ) ) + { + setCursor( Qt::OpenHandCursor ); + } + else + { + setCursor( Qt::ArrowCursor ); + } + return e->ignore(); + } // no item under the mouse or previously selected if ( !m_mouseGrabItem ) return e->ignore(); diff --git a/ui/tocmodel.cpp b/ui/tocmodel.cpp index ccbaa4c84..0a4608c54 100644 --- a/ui/tocmodel.cpp +++ b/ui/tocmodel.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include @@ -149,11 +150,38 @@ QModelIndex TOCModelPrivate::indexForItem( TOCItem *item ) const void TOCModelPrivate::findViewport( const Okular::DocumentViewport &viewport, TOCItem *item, QList< TOCItem* > &list ) const { - if ( item->viewport.isValid() && item->viewport.pageNumber == viewport.pageNumber ) - list.append( item ); + TOCItem *todo = item; - foreach ( TOCItem *child, item->children ) - findViewport( viewport, child, list ); + while ( todo ) + { + TOCItem *current = todo; + todo = 0; + TOCItem *pos = 0; + + foreach ( TOCItem *child, current->children ) + { + if ( child->viewport.isValid() ) + { + if ( child->viewport.pageNumber <= viewport.pageNumber ) + { + pos = child; + if ( child->viewport.pageNumber == viewport.pageNumber ) + { + break; + } + } + else + { + break; + } + } + } + if ( pos ) + { + list.append( pos ); + todo = pos; + } + } } @@ -198,7 +226,31 @@ QVariant TOCModel::data( const QModelIndex &index, int role ) const break; case Qt::DecorationRole: if ( item->highlight ) - return QIcon::fromTheme( QApplication::layoutDirection() == Qt::RightToLeft ? QStringLiteral("arrow-left") : QStringLiteral("arrow-right") ); + { + const QVariant icon = QIcon::fromTheme( QApplication::layoutDirection() == Qt::RightToLeft ? QStringLiteral("arrow-left") : QStringLiteral("arrow-right") ); + TOCItem *lastHighlighted = d->currentPage.last(); + + // in the mobile version our parent is not a QTreeView; add icon to the last highlighted item + // TODO misusing parent() here, fix + QTreeView *view = dynamic_cast< QTreeView* > ( QObject::parent() ); + if ( !view ) + { + if ( item == lastHighlighted ) + return icon; + return QVariant(); + } + + if ( view->isExpanded( index ) ) + { + // if this is the last highlighted node, its child is on a page below, thus it needs icon + if ( item == lastHighlighted ) + return icon; + } + else + { + return icon; + } + } break; case PageItemDelegate::PageRole: if ( item->viewport.isValid() ) @@ -291,6 +343,7 @@ void TOCModel::fill( const Okular::DocumentSynopsis *toc ) if ( !index.isValid() ) continue; + // TODO misusing parent() here, fix QMetaObject::invokeMethod( QObject::parent(), "expand", Qt::QueuedConnection, Q_ARG( QModelIndex, index ) ); } } @@ -302,6 +355,7 @@ void TOCModel::fill( const Okular::DocumentSynopsis *toc ) if ( !index.isValid() ) continue; + // TODO misusing parent() here, fix QMetaObject::invokeMethod( QObject::parent(), "expand", Qt::QueuedConnection, Q_ARG( QModelIndex, index ) ); } } @@ -339,13 +393,6 @@ void TOCModel::setCurrentViewport( const Okular::DocumentViewport &viewport ) QList< TOCItem* > newCurrentPage; d->findViewport( viewport, d->root, newCurrentPage ); - // HACK: for now, support only the first item found - if ( newCurrentPage.count() > 0 ) - { - TOCItem *first = newCurrentPage.first(); - newCurrentPage.clear(); - newCurrentPage.append( first ); - } d->currentPage = newCurrentPage;